FiveDBU for 32/64 bits

Re: FiveDBU for 32/64 bits

Postby Antonio Linares » Tue Jun 05, 2012 8:16 am

Stefan,

Thanks a lot! :-)
regards, saludos

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

Re: FiveDBU for 32/64 bits

Postby ukoenig » Tue Jun 05, 2012 9:35 am

Got it working.
The new Code with all changes :

1. Two new Buttons < Add file > and < File preview >
2. New Functions < Fileview > and < FileSel >
The Function < FileSel > repaints the Structure-browser and keeps the old Row-/Col-position
Next You can open a Fileviewer with the Button < File preview >

Code: Select all  Expand view  RUN

//----------------------------------------------------------------------------//
   
function Edit()

   local oWnd, aRecord := ( Alias() )->( LoadRecord() ), oBar, oBrw, oMsgBar
   local cAlias := Alias(), oBtnSave, nRecNo := ( Alias() )->( RecNo() )
   local oMsgDeleted, cValue := ""
   
   DEFINE WINDOW oWnd TITLE "Edit " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 80, 70
   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" RESOURCE "save" ;
      ACTION ( ( cAlias )->( SaveRecord( aRecord, nRecNo ) ), oBtnSave:Disable() )

   oBtnSave:Disable()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION GoPrevRecord( oBrw, aRecord, oMsgDeleted ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" GROUP ;
      ACTION oBrw:Report()
     
   DEFINE BUTTON OF oBar PROMPT "Add-File" RESOURCE "select" ;
      ACTION  cValue := FileSel( oBrw )

  DEFINE BUTTON OF oBar PROMPT "File-Preview" RESOURCE "view" ;
      ACTION  FileView( oBrw, cValue )

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

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRecord AUTOCOLS LINES ;
      HEADERS "FieldName", "Value" COLSIZES 150, 400 FASTEDIT ;
      ON CHANGE ( ( cAlias )->( SetEditType( oBrw, oBtnSave ) ), oBrw:DrawLine( .T. ), ;
      cValue := ( cAlias )->(FieldGet(oBrw:nArrayAt)), ;
                  oMsgBar:cMsgDef := " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + ;
                                 "/" + AllTrim( Str( ( cAlias )->( RecCount() ) ) ),;
                  oMsgBar:Refresh() )                
   
   oBrw:nEditTypes = EDIT_GET
   oBrw:aCols[ 1 ]:nEditType = 0 // Don't allow to edit first column
   oBrw:aCols[ 2 ]:bOnChange = { || oBtnSave:Enable() }
   oBrw:aCols[ 2 ]:lWillShowABtn = .T.
   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLCELL  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:lUpdate   := .t.
   oBrw:SetFocus()

   cValue := ( cAlias )->(FieldGet(oBrw:nArrayAt))

   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar ;
      PROMPT " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + "/" + ;
      AllTrim( Str( ( cAlias )->( RecCount() ) ) ) OF oWnd 2010

  DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
         SIZE 130 ;
         BITMAPS If( ( cAlias )->( Deleted() ), "deleted", "nondeleted" ) ;
         ACTION ( cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
   
   ACTIVATE WINDOW oWnd
   
return nil      

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

function FileView( oBrw, cValue )
lShow := .F.

// If a field contains a backslash "\" or a "dot" then we may assume
// that it is a file and then we allow to call ShellExecute( 0, "open", <field value> )

IF ( Alias() )->( FIELDTYPE( oBrw:nArrayAt ) ) = "C" // protect to use numeric or logical fields
    IF !EMPTY(StrToken( cValue,  1, ":" ))
        lShow := .T.
    ELSEIF !EMPTY(StrToken( cValue,  1, "\" ))
        lShow := .T.
    ELSEIF !EMPTY(StrToken( cValue,  1, "
." ))
        lShow := .T.
    ENDIF
ENDIF
IF lShow = .T.
      ShellExecute( 0, "
open", cValue )
ELSE
    MsgAlert( "
No File-preview possible !", "Error" )
ENDIF

return nil  

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

function FileSel( oBrw )
local cAlias := Alias(), cFile

cFilter := "
ALL (*.*)|*.*|" + "BMP (*.bmp)|*.bmp|" + "JPG (*.jpg)|*.jpg|" + "PNG (*.png)| *.png|" + ;
        "
TIFF (*.tiff)| *.tiff|" + "PDF (*.pdf)| *.pdf|" + "DDS (*.dds)| *.dds|" + ;
                "
IFF (*.iff)| *.iff|" + "PCX  (*.pcx)| *.pcx|" + "PPM (*.ppm)| *.ppm|" + ;
                "
PSD (*.ppm)| *.psd|" + "SGI  (*.sgi)| *.sgi|" + "TARGA (*.tga)| *.tga|"

cFile := cGetFile32( cFilter,"
Select a File" ,,  "\" + CurDir() )

IF EMPTY( cFile )
    MsgAlert( "
No file selected !","ATTENTION" )
ELSE
    IF ( Alias() )->( FIELDTYPE( oBrw:nArrayAt ) ) = "
C"
        IF ( Alias() )->( DbRLock( ( cAlias )->( RecNo() ) ) )
            ( cAlias )->( FieldPut( oBrw:nArrayAt, cFile ) )
            ( Alias() )->( DbUnLock() )
            oBrw:Refresh()  
        ENDIF
        nOldPos := oBrw:nArrayAt
        oBrw:SetArray( aRecord := LoadRecord() )
        oBrw:SetFocus()
        Eval( oBrw:bChange )
                oBrw:nArrayAt := nOldPos
        oBrw:nRowSel := nOldPos
    ELSE
        MsgAlert( "
Wrong Fieldtype to save Text", "Error")
    ENDIF
ENDIF

return ( cFile )


Best Regards
Uwe :lol:
Last edited by ukoenig on Tue Jun 05, 2012 11:19 am, edited 1 time 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
ukoenig
 
Posts: 4043
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany

Re: FiveDBU for 32/64 bits

Postby StefanHaupt » Tue Jun 05, 2012 10:49 am

enhanced version of New ()
- editing fields is now supported, double click the row you want to change, save the changes with edit button
- esc does not close the dialog anymore

Code: Select all  Expand view  RUN
function New()

       local oDlg, oGet, oBrw, oBtn
       local cFieldName := Space( 10 ), cType := "Character", nLen := 10, nDec := 0
       local aFields := { Array( 4 ) }, cDbfName := Space( 8 ), aTemp
       local oLen, oDec, aType := { "Character", "Number", "Date", "Logical", "Memo" }
       local bChange := {|| If( cType == "Character", (nLen := 10, nDec := 0, oDec:Disable() ),),;
                            If( cType == "Number",    (nLen := 10, nDec := 0, oDec:Enable()  ),),;
                            If( cType == "Date",      (nLen := 8,  nDec := 0, oDec:Disable() ),),;
                            If( cType == "Logical",   (nLen := 1,  nDec := 0, oDec:Disable() ),),;
                            If( cType == "Memo",      (nLen := 10, nDec := 0, oDec:Disable() ),),;
                            oDlg:Update() }
       local bEdit := {|| IF ( !Empty (aFields[1,1]) ,;
                          (oBtn:Enable (),;
                           cFieldName := aFields[oBrw:nArrayAt,1] ,;
                           cType := aFields[oBrw:nArrayAt,2] ,;
                           cType := aType[ aScan(aType, {|x| Left(x,1) = cType} )],;
                           Eval (bChange) ,;
                           nLen := aFields[oBrw:nArrayAt,3] ,;
                           nDec := aFields[oBrw:nArrayAt,4] ,;
                           oGet:SetPos( 0 ),;
                           oGet:SetFocus(),;
                           oDlg:Update() ) ,) ;
                         }
       local bSave := {|| oBtn:Disable (),;
                          aFields[oBrw:nArrayAt,1] := cFieldname,;
                          aFields[oBrw:nArrayAt,2] := Left (cType,1),;
                          aFields[oBrw:nArrayAt,3] := nLen,;
                          aFields[oBrw:nArrayAt,4] := nDec,;
                          oBrw:SetArray (aFields),;
                          cFieldName := Space( 10 ),;
                          Eval (bChange) ,;
                          oDlg:Update() ,;
                          oGet:SetPos( 0 ),;
                          oGet:SetFocus(),;
                          oBrw:GoBottom();
                          }

       DEFINE DIALOG oDlg TITLE "DBF builder" SIZE 415, 400

       @ 0.5,  2 SAY "Field Name" OF oDlg SIZE 40, 8
       @ 0.5, 10 SAY "Type" OF oDlg SIZE 40, 8
       @ 0.5, 17 SAY "Len" OF oDlg SIZE 40, 8
       @ 0.5, 22 SAY "Dec" OF oDlg SIZE 20, 8

       @ 1.4, 1 GET oGet VAR cFieldName PICTURE "!!!!!!!!!!" OF oDlg SIZE 41, 11 UPDATE

       @ 1.3, 6.5 COMBOBOX cType ITEMS aType ;
          OF oDlg ON CHANGE Eval (bChange) UPDATE

       @ 1.4, 11.9 GET oLen VAR nLen PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

       @ 1.4, 15.4 GET oDec VAR nDec PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

       @ 0.9, 26 BUTTON "&Add" OF oDlg SIZE 45, 13 ;
          ACTION AddField( @aFields, @cFieldName, @cType, @nLen, @nDec, oGet, oBrw )

       @ 2.4, 26 BUTTON oBtn PROMPT "&Edit" OF oDlg SIZE 45, 13 ;
         ACTION Eval (bSave)

       @ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
         ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

       @ 4.4, 26 BUTTON "Move &Up" OF oDlg SIZE 45, 13 ;
          ACTION If( oBrw:nArrayAt > 1,;
                     ( aTemp := aFields[ oBrw:nArrayAt ],;
                       aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt - 1 ],;
                       aFields[ oBrw:nArrayAt - 1 ] := aTemp,;
                       oBrw:GoUp() ),)

       @ 5.4, 26 BUTTON "Move D&own" OF oDlg SIZE 45, 13 ;
          ACTION If( oBrw:nArrayAt < Len( aFields ),;
                     ( aTemp := aFields[ oBrw:nArrayAt ],;
                       aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt + 1 ],;
                       aFields[ oBrw:nArrayAt + 1 ] := aTemp,;
                       oBrw:GoDown() ),)

       @ 6.4, 26 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()

       @ 2.2, 2 SAY "Fields" OF oDlg SIZE 40, 8

       @ 3.2, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS ;
          HEADERS "Name", "Type", "Len", "Dec" ;
          COLSIZES 90, 55, 40, 40 ;
          SIZE 140, 130 OF oDlg ;
          ON DBLCLICK Eval (bEdit)

       oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
       oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                             { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                             { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
       oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
       oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
       oBrw:CreateFromCode()

       @ 12.1, 2 SAY "DBF Name:" OF oDlg SIZE 30, 8

       @ 14, 6 GET cDbfName PICTURE "!!!!!!!!!!!!" OF oDlg SIZE 100, 11

       @ 10, 26 BUTTON "&Create" OF oDlg SIZE 45, 13 ;
          ACTION ( If( ! Empty( cDbfName ) .and. Len( aFields ) > 0,;
              DbCreate( AllTrim( cDbfName ), aFields ),), oDlg:End(),;
              Open( hb_CurDrive() + ":\" + CurDir() + "\" + AllTrim( cDbfName ) ) )

       ACTIVATE DIALOG oDlg CENTERED ON INIT (Eval (bChange), oBtn:Disable() ) ;
                                     VALID !GETKEYSTATE( VK_ESCAPE )

    return nil

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

    function AddField( aFields, cFieldName, cType, nLen, nDec, oGet, oBrw )

       if Empty( cFieldName )
          oGet:SetPos( 0 )
          return nil
       endif

       if Len( aFields ) == 1 .and. Empty( aFields[ 1 ][ 1 ] )
          aFields = { { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } }
       else
          AAdd( aFields, { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } )
       endif

       oBrw:SetArray( aFields )
       oGet:VarPut( cFieldName := Space( 10 ) )
       oGet:SetPos( 0 )
       oGet:SetFocus()
       oBrw:GoBottom()

    return nil
kind regards
Stefan
StefanHaupt
 
Posts: 824
Joined: Thu Oct 13, 2005 7:39 am
Location: Germany

Re: FiveDBU for 32/64 bits

Postby ukoenig » Tue Jun 05, 2012 11:28 am

Stefan,

Function :

@ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

from Your first post is missing.

Code: Select all  Expand view  RUN

function DelField( aFields, cFieldName, oGet, oBrw )

       if Len( aFields ) >= 1
         ADel( aFields, oBrw:nArrayAt, .t. )
         oBrw:SetArray( aFields )
       endif

       oGet:VarPut( cFieldName := Space( 10 ) )
       oGet:SetPos( 0 )
       oGet:SetFocus()
       oBrw:GoBottom()
                   
    return nil
 


Best 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
ukoenig
 
Posts: 4043
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany

Re: FiveDBU for 32/64 bits

Postby Antonio Linares » Tue Jun 05, 2012 12:13 pm

Implementing the Index builder and the Expression builder:

Image

Image

Code: Select all  Expand view  RUN
#include "FiveWin.ch"
#include "xbrowse.ch"

#ifdef __XHARBOUR__
   #define hb_CurDrive() CurDrive()
#endif  

#define GENBLOCK(x)  &( "{ || " + x + " }" )

REQUEST DBFCDX

static oWndMain, oMruDBFs, aSearches := {}

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

function Main( cDbfName )

   local oBar, oBmpTiled
   
   SET DATE FORMAT TO "DD/MM/YYYY"

   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"

   DEFINE WINDOW oWndMain TITLE "FiveDBU" MDI MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION New()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION Open()

   DEFINE BUTTON OF oBar PROMPT "Copy" RESOURCE "copy" ACTION Copy() GROUP

   DEFINE BUTTON OF oBar PROMPT "Paste" RESOURCE "paste" ACTION Paste()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION oWndMain:PrevWindow() GROUP WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION oWndMain:NextWindow() WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   DEFINE MSGBAR PROMPT "FiveDBU 32/64 bits, (c) FiveTech Software 2012" ;
      OF oWndMain 2010 KEYBOARD DATE

   if ! Empty( cDbfName )
      Open( cDbfName )
   endif  

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )
   
   oBmpTiled:End()      

return nil

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

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Files"
      MENU
         MENUITEM "New..."
         MENUITEM "Open..." ACTION Open()
         SEPARATOR
         MENUITEM "Recent files"
         MENU
            MRU oMruDBFs ;
               FILENAME ".\FiveDBU.ini" ;    // .INI to manipulate. '\.' for local
               SECTION  "Recent DBF files" ; // The name of the INI section
               ACTION   Open( cMruItem ) ;   // cMruItem is automatically provided
               MESSAGE  "Open this file" ;   // The message for all of them
               SIZE     10
         ENDMENU      

         SEPARATOR
         MENUITEM "Exit" ACTION oWndMain:End()
      ENDMENU
     
      // oMenu:AddEdit()
      oMenu:AddMdi()
      oMenu:AddHelp( "FiveDBU", "(c) FiveTech Software 2012" )
   ENDMENU
   
return oMenu      

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

function Open( cFileName )

   local oWnd, oBar, oBrw, oMsgBar, oMsgDeleted, oMsgTagName
   local oPopup, cAlias, n, cClrBack, nTags
   
   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )
   
   if Empty( cFileName )
      return nil
   endif  
   
   if ! "." $ cFileName
      cFileName += ".dbf"
   endif  
   
   if ! File( cFileName )
      MsgStop( "File not found: " + cFileName )
      return nil
   endif
   
   if File( cFileNoExt( cFileName ) + ".ntx" )
      USE ( cFileName ) VIA "DBFNTX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
   else  
      USE ( cFileName ) VIA "DBFCDX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
      cAlias = Alias()
   endif        
   
   oMruDBFs:Save( cFileName )
   
   MENU oPopup POPUP
      MENUITEM "Natural order" ;
         ACTION ( ( cAlias )->( DbSetOrder( 0 ) ), oBrw:Refresh(), oBrw:SetFocus(),;
                  ( cAlias )->( Eval( oBrw:bChange ) ) )
     
      if ( nTags := ( cAlias )->( OrdTagsCount() ) ) > 0
         SEPARATOR
      endif  
     
      for n = 1 to nTags
         if ! Empty( OrdName( n ) )
            if ! Empty( OrdName( 1 ) )
               DbSetOrder( OrdName( 1 ) )
               DbGoTop()
            endif  
            MENUITEM OrdName( n ) ;
               ACTION ( ( cAlias )->( DbSetOrder( oMenuItem:cPrompt ) ),;
                        oBrw:Refresh(), ( cAlias )->( Eval( oBrw:bChange ) ), oBrw:SetFocus() )
         endif
      next    
   ENDMENU  
   
   DEFINE WINDOW oWnd TITLE "Browse " + cFileName MDICHILD

   oWnd:bCopy = { || MsgInfo( "copy" ) }

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( ( oBrw:cAlias )->( DbAppend() ), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( oBrw:cAlias )->( Edit() )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION ( obrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )

   DEFINE BUTTON OF oBar PROMPT "Search" RESOURCE "search" ;
      GROUP ACTION ( cAlias )->( Search( oBrw ) )

   DEFINE BUTTON OF oBar PROMPT "Index" RESOURCE "index" ;
      MENU oPopup ACTION ( cAlias )->( Indexes() )

   DEFINE BUTTON OF oBar PROMPT "Top" RESOURCE "top" ;
      ACTION ( oBrw:GoTop(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Bottom" RESOURCE "bottom" ;
      ACTION ( oBrw:GoBottom(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Struct" RESOURCE "struct" ;
      ACTION ( oBrw:cAlias )->( Struct() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report()

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd LINES ;
      ON CHANGE ( oMsgBar:cMsgDef := "Alias: " + Alias() + ;
                                     " RecNo: " + AllTrim( Str( RecNo() ) ) + "/" + ;
                                     AllTrim( Str( RecCount() ) ),;
                                     oMsgBar:Refresh(),;
                                     oMsgTagName:SetText( "Ordered by: " + If( ! Empty( OrdName() ), OrdName(), "Natural order" ) ),;
                                     oMsgDeleted:SetText( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "DELETED", "NON DELETED" ) ),;
                                     oMsgDeleted:SetBitmap( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "deleted", "nondeleted" ) ) )

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 198, 255, 198 ) }, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                           RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]                                              
   oBrw:bClrSelFocus = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                              cClrBack } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   oBrw:bLDblClick = { || ( oBrw:cAlias )->( Edit() ) }                      
   
   oWnd:oClient = oBrw
   oWnd:oControl = oBrw

   DEFINE MSGBAR oMsgBar PROMPT "Alias: " + Alias() + " | RecNo: " + ;
      AllTrim( Str( RecNo() ) ) + "/" + ;
      AllTrim( Str( RecCount() ) ) ;
      OF oWnd 2010

   DEFINE MSGITEM oMsgTagName OF oMsgBar ;
          PROMPT "Ordered by: " + ;
          If( ! Empty( ( oBrw:cAlias )->( OrdName() ) ),;
              ( oBrw:cAlias )->( OrdName() ), "Natural order" ) ;
          SIZE 150

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( oBrw:cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS "nondeleted" ;
          ACTION ( oBrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
         
   ACTIVATE WINDOW oWnd ;
      VALID ( ( cAlias )->( DbCloseArea() ), oBrw:cAlias := "", .T. )
   
return nil  

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

function Copy()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Copy()
   endif  

return nil

//----------------------------------------------------------------------------//
 
function DelField( aFields, cFieldName, oGet, oBrw )

   if Len( aFields ) >= 1
      ADel( aFields, oBrw:nArrayAt, .T. )
      oBrw:SetArray( aFields )
   endif

   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()
               
return nil

//----------------------------------------------------------------------------//
       
function DelRecord( oBrw, oMsgDeleted )

   if ! Deleted()
      if ! MsgYesNo( "Want to delete this record ?" )
         return nil
      endif  
      DbRLock()  
      DbDelete()  
      DbUnlock()  
      oMsgDeleted:SetText( "DELETED" )
      oMsgDeleted:SetBitmap( "deleted" )
   else
      DbRLock()  
      DbRecall()  
      DbUnlock()        
      oMsgDeleted:SetText( "NON DELETED" )
      oMsgDeleted:SetBitmap( "nondeleted" )
      MsgInfo( "UnDeleted record" )
   endif
   
   Eval( oBrw:bChange )
   oBrw:Refresh()

return nil  

//----------------------------------------------------------------------------//
   
function Edit()

   local oWnd, aRecord := ( Alias() )->( LoadRecord() ), oBar, oBrw, oMsgBar
   local cAlias := Alias(), oBtnSave, nRecNo := ( Alias() )->( RecNo() )
   local oMsgDeleted
   
   DEFINE WINDOW oWnd TITLE "Edit " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" RESOURCE "save" ;
      ACTION ( ( cAlias )->( SaveRecord( aRecord, nRecNo ) ), oBtnSave:Disable() )

   oBtnSave:Disable()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION GoPrevRecord( oBrw, aRecord, oMsgDeleted ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP

   DEFINE BUTTON OF oBar PROMPT "View" RESOURCE "view" ;
      ACTION View( oBrw:aRow[ 2 ], oWnd )
     
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRecord AUTOCOLS LINES ;
      HEADERS "FieldName", "Value" COLSIZES 150, 400 FASTEDIT ;
      ON CHANGE ( ( cAlias )->( SetEditType( oBrw, oBtnSave ) ), oBrw:DrawLine( .T. ),;
                  oMsgBar:cMsgDef := " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + ;
                                 "/" + AllTrim( Str( ( cAlias )->( RecCount() ) ) ),;
                  oMsgBar:Refresh() )                

   oBrw:nEditTypes = EDIT_GET
   oBrw:aCols[ 1 ]:nEditType = 0 // Don't allow to edit first column
   oBrw:aCols[ 2 ]:bOnChange = { || oBtnSave:Enable() }
   oBrw:aCols[ 2 ]:lWillShowABtn = .T.
   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar ;
      PROMPT " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + "/" + ;
      AllTrim( Str( ( cAlias )->( RecCount() ) ) ) OF oWnd 2010

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS If( ( cAlias )->( Deleted() ), "deleted", "nondeleted" ) ;
          ACTION ( cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
   
   ACTIVATE WINDOW oWnd
   
return nil      

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

function GoPrevRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( -1 )
   
   oBrw:SetArray( aRecord := LoadRecord() )
   oBrw:SetFocus()
   Eval( oBrw:bChange )

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( 1 )
   
   If Eof()
      DbSkip( -1 )
   else
      oBrw:SetArray( aRecord := LoadRecord() )
      oBrw:SetFocus()
      Eval( oBrw:bChange )
   endif  

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function SetEditType( oBrw, oBtnSave )

   local cType := FieldType( oBrw:nArrayAt )
   
   do case
      case cType == "M"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { | c | c := oBrw:aRow[ 2 ],;
                                               MemoEdit( @oBrw:aRow[ 2 ], FieldName( oBrw:nArrayAt ) ),;
                                               If( ! c == oBrw:aRow[ 2 ], oBtnSave:Enable(),),;
                                               oBrw:aRow[ 2 ] }
   
      case cType == "D"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { || If( ! Empty( oBrw:aRow[ 2 ] ) .and. ;
                                                 ! AllTrim( oBrw:aRow[ 2 ] ) == "/  /",;
                                             DToC( MsgDate( CtoD( oBrw:aRow[ 2 ] ) ) ),;
                                             DToC( MsgDate( Date() ) ) ) }
   
      case cType == "L"
           oBrw:aCols[ 2 ]:nEditType = EDIT_LISTBOX
           oBrw:aCols[ 2 ]:aEditListTxt   = { ".T.", ".F." }
           
      otherwise
           oBrw:aCols[ 2 ]:nEditType = EDIT_GET
   endcase
   
return nil              

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

function IndexBuilder()

   local oDlg, cExp := Space( 80 ), cTo := Space( 80 ), cTag := Space( 20 )
   local cFor := Space( 80 ), cWhile := Space( 80 ), lUnique := .F.
   local lDescend := .F., lMemory := .F., cScope := "All", nRecNo
   local oPgr, nMeter := 0, nStep := 10, lTag := .T.
   
   DEFINE DIALOG oDlg TITLE "Index builder" SIZE 530, 380

   @ 0.4, 3 SAY "Expression:" OF oDlg SIZE 40, 8

   @ 0.5, 6 GET cExp OF oDlg SIZE 200, 11 ACTION ExpBuilder( @cExp ) ;
      VALID ! Empty( cExp )
   
   @ 1.5, 6 SAY "To:" OF oDlg SIZE 40, 8

   @ 1.7, 6 GET cTo OF oDlg SIZE 200, 11

   @ 2.6, 5.5 SAY "Tag:" OF oDlg SIZE 40, 8

   @   3, 6 GET cTag OF oDlg SIZE 100, 11
   
   @ 3.7, 5.9 SAY "For:" OF oDlg SIZE 40, 8

   @ 4.3, 6 GET cFor OF oDlg SIZE 200, 11 ACTION ExpBuilder()

   @ 4.8, 5 SAY "While:" OF oDlg SIZE 40, 8

   @ 5.6, 6 GET cWhile OF oDlg SIZE 200, 11 ACTION ExpBuilder()
   
   @ 6.8, 6.9 CHECKBOX lUnique PROMPT "&Unique" OF oDlg SIZE 50, 8

   @ 6.8, 13.9 CHECKBOX lDescend PROMPT "&Descending" OF oDlg SIZE 80, 8

   @ 6.8, 23 CHECKBOX lMemory PROMPT "&Memory" OF oDlg SIZE 40, 8

   @ 6.8, 8 SAY "Scope:" OF oDlg SIZE 40, 8
   
   @ 8.2, 6 COMBOBOX cScope ITEMS { "All", "Next", "Record", "Rest" } OF oDlg

   @ 6.8, 16.1 SAY "Record:" OF oDlg SIZE 40, 8

   @ 8.8, 12.1 GET nRecNo OF oDlg SIZE 30, 11

   @ 8.5, 8 SAY "Progress:" OF oDlg SIZE 40, 8
   
   @ 9.2, 8 PROGRESS oPgr OF oDlg SIZE 200, 10
   
   @ 9.2, 13 BUTTON "C&reate" OF oDlg SIZE 45, 13 ;
      ACTION ( OrdCondSet( If( ! Empty( cFor ), cFor,),;
                           If( ! Empty( cFor ), GENBLOCK( cFor ),),;
                           If( cScope == "All", .T.,),;
                           If( ! Empty( cWhile ), GENBLOCK( cWhile ),),;
                           { || nMeter += nStep, oPgr:SetPos( nMeter ), SysRefresh() },;
                           nStep, Recno(),;
                           If( cScope == "Next", nRecNo,),;
                           If( cScope == "Record", nRecNo,),;
                           If( cScope == "Rest", .T.,),;
                           If( lDescend, .T.,),;
                           lTag,, .F., .F., .F., .T., .F., .F. ),;
               OrdCreate( OrdBagName(), If( lTag, cTag,), cExp, GENBLOCK( cExp ),;
                          If( lUnique, .T.,) ), oDlg:End() )                                      

   @ 9.2, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
   
   ACTIVATE DIALOG oDlg CENTERED

return nil

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

function Indexes()

   local oWnd, oBar, oBrw, oMsgBar
   local cAlias := Alias(), aIndexes := {}, n
   
   for n = 1 to 15
      if ! Empty( OrdName( n ) )
         AAdd( aIndexes, { n,;
                           OrdName( n ),;
                           OrdKey( n ),;
                           OrdFor( n ),;
                           OrdBagName( n ),;
                           OrdBagExt( n ) } )
      endif  
   next    
   
   DEFINE WINDOW oWnd TITLE "Indexes of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( IndexBuilder(), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION If( MsgYesNo( "Want to delete this tag ?" ),;
                ( ( cAlias )->( OrdBagClear( oBrw:nArrayAt ) ), oBrw:Refresh() ),)

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aIndexes AUTOCOLS LINES ;
      HEADERS "Order", "TagName", "Expression", "For", "BagName", "BagExt" ;
      COLSIZES 50, 150, 400, 400, 150, 150

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010
   
   ACTIVATE WINDOW oWnd

return nil

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

function ExpBuilder( cExp )

   local oDlg, oBrw, aFields := DBStruct()
   local oExp
   
   cExp = RTrim( cExp )
   
   DEFINE DIALOG oDlg TITLE "Expression builder" SIZE 480, 450
   
   @ 0.2, 1.5 SAY "Expression:" SIZE 80, 11 OF oDlg
   
   @ 1.1, 1 GET oExp VAR cExp MEMO SIZE 221, 27
   
   @ 3, 1.5 SAY "Fields" OF oDlg SIZE 40, 10
   
   @ 4, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES SIZE 120, 120 ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 95, 30, 30, 30
     
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:bLDblClick = { || cExp += oBrw:aRow[ 1 ], oExp:Refresh() }

   @ 3, 23.1 SAY "Operators" OF oDlg SIZE 40, 10

   @ 3.1, 23 BUTTON "=" OF oDlg SIZE 15, 15 ACTION ( cExp += " = ", oExp:Refresh() )

   @ 3.1, 26.2 BUTTON "<>" OF oDlg SIZE 15, 15 ACTION ( cExp += " <> ", oExp:Refresh() )

   @ 3.1, 29.4 BUTTON "+" OF oDlg SIZE 15, 15 ACTION ( cExp += " + ", oExp:Refresh() )

   @ 3.1, 32.6 BUTTON "(" OF oDlg SIZE 15, 15 ACTION ( cExp += " ( ", oExp:Refresh() )

   @ 3.1, 35.8 BUTTON ".T." OF oDlg SIZE 15, 15 ACTION ( cExp += " .T. ", oExp:Refresh() )

   @ 4.1, 23 BUTTON "<" OF oDlg SIZE 15, 15 ACTION ( cExp += " < ", oExp:Refresh() )

   @ 4.1, 26.2 BUTTON ">" OF oDlg SIZE 15, 15 ACTION ( cExp += " > ", oExp:Refresh() )

   @ 4.1, 29.4 BUTTON "-" OF oDlg SIZE 15, 15 ACTION ( cExp += " - ", oExp:Refresh() )

   @ 4.1, 32.6 BUTTON ")" OF oDlg SIZE 15, 15 ACTION ( cExp += " )", oExp:Refresh() )

   @ 4.1, 35.8 BUTTON ".F." OF oDlg SIZE 15, 15 ACTION ( cExp += " .F. ", oExp:Refresh() )

   @ 5.1, 23 BUTTON "<=" OF oDlg SIZE 15, 15 ACTION ( cExp += " <= ", oExp:Refresh() )

   @ 5.1, 26.2 BUTTON ">=" OF oDlg SIZE 15, 15 ACTION ( cExp += " >= ", oExp:Refresh() )

   @ 5.1, 29.4 BUTTON "*" OF oDlg SIZE 15, 15 ACTION ( cExp += " * ", oExp:Refresh() )

   @ 5.1, 32.6 BUTTON "/" OF oDlg SIZE 15, 15 ACTION ( cExp += " / ", oExp:Refresh() )

   @ 5.1, 35.8 BUTTON "$" OF oDlg SIZE 15, 15 ACTION ( cExp += " $ ", oExp:Refresh() )

   @ 6.1, 23 BUTTON '"' OF oDlg SIZE 15, 15 ACTION ( cExp += '"', oExp:Refresh() )

   @ 6.1, 26.2 BUTTON "!" OF oDlg SIZE 15, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 6.1, 29.4 BUTTON "SP" OF oDlg SIZE 15, 15 ACTION ( cExp += " ", oExp:Refresh() )

   @ 6.1, 32.6 BUTTON "," OF oDlg SIZE 15, 15 ACTION ( cExp += ", ", oExp:Refresh() )

   @ 6.1, 35.8 BUTTON ":" OF oDlg SIZE 15, 15 ACTION ( cExp += " : ", oExp:Refresh() )

   @ 7.1, 23 BUTTON "AND" OF oDlg SIZE 27, 15 ACTION ( cExp += " .and. ", oExp:Refresh() )

   @ 7.1, 28.4 BUTTON "OR" OF oDlg SIZE 27, 15 ACTION ( cExp += " .or. ", oExp:Refresh() )

   @ 7.1, 33.7 BUTTON "NOT" OF oDlg SIZE 27, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 11, 13 BUTTON "&Ok" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 11, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
           
   ACTIVATE DIALOG oDlg CENTERED

return cExp

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

function LoadRecord()

   local aRecord := {}, n
   
   for n = 1 to FCount()
      AAdd( aRecord, { FieldName( n ), FieldGet( n ) } )
   next
   
return aRecord      
   
//----------------------------------------------------------------------------//

function Search( oBrw )

   local oDlg, oCbx, cSearch := Space( 50 )
   local nRecNo := RecNo(), lInc := .T.
   
   DEFINE DIALOG oDlg TITLE "Search: " + Alias() SIZE 400, 200
   
   @ 0.5, 1.5 SAY "Ordered by: " + OrdName() OF oDlg
   
   @ 1.2, 1.5 SAY "Key: " + OrdKey() OF oDlg
   
   @ 2.4, 1.2 COMBOBOX oCbx VAR cSearch ITEMS aSearches OF oDlg SIZE 180, 150 ;
     STYLE CBS_DROPDOWN
   
   oCbx:oGet:bChange = { || DbSeek( AllTrim( oCbx:GetText() ), lInc ), oBrw:Refresh() }
   
   @ 3.7, 1.5 CHECKBOX lInc PROMPT "&Incremental" OF oDlg SIZE 80, 10
   
   @ 4, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! DbSeek( AllTrim( cSearch ), lInc ), DbGoTo( nRecNo ),),;
               AAdd( aSearches, AllTrim( cSearch ) ), oDlg:End() )

   @ 4, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil  

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

function SaveRecord( aRecord, nRecNo )

   local n

   ( Alias() )->( DbGoTo( nRecNo ) )
   
   if ( Alias() )->( DbRLock( nRecNo ) )
      for n = 1 to Len( aRecord )
         ( Alias() )->( FieldPut( n, aRecord[ n ][ 2 ] ) )
      next
      ( Alias() )->( DbUnLock() )
      MsgInfo( "Record updated" )
   else
      MsgAlert( "Record in use, please try it again" )
   endif        

return nil      

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

function Struct()

   local oDlg, oBrw, aFields := DbStruct()
   
   DEFINE DIALOG oDlg TITLE Alias() + " fields" SIZE 400, 400

   @ 0, 0 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 150, 50, 80, 80

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
     
   oDlg:oClient = oBrw
   
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( BuildStructBar( oDlg, oBrw ), oDlg:Resize(), oBrw:SetFocus() )
   
return nil  

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

function BuildStructBar( oDlg, oBrw )

   local oBar

   DEFINE BUTTONBAR oBar OF oDlg 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Code" RESOURCE "code" ;
      ACTION ( TxtStruct(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oDlg:End() GROUP

return nil

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

function TxtStruct()

   local cCode := "local aFields := { ", n
   
   for n = 1 to FCount()
      if n > 1
         cCode += Space( 27 )
      endif  
      cCode += '{ "' + FieldName( n ) + '", "' + ;
               FieldType( n ) + '", ' + ;
               AllTrim( Str( FieldLen( n ) ) ) + ", " + ;
               AllTrim( Str( FieldDec( n ) ) ) + " },;" + CRLF
   next
   
   cCode = SubStr( cCode, 1, Len( cCode ) - 4 ) + " }"
   
   MemoEdit( cCode, "Code" )

return nil

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

function View( cFileName, oWnd )

   local cExt := Lower( cFileExt( cFileName ) )
   
   do case
      case cExt == "bmp"
           WinExec( "mspaint" + " " + cFileName )
           
      case cExt == "txt"
           WinExec( "notepad" + " " + cFileName )    
           
      otherwise
           ShellExecute( oWnd:hWnd, "Open", cFileName )
   endcase
   
return nil                

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

function New()

   local oDlg, oGet, oBrw, oBtn
   local cFieldName := Space( 10 ), cType := "Character", nLen := 10, nDec := 0
   local aFields := { Array( 4 ) }, cDbfName := Space( 8 ), aTemp
   local oLen, oDec, aType := { "Character", "Number", "Date", "Logical", "Memo" }
   local bChange := {|| If( cType == "Character", (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        If( cType == "Number",    (nLen := 10, nDec := 0, oDec:Enable()  ),),;
                        If( cType == "Date",      (nLen := 8,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Logical",   (nLen := 1,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Memo",      (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        oDlg:Update() }
   local bEdit := {|| IF ( !Empty (aFields[1,1]) ,;
                      (oBtn:Enable (),;
                       cFieldName := aFields[oBrw:nArrayAt,1] ,;
                       cType := aFields[oBrw:nArrayAt,2] ,;
                       cType := aType[ aScan(aType, {|x| Left(x,1) = cType} )],;
                       Eval (bChange) ,;
                       nLen := aFields[oBrw:nArrayAt,3] ,;
                       nDec := aFields[oBrw:nArrayAt,4] ,;
                       oGet:SetPos( 0 ),;
                       oGet:SetFocus(),;
                       oDlg:Update() ) ,) ;
                     }
   local bSave := {|| oBtn:Disable (),;
                      aFields[oBrw:nArrayAt,1] := cFieldname,;
                      aFields[oBrw:nArrayAt,2] := Left (cType,1),;
                      aFields[oBrw:nArrayAt,3] := nLen,;
                      aFields[oBrw:nArrayAt,4] := nDec,;
                      oBrw:SetArray (aFields),;
                      cFieldName := Space( 10 ),;
                      Eval (bChange) ,;
                      oDlg:Update() ,;
                      oGet:SetPos( 0 ),;
                      oGet:SetFocus(),;
                      oBrw:GoBottom();
                      }

   DEFINE DIALOG oDlg TITLE "DBF builder" SIZE 415, 400

   @ 0.5,  2 SAY "Field Name" OF oDlg SIZE 40, 8
   @ 0.5, 10 SAY "Type" OF oDlg SIZE 40, 8
   @ 0.5, 17 SAY "Len" OF oDlg SIZE 40, 8
   @ 0.5, 22 SAY "Dec" OF oDlg SIZE 20, 8

   @ 1.4, 1 GET oGet VAR cFieldName PICTURE "!!!!!!!!!!" OF oDlg SIZE 41, 11 UPDATE

   @ 1.3, 6.5 COMBOBOX cType ITEMS aType ;
      OF oDlg ON CHANGE Eval (bChange) UPDATE

   @ 1.4, 11.9 GET oLen VAR nLen PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 1.4, 15.4 GET oDec VAR nDec PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 0.9, 26 BUTTON "&Add" OF oDlg SIZE 45, 13 ;
      ACTION AddField( @aFields, @cFieldName, @cType, @nLen, @nDec, oGet, oBrw )

   @ 2.4, 26 BUTTON oBtn PROMPT "&Edit" OF oDlg SIZE 45, 13 ;
     ACTION Eval (bSave)

   @ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
     ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

   @ 4.4, 26 BUTTON "Move &Up" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt > 1,;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt - 1 ],;
                   aFields[ oBrw:nArrayAt - 1 ] := aTemp,;
                   oBrw:GoUp() ),)

   @ 5.4, 26 BUTTON "Move D&own" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt < Len( aFields ),;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt + 1 ],;
                   aFields[ oBrw:nArrayAt + 1 ] := aTemp,;
                   oBrw:GoDown() ),)

   @ 6.4, 26 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 2.2, 2 SAY "Fields" OF oDlg SIZE 40, 8

   @ 3.2, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 90, 55, 40, 40 ;
      SIZE 140, 130 OF oDlg ;
      ON DBLCLICK Eval (bEdit)

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   @ 12.1, 2 SAY "DBF Name:" OF oDlg SIZE 30, 8

   @ 14, 6 GET cDbfName PICTURE "!!!!!!!!!!!!" OF oDlg SIZE 100, 11

   @ 10, 26 BUTTON "&Create" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! Empty( cDbfName ) .and. Len( aFields ) > 0,;
          DbCreate( AllTrim( cDbfName ), aFields ),), oDlg:End(),;
          Open( hb_CurDrive() + ":\" + CurDir() + "\" + AllTrim( cDbfName ) ) )

   ACTIVATE DIALOG oDlg CENTERED ON INIT (Eval (bChange), oBtn:Disable() ) ;
                                 VALID !GETKEYSTATE( VK_ESCAPE )

return nil

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

function AddField( aFields, cFieldName, cType, nLen, nDec, oGet, oBrw )

   if Empty( cFieldName )
      oGet:SetPos( 0 )
      return nil
   endif

   if Len( aFields ) == 1 .and. Empty( aFields[ 1 ][ 1 ] )
      aFields = { { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } }
   else
      AAdd( aFields, { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } )
   endif

   oBrw:SetArray( aFields )
   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()

return nil
       
//----------------------------------------------------------------------------//

function OrdTagsCount()

   local n, nCount := 0
   
   for n = 1 to 100
      if ! Empty( OrdName( n ) )
         nCount++
      endif  
   next
   
return nCount  
   
//----------------------------------------------------------------------------//  

function Paste()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Paste()
   endif  

return nil

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

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapirdd.h>

HB_FUNC( ORDCONDGET )
{
   AREAP pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer();
   
   if( pArea )
   {
      LPDBORDERCONDINFO lpdbOrdCondInfo = pArea->lpdbOrdCondInfo;
     
      if( lpdbOrdCondInfo && lpdbOrdCondInfo->abWhile )
         hb_retc( lpdbOrdCondInfo->abWhile );
      else
         hb_retc( "
" );  
   }
   else
      hb_retc( "
" );    
}

#pragma ENDDUMP

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

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

Re: FiveDBU for 32/64 bits

Postby Antonio Linares » Tue Jun 05, 2012 12:35 pm

Started the functions list implementation in the Expression Builder:

Image

Code: Select all  Expand view  RUN
#include "FiveWin.ch"
#include "xbrowse.ch"

#ifdef __XHARBOUR__
   #define hb_CurDrive() CurDrive()
#endif  

#define GENBLOCK(x)  &( "{ || " + x + " }" )

REQUEST DBFCDX

static oWndMain, oMruDBFs, aSearches := {}

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

function Main( cDbfName )

   local oBar, oBmpTiled
   
   SET DATE FORMAT TO "DD/MM/YYYY"

   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"

   DEFINE WINDOW oWndMain TITLE "FiveDBU" MDI MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION New()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION Open()

   DEFINE BUTTON OF oBar PROMPT "Copy" RESOURCE "copy" ACTION Copy() GROUP

   DEFINE BUTTON OF oBar PROMPT "Paste" RESOURCE "paste" ACTION Paste()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION oWndMain:PrevWindow() GROUP WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION oWndMain:NextWindow() WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   DEFINE MSGBAR PROMPT "FiveDBU 32/64 bits, (c) FiveTech Software 2012" ;
      OF oWndMain 2010 KEYBOARD DATE

   if ! Empty( cDbfName )
      Open( cDbfName )
   endif  

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )
   
   oBmpTiled:End()      

return nil

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

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Files"
      MENU
         MENUITEM "New..."
         MENUITEM "Open..." ACTION Open()
         SEPARATOR
         MENUITEM "Recent files"
         MENU
            MRU oMruDBFs ;
               FILENAME ".\FiveDBU.ini" ;    // .INI to manipulate. '\.' for local
               SECTION  "Recent DBF files" ; // The name of the INI section
               ACTION   Open( cMruItem ) ;   // cMruItem is automatically provided
               MESSAGE  "Open this file" ;   // The message for all of them
               SIZE     10
         ENDMENU      

         SEPARATOR
         MENUITEM "Exit" ACTION oWndMain:End()
      ENDMENU
     
      // oMenu:AddEdit()
      oMenu:AddMdi()
      oMenu:AddHelp( "FiveDBU", "(c) FiveTech Software 2012" )
   ENDMENU
   
return oMenu      

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

function Open( cFileName )

   local oWnd, oBar, oBrw, oMsgBar, oMsgDeleted, oMsgTagName
   local oPopup, cAlias, n, cClrBack, nTags
   
   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )
   
   if Empty( cFileName )
      return nil
   endif  
   
   if ! "." $ cFileName
      cFileName += ".dbf"
   endif  
   
   if ! File( cFileName )
      MsgStop( "File not found: " + cFileName )
      return nil
   endif
   
   if File( cFileNoExt( cFileName ) + ".ntx" )
      USE ( cFileName ) VIA "DBFNTX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
   else  
      USE ( cFileName ) VIA "DBFCDX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
      cAlias = Alias()
   endif        
   
   oMruDBFs:Save( cFileName )
   
   MENU oPopup POPUP
      MENUITEM "Natural order" ;
         ACTION ( ( cAlias )->( DbSetOrder( 0 ) ), oBrw:Refresh(), oBrw:SetFocus(),;
                  ( cAlias )->( Eval( oBrw:bChange ) ) )
     
      if ( nTags := ( cAlias )->( OrdTagsCount() ) ) > 0
         SEPARATOR
      endif  
     
      for n = 1 to nTags
         if ! Empty( OrdName( n ) )
            if ! Empty( OrdName( 1 ) )
               DbSetOrder( OrdName( 1 ) )
               DbGoTop()
            endif  
            MENUITEM OrdName( n ) ;
               ACTION ( ( cAlias )->( DbSetOrder( oMenuItem:cPrompt ) ),;
                        oBrw:Refresh(), ( cAlias )->( Eval( oBrw:bChange ) ), oBrw:SetFocus() )
         endif
      next    
   ENDMENU  
   
   DEFINE WINDOW oWnd TITLE "Browse " + cFileName MDICHILD

   oWnd:bCopy = { || MsgInfo( "copy" ) }

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( ( oBrw:cAlias )->( DbAppend() ), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( oBrw:cAlias )->( Edit() )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION ( obrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )

   DEFINE BUTTON OF oBar PROMPT "Search" RESOURCE "search" ;
      GROUP ACTION ( cAlias )->( Search( oBrw ) )

   DEFINE BUTTON OF oBar PROMPT "Index" RESOURCE "index" ;
      MENU oPopup ACTION ( cAlias )->( Indexes() )

   DEFINE BUTTON OF oBar PROMPT "Top" RESOURCE "top" ;
      ACTION ( oBrw:GoTop(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Bottom" RESOURCE "bottom" ;
      ACTION ( oBrw:GoBottom(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Struct" RESOURCE "struct" ;
      ACTION ( oBrw:cAlias )->( Struct() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report()

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd LINES ;
      ON CHANGE ( oMsgBar:cMsgDef := "Alias: " + Alias() + ;
                                     " RecNo: " + AllTrim( Str( RecNo() ) ) + "/" + ;
                                     AllTrim( Str( RecCount() ) ),;
                                     oMsgBar:Refresh(),;
                                     oMsgTagName:SetText( "Ordered by: " + If( ! Empty( OrdName() ), OrdName(), "Natural order" ) ),;
                                     oMsgDeleted:SetText( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "DELETED", "NON DELETED" ) ),;
                                     oMsgDeleted:SetBitmap( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "deleted", "nondeleted" ) ) )

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 198, 255, 198 ) }, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                           RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]                                              
   oBrw:bClrSelFocus = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                              cClrBack } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   oBrw:bLDblClick = { || ( oBrw:cAlias )->( Edit() ) }                      
   
   oWnd:oClient = oBrw
   oWnd:oControl = oBrw

   DEFINE MSGBAR oMsgBar PROMPT "Alias: " + Alias() + " | RecNo: " + ;
      AllTrim( Str( RecNo() ) ) + "/" + ;
      AllTrim( Str( RecCount() ) ) ;
      OF oWnd 2010

   DEFINE MSGITEM oMsgTagName OF oMsgBar ;
          PROMPT "Ordered by: " + ;
          If( ! Empty( ( oBrw:cAlias )->( OrdName() ) ),;
              ( oBrw:cAlias )->( OrdName() ), "Natural order" ) ;
          SIZE 150

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( oBrw:cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS "nondeleted" ;
          ACTION ( oBrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
         
   ACTIVATE WINDOW oWnd ;
      VALID ( ( cAlias )->( DbCloseArea() ), oBrw:cAlias := "", .T. )
   
return nil  

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

function Copy()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Copy()
   endif  

return nil

//----------------------------------------------------------------------------//
 
function DelField( aFields, cFieldName, oGet, oBrw )

   if Len( aFields ) >= 1
      ADel( aFields, oBrw:nArrayAt, .T. )
      oBrw:SetArray( aFields )
   endif

   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()
               
return nil

//----------------------------------------------------------------------------//
       
function DelRecord( oBrw, oMsgDeleted )

   if ! Deleted()
      if ! MsgYesNo( "Want to delete this record ?" )
         return nil
      endif  
      DbRLock()  
      DbDelete()  
      DbUnlock()  
      oMsgDeleted:SetText( "DELETED" )
      oMsgDeleted:SetBitmap( "deleted" )
   else
      DbRLock()  
      DbRecall()  
      DbUnlock()        
      oMsgDeleted:SetText( "NON DELETED" )
      oMsgDeleted:SetBitmap( "nondeleted" )
      MsgInfo( "UnDeleted record" )
   endif
   
   Eval( oBrw:bChange )
   oBrw:Refresh()

return nil  

//----------------------------------------------------------------------------//
   
function Edit()

   local oWnd, aRecord := ( Alias() )->( LoadRecord() ), oBar, oBrw, oMsgBar
   local cAlias := Alias(), oBtnSave, nRecNo := ( Alias() )->( RecNo() )
   local oMsgDeleted
   
   DEFINE WINDOW oWnd TITLE "Edit " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" RESOURCE "save" ;
      ACTION ( ( cAlias )->( SaveRecord( aRecord, nRecNo ) ), oBtnSave:Disable() )

   oBtnSave:Disable()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION GoPrevRecord( oBrw, aRecord, oMsgDeleted ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP

   DEFINE BUTTON OF oBar PROMPT "View" RESOURCE "view" ;
      ACTION View( oBrw:aRow[ 2 ], oWnd )
     
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRecord AUTOCOLS LINES ;
      HEADERS "FieldName", "Value" COLSIZES 150, 400 FASTEDIT ;
      ON CHANGE ( ( cAlias )->( SetEditType( oBrw, oBtnSave ) ), oBrw:DrawLine( .T. ),;
                  oMsgBar:cMsgDef := " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + ;
                                 "/" + AllTrim( Str( ( cAlias )->( RecCount() ) ) ),;
                  oMsgBar:Refresh() )                

   oBrw:nEditTypes = EDIT_GET
   oBrw:aCols[ 1 ]:nEditType = 0 // Don't allow to edit first column
   oBrw:aCols[ 2 ]:bOnChange = { || oBtnSave:Enable() }
   oBrw:aCols[ 2 ]:lWillShowABtn = .T.
   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar ;
      PROMPT " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + "/" + ;
      AllTrim( Str( ( cAlias )->( RecCount() ) ) ) OF oWnd 2010

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS If( ( cAlias )->( Deleted() ), "deleted", "nondeleted" ) ;
          ACTION ( cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
   
   ACTIVATE WINDOW oWnd
   
return nil      

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

function GoPrevRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( -1 )
   
   oBrw:SetArray( aRecord := LoadRecord() )
   oBrw:SetFocus()
   Eval( oBrw:bChange )

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( 1 )
   
   If Eof()
      DbSkip( -1 )
   else
      oBrw:SetArray( aRecord := LoadRecord() )
      oBrw:SetFocus()
      Eval( oBrw:bChange )
   endif  

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function SetEditType( oBrw, oBtnSave )

   local cType := FieldType( oBrw:nArrayAt )
   
   do case
      case cType == "M"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { | c | c := oBrw:aRow[ 2 ],;
                                               MemoEdit( @oBrw:aRow[ 2 ], FieldName( oBrw:nArrayAt ) ),;
                                               If( ! c == oBrw:aRow[ 2 ], oBtnSave:Enable(),),;
                                               oBrw:aRow[ 2 ] }
   
      case cType == "D"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { || If( ! Empty( oBrw:aRow[ 2 ] ) .and. ;
                                                 ! AllTrim( oBrw:aRow[ 2 ] ) == "/  /",;
                                             DToC( MsgDate( CtoD( oBrw:aRow[ 2 ] ) ) ),;
                                             DToC( MsgDate( Date() ) ) ) }
   
      case cType == "L"
           oBrw:aCols[ 2 ]:nEditType = EDIT_LISTBOX
           oBrw:aCols[ 2 ]:aEditListTxt   = { ".T.", ".F." }
           
      otherwise
           oBrw:aCols[ 2 ]:nEditType = EDIT_GET
   endcase
   
return nil              

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

function IndexBuilder()

   local oDlg, cExp := Space( 80 ), cTo := Space( 80 ), cTag := Space( 20 )
   local cFor := Space( 80 ), cWhile := Space( 80 ), lUnique := .F.
   local lDescend := .F., lMemory := .F., cScope := "All", nRecNo
   local oPgr, nMeter := 0, nStep := 10, lTag := .T.
   
   DEFINE DIALOG oDlg TITLE "Index builder" SIZE 530, 380

   @ 0.4, 3 SAY "Expression:" OF oDlg SIZE 40, 8

   @ 0.5, 6 GET cExp OF oDlg SIZE 200, 11 ACTION ExpBuilder( @cExp ) ;
      VALID ! Empty( cExp )
   
   @ 1.5, 6 SAY "To:" OF oDlg SIZE 40, 8

   @ 1.7, 6 GET cTo OF oDlg SIZE 200, 11

   @ 2.6, 5.5 SAY "Tag:" OF oDlg SIZE 40, 8

   @   3, 6 GET cTag OF oDlg SIZE 100, 11
   
   @ 3.7, 5.9 SAY "For:" OF oDlg SIZE 40, 8

   @ 4.3, 6 GET cFor OF oDlg SIZE 200, 11 ACTION ExpBuilder()

   @ 4.8, 5 SAY "While:" OF oDlg SIZE 40, 8

   @ 5.6, 6 GET cWhile OF oDlg SIZE 200, 11 ACTION ExpBuilder()
   
   @ 6.8, 6.9 CHECKBOX lUnique PROMPT "&Unique" OF oDlg SIZE 50, 8

   @ 6.8, 13.9 CHECKBOX lDescend PROMPT "&Descending" OF oDlg SIZE 80, 8

   @ 6.8, 23 CHECKBOX lMemory PROMPT "&Memory" OF oDlg SIZE 80, 8

   @ 6.8, 8 SAY "Scope:" OF oDlg SIZE 40, 8
   
   @ 8.2, 6 COMBOBOX cScope ITEMS { "All", "Next", "Record", "Rest" } OF oDlg

   @ 6.8, 16.1 SAY "Record:" OF oDlg SIZE 40, 8

   @ 8.8, 12.1 GET nRecNo OF oDlg SIZE 30, 11

   @ 8.5, 8 SAY "Progress:" OF oDlg SIZE 40, 8
   
   @ 9.2, 8 PROGRESS oPgr OF oDlg SIZE 200, 10
   
   @ 9.2, 13 BUTTON "C&reate" OF oDlg SIZE 45, 13 ;
      ACTION ( OrdCondSet( If( ! Empty( cFor ), cFor,),;
                           If( ! Empty( cFor ), GENBLOCK( cFor ),),;
                           If( cScope == "All", .T.,),;
                           If( ! Empty( cWhile ), GENBLOCK( cWhile ),),;
                           { || nMeter += nStep, oPgr:SetPos( nMeter ), SysRefresh() },;
                           nStep, Recno(),;
                           If( cScope == "Next", nRecNo,),;
                           If( cScope == "Record", nRecNo,),;
                           If( cScope == "Rest", .T.,),;
                           If( lDescend, .T.,),;
                           lTag,, .F., .F., .F., .T., .F., .F. ),;
               OrdCreate( OrdBagName(), If( lTag, cTag,), cExp, GENBLOCK( cExp ),;
                          If( lUnique, .T.,) ), oDlg:End() )                                      

   @ 9.2, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
   
   ACTIVATE DIALOG oDlg CENTERED

return nil

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

function Indexes()

   local oWnd, oBar, oBrw, oMsgBar
   local cAlias := Alias(), aIndexes := {}, n
   
   for n = 1 to 15
      if ! Empty( OrdName( n ) )
         AAdd( aIndexes, { n,;
                           OrdName( n ),;
                           OrdKey( n ),;
                           OrdFor( n ),;
                           OrdBagName( n ),;
                           OrdBagExt( n ) } )
      endif  
   next    
   
   DEFINE WINDOW oWnd TITLE "Indexes of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( IndexBuilder(), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION If( MsgYesNo( "Want to delete this tag ?" ),;
                ( ( cAlias )->( OrdBagClear( oBrw:nArrayAt ) ), oBrw:Refresh() ),)

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aIndexes AUTOCOLS LINES ;
      HEADERS "Order", "TagName", "Expression", "For", "BagName", "BagExt" ;
      COLSIZES 50, 150, 400, 400, 150, 150

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010
   
   ACTIVATE WINDOW oWnd

return nil

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

function ExpBuilder( cExp )

   local oDlg, oBrw, aFields := DBStruct()
   local oExp, cFunction
   
   cExp = RTrim( cExp )
   
   DEFINE DIALOG oDlg TITLE "Expression builder" SIZE 480, 450
   
   @ 0.2, 1.5 SAY "Expression:" SIZE 80, 11 OF oDlg
   
   @ 1.1, 1 GET oExp VAR cExp MEMO SIZE 221, 27
   
   @ 3, 1.5 SAY "Fields" OF oDlg SIZE 40, 10
   
   @ 4, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES SIZE 120, 120 ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 95, 30, 30, 30
     
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:bLDblClick = { || cExp += oBrw:aRow[ 1 ], oExp:Refresh() }

   @ 3, 23.1 SAY "Operators" OF oDlg SIZE 40, 10

   @ 3.1, 23 BUTTON "=" OF oDlg SIZE 15, 15 ACTION ( cExp += " = ", oExp:Refresh() )

   @ 3.1, 26.2 BUTTON "<>" OF oDlg SIZE 15, 15 ACTION ( cExp += " <> ", oExp:Refresh() )

   @ 3.1, 29.4 BUTTON "+" OF oDlg SIZE 15, 15 ACTION ( cExp += " + ", oExp:Refresh() )

   @ 3.1, 32.6 BUTTON "(" OF oDlg SIZE 15, 15 ACTION ( cExp += " ( ", oExp:Refresh() )

   @ 3.1, 35.8 BUTTON ".T." OF oDlg SIZE 15, 15 ACTION ( cExp += " .T. ", oExp:Refresh() )

   @ 4.1, 23 BUTTON "<" OF oDlg SIZE 15, 15 ACTION ( cExp += " < ", oExp:Refresh() )

   @ 4.1, 26.2 BUTTON ">" OF oDlg SIZE 15, 15 ACTION ( cExp += " > ", oExp:Refresh() )

   @ 4.1, 29.4 BUTTON "-" OF oDlg SIZE 15, 15 ACTION ( cExp += " - ", oExp:Refresh() )

   @ 4.1, 32.6 BUTTON ")" OF oDlg SIZE 15, 15 ACTION ( cExp += " )", oExp:Refresh() )

   @ 4.1, 35.8 BUTTON ".F." OF oDlg SIZE 15, 15 ACTION ( cExp += " .F. ", oExp:Refresh() )

   @ 5.1, 23 BUTTON "<=" OF oDlg SIZE 15, 15 ACTION ( cExp += " <= ", oExp:Refresh() )

   @ 5.1, 26.2 BUTTON ">=" OF oDlg SIZE 15, 15 ACTION ( cExp += " >= ", oExp:Refresh() )

   @ 5.1, 29.4 BUTTON "*" OF oDlg SIZE 15, 15 ACTION ( cExp += " * ", oExp:Refresh() )

   @ 5.1, 32.6 BUTTON "/" OF oDlg SIZE 15, 15 ACTION ( cExp += " / ", oExp:Refresh() )

   @ 5.1, 35.8 BUTTON "$" OF oDlg SIZE 15, 15 ACTION ( cExp += " $ ", oExp:Refresh() )

   @ 6.1, 23 BUTTON '"' OF oDlg SIZE 15, 15 ACTION ( cExp += '"', oExp:Refresh() )

   @ 6.1, 26.2 BUTTON "!" OF oDlg SIZE 15, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 6.1, 29.4 BUTTON "SP" OF oDlg SIZE 15, 15 ACTION ( cExp += " ", oExp:Refresh() )

   @ 6.1, 32.6 BUTTON "," OF oDlg SIZE 15, 15 ACTION ( cExp += ", ", oExp:Refresh() )

   @ 6.1, 35.8 BUTTON ":" OF oDlg SIZE 15, 15 ACTION ( cExp += " : ", oExp:Refresh() )

   @ 7.1, 23 BUTTON "AND" OF oDlg SIZE 27, 15 ACTION ( cExp += " .and. ", oExp:Refresh() )

   @ 7.1, 28.4 BUTTON "OR" OF oDlg SIZE 27, 15 ACTION ( cExp += " .or. ", oExp:Refresh() )

   @ 7.1, 33.7 BUTTON "NOT" OF oDlg SIZE 27, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 10.3, 23.2 SAY "Functions" OF oDlg SIZE 84, 11

   @ 11.9, 17.3 COMBOBOX cFunction ITEMS { "AllTrim()", "Left()", "Right()", "SubStr()" } ;
      OF oDlg SIZE 92, 80 ON CHANGE ( cExp += Left( cFunction, Len( cFunction ) - 1 ) + " ",;
                                      oExp:Refresh() )

   @ 11, 13 BUTTON "&Ok" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 11, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
           
   ACTIVATE DIALOG oDlg CENTERED

return cExp

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

function LoadRecord()

   local aRecord := {}, n
   
   for n = 1 to FCount()
      AAdd( aRecord, { FieldName( n ), FieldGet( n ) } )
   next
   
return aRecord      
   
//----------------------------------------------------------------------------//

function Search( oBrw )

   local oDlg, oCbx, cSearch := Space( 50 )
   local nRecNo := RecNo(), lInc := .T.
   
   DEFINE DIALOG oDlg TITLE "Search: " + Alias() SIZE 400, 200
   
   @ 0.5, 1.5 SAY "Ordered by: " + OrdName() OF oDlg
   
   @ 1.2, 1.5 SAY "Key: " + OrdKey() OF oDlg
   
   @ 2.4, 1.2 COMBOBOX oCbx VAR cSearch ITEMS aSearches OF oDlg SIZE 180, 150 ;
     STYLE CBS_DROPDOWN
   
   oCbx:oGet:bChange = { || DbSeek( AllTrim( oCbx:GetText() ), lInc ), oBrw:Refresh() }
   
   @ 3.7, 1.5 CHECKBOX lInc PROMPT "&Incremental" OF oDlg SIZE 80, 10
   
   @ 4, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! DbSeek( AllTrim( cSearch ), lInc ), DbGoTo( nRecNo ),),;
               AAdd( aSearches, AllTrim( cSearch ) ), oDlg:End() )

   @ 4, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil  

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

function SaveRecord( aRecord, nRecNo )

   local n

   ( Alias() )->( DbGoTo( nRecNo ) )
   
   if ( Alias() )->( DbRLock( nRecNo ) )
      for n = 1 to Len( aRecord )
         ( Alias() )->( FieldPut( n, aRecord[ n ][ 2 ] ) )
      next
      ( Alias() )->( DbUnLock() )
      MsgInfo( "Record updated" )
   else
      MsgAlert( "Record in use, please try it again" )
   endif        

return nil      

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

function Struct()

   local oDlg, oBrw, aFields := DbStruct()
   
   DEFINE DIALOG oDlg TITLE Alias() + " fields" SIZE 400, 400

   @ 0, 0 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 150, 50, 80, 80

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
     
   oDlg:oClient = oBrw
   
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( BuildStructBar( oDlg, oBrw ), oDlg:Resize(), oBrw:SetFocus() )
   
return nil  

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

function BuildStructBar( oDlg, oBrw )

   local oBar

   DEFINE BUTTONBAR oBar OF oDlg 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Code" RESOURCE "code" ;
      ACTION ( TxtStruct(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oDlg:End() GROUP

return nil

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

function TxtStruct()

   local cCode := "local aFields := { ", n
   
   for n = 1 to FCount()
      if n > 1
         cCode += Space( 27 )
      endif  
      cCode += '{ "' + FieldName( n ) + '", "' + ;
               FieldType( n ) + '", ' + ;
               AllTrim( Str( FieldLen( n ) ) ) + ", " + ;
               AllTrim( Str( FieldDec( n ) ) ) + " },;" + CRLF
   next
   
   cCode = SubStr( cCode, 1, Len( cCode ) - 4 ) + " }"
   
   MemoEdit( cCode, "Code" )

return nil

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

function View( cFileName, oWnd )

   local cExt := Lower( cFileExt( cFileName ) )
   
   do case
      case cExt == "bmp"
           WinExec( "mspaint" + " " + cFileName )
           
      case cExt == "txt"
           WinExec( "notepad" + " " + cFileName )    
           
      otherwise
           ShellExecute( oWnd:hWnd, "Open", cFileName )
   endcase
   
return nil                

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

function New()

   local oDlg, oGet, oBrw, oBtn
   local cFieldName := Space( 10 ), cType := "Character", nLen := 10, nDec := 0
   local aFields := { Array( 4 ) }, cDbfName := Space( 8 ), aTemp
   local oLen, oDec, aType := { "Character", "Number", "Date", "Logical", "Memo" }
   local bChange := {|| If( cType == "Character", (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        If( cType == "Number",    (nLen := 10, nDec := 0, oDec:Enable()  ),),;
                        If( cType == "Date",      (nLen := 8,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Logical",   (nLen := 1,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Memo",      (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        oDlg:Update() }
   local bEdit := {|| IF ( !Empty (aFields[1,1]) ,;
                      (oBtn:Enable (),;
                       cFieldName := aFields[oBrw:nArrayAt,1] ,;
                       cType := aFields[oBrw:nArrayAt,2] ,;
                       cType := aType[ aScan(aType, {|x| Left(x,1) = cType} )],;
                       Eval (bChange) ,;
                       nLen := aFields[oBrw:nArrayAt,3] ,;
                       nDec := aFields[oBrw:nArrayAt,4] ,;
                       oGet:SetPos( 0 ),;
                       oGet:SetFocus(),;
                       oDlg:Update() ) ,) ;
                     }
   local bSave := {|| oBtn:Disable (),;
                      aFields[oBrw:nArrayAt,1] := cFieldname,;
                      aFields[oBrw:nArrayAt,2] := Left (cType,1),;
                      aFields[oBrw:nArrayAt,3] := nLen,;
                      aFields[oBrw:nArrayAt,4] := nDec,;
                      oBrw:SetArray (aFields),;
                      cFieldName := Space( 10 ),;
                      Eval (bChange) ,;
                      oDlg:Update() ,;
                      oGet:SetPos( 0 ),;
                      oGet:SetFocus(),;
                      oBrw:GoBottom();
                      }

   DEFINE DIALOG oDlg TITLE "DBF builder" SIZE 415, 400

   @ 0.5,  2 SAY "Field Name" OF oDlg SIZE 40, 8
   @ 0.5, 10 SAY "Type" OF oDlg SIZE 40, 8
   @ 0.5, 17 SAY "Len" OF oDlg SIZE 40, 8
   @ 0.5, 22 SAY "Dec" OF oDlg SIZE 20, 8

   @ 1.4, 1 GET oGet VAR cFieldName PICTURE "!!!!!!!!!!" OF oDlg SIZE 41, 11 UPDATE

   @ 1.3, 6.5 COMBOBOX cType ITEMS aType ;
      OF oDlg ON CHANGE Eval (bChange) UPDATE

   @ 1.4, 11.9 GET oLen VAR nLen PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 1.4, 15.4 GET oDec VAR nDec PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 0.9, 26 BUTTON "&Add" OF oDlg SIZE 45, 13 ;
      ACTION AddField( @aFields, @cFieldName, @cType, @nLen, @nDec, oGet, oBrw )

   @ 2.4, 26 BUTTON oBtn PROMPT "&Edit" OF oDlg SIZE 45, 13 ;
     ACTION Eval (bSave)

   @ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
     ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

   @ 4.4, 26 BUTTON "Move &Up" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt > 1,;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt - 1 ],;
                   aFields[ oBrw:nArrayAt - 1 ] := aTemp,;
                   oBrw:GoUp() ),)

   @ 5.4, 26 BUTTON "Move D&own" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt < Len( aFields ),;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt + 1 ],;
                   aFields[ oBrw:nArrayAt + 1 ] := aTemp,;
                   oBrw:GoDown() ),)

   @ 6.4, 26 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 2.2, 2 SAY "Fields" OF oDlg SIZE 40, 8

   @ 3.2, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 90, 55, 40, 40 ;
      SIZE 140, 130 OF oDlg ;
      ON DBLCLICK Eval (bEdit)

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   @ 12.1, 2 SAY "DBF Name:" OF oDlg SIZE 30, 8

   @ 14, 6 GET cDbfName PICTURE "!!!!!!!!!!!!" OF oDlg SIZE 100, 11

   @ 10, 26 BUTTON "&Create" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! Empty( cDbfName ) .and. Len( aFields ) > 0,;
          DbCreate( AllTrim( cDbfName ), aFields ),), oDlg:End(),;
          Open( hb_CurDrive() + ":\" + CurDir() + "\" + AllTrim( cDbfName ) ) )

   ACTIVATE DIALOG oDlg CENTERED ON INIT (Eval (bChange), oBtn:Disable() ) ;
                                 VALID !GETKEYSTATE( VK_ESCAPE )

return nil

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

function AddField( aFields, cFieldName, cType, nLen, nDec, oGet, oBrw )

   if Empty( cFieldName )
      oGet:SetPos( 0 )
      return nil
   endif

   if Len( aFields ) == 1 .and. Empty( aFields[ 1 ][ 1 ] )
      aFields = { { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } }
   else
      AAdd( aFields, { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } )
   endif

   oBrw:SetArray( aFields )
   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()

return nil
       
//----------------------------------------------------------------------------//

function OrdTagsCount()

   local n, nCount := 0
   
   for n = 1 to 100
      if ! Empty( OrdName( n ) )
         nCount++
      endif  
   next
   
return nCount  
   
//----------------------------------------------------------------------------//  

function Paste()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Paste()
   endif  

return nil

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

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapirdd.h>

HB_FUNC( ORDCONDGET )
{
   AREAP pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer();
   
   if( pArea )
   {
      LPDBORDERCONDINFO lpdbOrdCondInfo = pArea->lpdbOrdCondInfo;
     
      if( lpdbOrdCondInfo && lpdbOrdCondInfo->abWhile )
         hb_retc( lpdbOrdCondInfo->abWhile );
      else
         hb_retc( "
" );  
   }
   else
      hb_retc( "
" );    
}

#pragma ENDDUMP

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

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

Re: FiveDBU for 32/64 bits

Postby Antonio Linares » Tue Jun 05, 2012 1:02 pm

Started the relations implementation:

Image

Code: Select all  Expand view  RUN
#include "FiveWin.ch"
#include "xbrowse.ch"
#include "dbinfo.ch"

#ifdef __XHARBOUR__
   #define hb_CurDrive() CurDrive()
#endif  

#define GENBLOCK(x)  &( "{ || " + x + " }" )

REQUEST DBFCDX

static oWndMain, oMruDBFs, aSearches := {}

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

function Main( cDbfName )

   local oBar, oBmpTiled
   
   SET DATE FORMAT TO "DD/MM/YYYY"

   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"

   DEFINE WINDOW oWndMain TITLE "FiveDBU" MDI MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION New()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION Open()

   DEFINE BUTTON OF oBar PROMPT "Copy" RESOURCE "copy" ACTION Copy() GROUP

   DEFINE BUTTON OF oBar PROMPT "Paste" RESOURCE "paste" ACTION Paste()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION oWndMain:PrevWindow() GROUP WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION oWndMain:NextWindow() WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   DEFINE MSGBAR PROMPT "FiveDBU 32/64 bits, (c) FiveTech Software 2012" ;
      OF oWndMain 2010 KEYBOARD DATE

   if ! Empty( cDbfName )
      Open( cDbfName )
   endif  

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )
   
   oBmpTiled:End()      

return nil

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

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Files"
      MENU
         MENUITEM "New..."
         MENUITEM "Open..." ACTION Open()
         SEPARATOR
         MENUITEM "Recent files"
         MENU
            MRU oMruDBFs ;
               FILENAME ".\FiveDBU.ini" ;    // .INI to manipulate. '\.' for local
               SECTION  "Recent DBF files" ; // The name of the INI section
               ACTION   Open( cMruItem ) ;   // cMruItem is automatically provided
               MESSAGE  "Open this file" ;   // The message for all of them
               SIZE     10
         ENDMENU      

         SEPARATOR
         MENUITEM "Exit" ACTION oWndMain:End()
      ENDMENU
     
      // oMenu:AddEdit()
      oMenu:AddMdi()
      oMenu:AddHelp( "FiveDBU", "(c) FiveTech Software 2012" )
   ENDMENU
   
return oMenu      

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

function Open( cFileName )

   local oWnd, oBar, oBrw, oMsgBar, oMsgDeleted, oMsgTagName
   local oPopup, cAlias, n, cClrBack, nTags
   
   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )
   
   if Empty( cFileName )
      return nil
   endif  
   
   if ! "." $ cFileName
      cFileName += ".dbf"
   endif  
   
   if ! File( cFileName )
      MsgStop( "File not found: " + cFileName )
      return nil
   endif
   
   if File( cFileNoExt( cFileName ) + ".ntx" )
      USE ( cFileName ) VIA "DBFNTX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
   else  
      USE ( cFileName ) VIA "DBFCDX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
      cAlias = Alias()
   endif        
   
   oMruDBFs:Save( cFileName )
   
   MENU oPopup POPUP
      MENUITEM "Natural order" ;
         ACTION ( ( cAlias )->( DbSetOrder( 0 ) ), oBrw:Refresh(), oBrw:SetFocus(),;
                  ( cAlias )->( Eval( oBrw:bChange ) ) )
     
      if ( nTags := ( cAlias )->( OrdTagsCount() ) ) > 0
         SEPARATOR
      endif  
     
      for n = 1 to nTags
         if ! Empty( OrdName( n ) )
            if ! Empty( OrdName( 1 ) )
               DbSetOrder( OrdName( 1 ) )
               DbGoTop()
            endif  
            MENUITEM OrdName( n ) ;
               ACTION ( ( cAlias )->( DbSetOrder( oMenuItem:cPrompt ) ),;
                        oBrw:Refresh(), ( cAlias )->( Eval( oBrw:bChange ) ), oBrw:SetFocus() )
         endif
      next    
   ENDMENU  
   
   DEFINE WINDOW oWnd TITLE "Browse " + cFileName MDICHILD

   oWnd:bCopy = { || MsgInfo( "copy" ) }

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( ( oBrw:cAlias )->( DbAppend() ), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( oBrw:cAlias )->( Edit() )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION ( obrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )

   DEFINE BUTTON OF oBar PROMPT "Search" RESOURCE "search" ;
      GROUP ACTION ( cAlias )->( Search( oBrw ) )

   DEFINE BUTTON OF oBar PROMPT "Index" RESOURCE "index" ;
      MENU oPopup ACTION ( cAlias )->( Indexes() )

   DEFINE BUTTON OF oBar PROMPT "Relations" RESOURCE "relation" ;
      ACTION ( cAlias )->( Relations() )

   DEFINE BUTTON OF oBar PROMPT "Top" RESOURCE "top" ;
      ACTION ( oBrw:GoTop(), oBrw:SetFocus() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Bottom" RESOURCE "bottom" ;
      ACTION ( oBrw:GoBottom(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Struct" RESOURCE "struct" ;
      ACTION ( oBrw:cAlias )->( Struct() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report()

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd LINES ;
      ON CHANGE ( oMsgBar:cMsgDef := "Alias: " + Alias() + ;
                                     " RecNo: " + AllTrim( Str( RecNo() ) ) + "/" + ;
                                     AllTrim( Str( RecCount() ) ),;
                                     oMsgBar:Refresh(),;
                                     oMsgTagName:SetText( "Ordered by: " + If( ! Empty( OrdName() ), OrdName(), "Natural order" ) ),;
                                     oMsgDeleted:SetText( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "DELETED", "NON DELETED" ) ),;
                                     oMsgDeleted:SetBitmap( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "deleted", "nondeleted" ) ) )

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 198, 255, 198 ) }, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                           RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]                                              
   oBrw:bClrSelFocus = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                              cClrBack } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   oBrw:bLDblClick = { || ( oBrw:cAlias )->( Edit() ) }                      
   
   oWnd:oClient = oBrw
   oWnd:oControl = oBrw

   DEFINE MSGBAR oMsgBar PROMPT "Alias: " + Alias() + " | RecNo: " + ;
      AllTrim( Str( RecNo() ) ) + "/" + ;
      AllTrim( Str( RecCount() ) ) ;
      OF oWnd 2010

   DEFINE MSGITEM oMsgTagName OF oMsgBar ;
          PROMPT "Ordered by: " + ;
          If( ! Empty( ( oBrw:cAlias )->( OrdName() ) ),;
              ( oBrw:cAlias )->( OrdName() ), "Natural order" ) ;
          SIZE 150

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( oBrw:cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS "nondeleted" ;
          ACTION ( oBrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
         
   ACTIVATE WINDOW oWnd ;
      VALID ( ( cAlias )->( DbCloseArea() ), oBrw:cAlias := "", .T. )
   
return nil  

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

function Copy()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Copy()
   endif  

return nil

//----------------------------------------------------------------------------//
 
function DelField( aFields, cFieldName, oGet, oBrw )

   if Len( aFields ) >= 1
      ADel( aFields, oBrw:nArrayAt, .T. )
      oBrw:SetArray( aFields )
   endif

   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()
               
return nil

//----------------------------------------------------------------------------//
       
function DelRecord( oBrw, oMsgDeleted )

   if ! Deleted()
      if ! MsgYesNo( "Want to delete this record ?" )
         return nil
      endif  
      DbRLock()  
      DbDelete()  
      DbUnlock()  
      oMsgDeleted:SetText( "DELETED" )
      oMsgDeleted:SetBitmap( "deleted" )
   else
      DbRLock()  
      DbRecall()  
      DbUnlock()        
      oMsgDeleted:SetText( "NON DELETED" )
      oMsgDeleted:SetBitmap( "nondeleted" )
      MsgInfo( "UnDeleted record" )
   endif
   
   Eval( oBrw:bChange )
   oBrw:Refresh()

return nil  

//----------------------------------------------------------------------------//
   
function Edit()

   local oWnd, aRecord := ( Alias() )->( LoadRecord() ), oBar, oBrw, oMsgBar
   local cAlias := Alias(), oBtnSave, nRecNo := ( Alias() )->( RecNo() )
   local oMsgDeleted
   
   DEFINE WINDOW oWnd TITLE "Edit " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" RESOURCE "save" ;
      ACTION ( ( cAlias )->( SaveRecord( aRecord, nRecNo ) ), oBtnSave:Disable() )

   oBtnSave:Disable()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION GoPrevRecord( oBrw, aRecord, oMsgDeleted ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP

   DEFINE BUTTON OF oBar PROMPT "View" RESOURCE "view" ;
      ACTION View( oBrw:aRow[ 2 ], oWnd )
     
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRecord AUTOCOLS LINES ;
      HEADERS "FieldName", "Value" COLSIZES 150, 400 FASTEDIT ;
      ON CHANGE ( ( cAlias )->( SetEditType( oBrw, oBtnSave ) ), oBrw:DrawLine( .T. ),;
                  oMsgBar:cMsgDef := " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + ;
                                 "/" + AllTrim( Str( ( cAlias )->( RecCount() ) ) ),;
                  oMsgBar:Refresh() )                

   oBrw:nEditTypes = EDIT_GET
   oBrw:aCols[ 1 ]:nEditType = 0 // Don't allow to edit first column
   oBrw:aCols[ 2 ]:bOnChange = { || oBtnSave:Enable() }
   oBrw:aCols[ 2 ]:lWillShowABtn = .T.
   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar ;
      PROMPT " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + "/" + ;
      AllTrim( Str( ( cAlias )->( RecCount() ) ) ) OF oWnd 2010

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS If( ( cAlias )->( Deleted() ), "deleted", "nondeleted" ) ;
          ACTION ( cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
   
   ACTIVATE WINDOW oWnd
   
return nil      

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

function GoPrevRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( -1 )
   
   oBrw:SetArray( aRecord := LoadRecord() )
   oBrw:SetFocus()
   Eval( oBrw:bChange )

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( 1 )
   
   If Eof()
      DbSkip( -1 )
   else
      oBrw:SetArray( aRecord := LoadRecord() )
      oBrw:SetFocus()
      Eval( oBrw:bChange )
   endif  

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function SetEditType( oBrw, oBtnSave )

   local cType := FieldType( oBrw:nArrayAt )
   
   do case
      case cType == "M"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { | c | c := oBrw:aRow[ 2 ],;
                                               MemoEdit( @oBrw:aRow[ 2 ], FieldName( oBrw:nArrayAt ) ),;
                                               If( ! c == oBrw:aRow[ 2 ], oBtnSave:Enable(),),;
                                               oBrw:aRow[ 2 ] }
   
      case cType == "D"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { || If( ! Empty( oBrw:aRow[ 2 ] ) .and. ;
                                                 ! AllTrim( oBrw:aRow[ 2 ] ) == "/  /",;
                                             DToC( MsgDate( CtoD( oBrw:aRow[ 2 ] ) ) ),;
                                             DToC( MsgDate( Date() ) ) ) }
   
      case cType == "L"
           oBrw:aCols[ 2 ]:nEditType = EDIT_LISTBOX
           oBrw:aCols[ 2 ]:aEditListTxt   = { ".T.", ".F." }
           
      otherwise
           oBrw:aCols[ 2 ]:nEditType = EDIT_GET
   endcase
   
return nil              

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

function IndexBuilder()

   local oDlg, cExp := Space( 80 ), cTo := Space( 80 ), cTag := Space( 20 )
   local cFor := Space( 80 ), cWhile := Space( 80 ), lUnique := .F.
   local lDescend := .F., lMemory := .F., cScope := "All", nRecNo
   local oPgr, nMeter := 0, nStep := 10, lTag := .T.
   
   DEFINE DIALOG oDlg TITLE "Index builder" SIZE 530, 380

   @ 0.4, 3 SAY "Expression:" OF oDlg SIZE 40, 8

   @ 0.5, 6 GET cExp OF oDlg SIZE 200, 11 ACTION ExpBuilder( @cExp ) ;
      VALID ! Empty( cExp )
   
   @ 1.5, 6 SAY "To:" OF oDlg SIZE 40, 8

   @ 1.7, 6 GET cTo OF oDlg SIZE 200, 11

   @ 2.6, 5.5 SAY "Tag:" OF oDlg SIZE 40, 8

   @   3, 6 GET cTag OF oDlg SIZE 100, 11
   
   @ 3.7, 5.9 SAY "For:" OF oDlg SIZE 40, 8

   @ 4.3, 6 GET cFor OF oDlg SIZE 200, 11 ACTION ExpBuilder()

   @ 4.8, 5 SAY "While:" OF oDlg SIZE 40, 8

   @ 5.6, 6 GET cWhile OF oDlg SIZE 200, 11 ACTION ExpBuilder()
   
   @ 6.8, 6.9 CHECKBOX lUnique PROMPT "&Unique" OF oDlg SIZE 50, 8

   @ 6.8, 13.9 CHECKBOX lDescend PROMPT "&Descending" OF oDlg SIZE 80, 8

   @ 6.8, 23 CHECKBOX lMemory PROMPT "&Memory" OF oDlg SIZE 80, 8

   @ 6.8, 8 SAY "Scope:" OF oDlg SIZE 40, 8
   
   @ 8.2, 6 COMBOBOX cScope ITEMS { "All", "Next", "Record", "Rest" } OF oDlg

   @ 6.8, 16.1 SAY "Record:" OF oDlg SIZE 40, 8

   @ 8.8, 12.1 GET nRecNo OF oDlg SIZE 30, 11

   @ 8.5, 8 SAY "Progress:" OF oDlg SIZE 40, 8
   
   @ 9.2, 8 PROGRESS oPgr OF oDlg SIZE 200, 10
   
   @ 9.2, 13 BUTTON "C&reate" OF oDlg SIZE 45, 13 ;
      ACTION ( OrdCondSet( If( ! Empty( cFor ), cFor,),;
                           If( ! Empty( cFor ), GENBLOCK( cFor ),),;
                           If( cScope == "All", .T.,),;
                           If( ! Empty( cWhile ), GENBLOCK( cWhile ),),;
                           { || nMeter += nStep, oPgr:SetPos( nMeter ), SysRefresh() },;
                           nStep, Recno(),;
                           If( cScope == "Next", nRecNo,),;
                           If( cScope == "Record", nRecNo,),;
                           If( cScope == "Rest", .T.,),;
                           If( lDescend, .T.,),;
                           lTag,, .F., .F., .F., .T., .F., .F. ),;
               OrdCreate( OrdBagName(), If( lTag, cTag,), cExp, GENBLOCK( cExp ),;
                          If( lUnique, .T.,) ), oDlg:End() )                                      

   @ 9.2, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
   
   ACTIVATE DIALOG oDlg CENTERED

return nil

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

function Indexes()

   local oWnd, oBar, oBrw, oMsgBar
   local cAlias := Alias(), aIndexes := {}, n
   
   for n = 1 to 15
      if ! Empty( OrdName( n ) )
         AAdd( aIndexes, { n,;
                           OrdName( n ),;
                           OrdKey( n ),;
                           OrdFor( n ),;
                           OrdBagName( n ),;
                           OrdBagExt( n ) } )
      endif  
   next    
   
   DEFINE WINDOW oWnd TITLE "Indexes of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( IndexBuilder(), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION If( MsgYesNo( "Want to delete this tag ?" ),;
                ( ( cAlias )->( OrdBagClear( oBrw:nArrayAt ) ), oBrw:Refresh() ),)

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aIndexes AUTOCOLS LINES ;
      HEADERS "Order", "TagName", "Expression", "For", "BagName", "BagExt" ;
      COLSIZES 50, 150, 400, 400, 150, 150

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010
   
   ACTIVATE WINDOW oWnd

return nil

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

function ExpBuilder( cExp )

   local oDlg, oBrw, aFields := DBStruct()
   local oExp, cFunction
   
   cExp = RTrim( cExp )
   
   DEFINE DIALOG oDlg TITLE "Expression builder" SIZE 480, 450
   
   @ 0.2, 1.5 SAY "Expression:" SIZE 80, 11 OF oDlg
   
   @ 1.1, 1 GET oExp VAR cExp MEMO SIZE 221, 27
   
   @ 3, 1.5 SAY "Fields" OF oDlg SIZE 40, 10
   
   @ 4, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES SIZE 120, 120 ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 95, 30, 30, 30
     
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:bLDblClick = { || cExp += oBrw:aRow[ 1 ], oExp:Refresh() }

   @ 3, 23.1 SAY "Operators" OF oDlg SIZE 40, 10

   @ 3.1, 23 BUTTON "=" OF oDlg SIZE 15, 15 ACTION ( cExp += " = ", oExp:Refresh() )

   @ 3.1, 26.2 BUTTON "<>" OF oDlg SIZE 15, 15 ACTION ( cExp += " <> ", oExp:Refresh() )

   @ 3.1, 29.4 BUTTON "+" OF oDlg SIZE 15, 15 ACTION ( cExp += " + ", oExp:Refresh() )

   @ 3.1, 32.6 BUTTON "(" OF oDlg SIZE 15, 15 ACTION ( cExp += " ( ", oExp:Refresh() )

   @ 3.1, 35.8 BUTTON ".T." OF oDlg SIZE 15, 15 ACTION ( cExp += " .T. ", oExp:Refresh() )

   @ 4.1, 23 BUTTON "<" OF oDlg SIZE 15, 15 ACTION ( cExp += " < ", oExp:Refresh() )

   @ 4.1, 26.2 BUTTON ">" OF oDlg SIZE 15, 15 ACTION ( cExp += " > ", oExp:Refresh() )

   @ 4.1, 29.4 BUTTON "-" OF oDlg SIZE 15, 15 ACTION ( cExp += " - ", oExp:Refresh() )

   @ 4.1, 32.6 BUTTON ")" OF oDlg SIZE 15, 15 ACTION ( cExp += " )", oExp:Refresh() )

   @ 4.1, 35.8 BUTTON ".F." OF oDlg SIZE 15, 15 ACTION ( cExp += " .F. ", oExp:Refresh() )

   @ 5.1, 23 BUTTON "<=" OF oDlg SIZE 15, 15 ACTION ( cExp += " <= ", oExp:Refresh() )

   @ 5.1, 26.2 BUTTON ">=" OF oDlg SIZE 15, 15 ACTION ( cExp += " >= ", oExp:Refresh() )

   @ 5.1, 29.4 BUTTON "*" OF oDlg SIZE 15, 15 ACTION ( cExp += " * ", oExp:Refresh() )

   @ 5.1, 32.6 BUTTON "/" OF oDlg SIZE 15, 15 ACTION ( cExp += " / ", oExp:Refresh() )

   @ 5.1, 35.8 BUTTON "$" OF oDlg SIZE 15, 15 ACTION ( cExp += " $ ", oExp:Refresh() )

   @ 6.1, 23 BUTTON '"' OF oDlg SIZE 15, 15 ACTION ( cExp += '"', oExp:Refresh() )

   @ 6.1, 26.2 BUTTON "!" OF oDlg SIZE 15, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 6.1, 29.4 BUTTON "SP" OF oDlg SIZE 15, 15 ACTION ( cExp += " ", oExp:Refresh() )

   @ 6.1, 32.6 BUTTON "," OF oDlg SIZE 15, 15 ACTION ( cExp += ", ", oExp:Refresh() )

   @ 6.1, 35.8 BUTTON ":" OF oDlg SIZE 15, 15 ACTION ( cExp += " : ", oExp:Refresh() )

   @ 7.1, 23 BUTTON "AND" OF oDlg SIZE 27, 15 ACTION ( cExp += " .and. ", oExp:Refresh() )

   @ 7.1, 28.4 BUTTON "OR" OF oDlg SIZE 27, 15 ACTION ( cExp += " .or. ", oExp:Refresh() )

   @ 7.1, 33.7 BUTTON "NOT" OF oDlg SIZE 27, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 10.3, 23.2 SAY "Functions" OF oDlg SIZE 84, 11

   @ 11.9, 17.3 COMBOBOX cFunction ITEMS { "AllTrim()", "Left()", "Right()", "SubStr()" } ;
      OF oDlg SIZE 92, 80 ON CHANGE ( cExp += Left( cFunction, Len( cFunction ) - 1 ) + " ",;
                                      oExp:Refresh() )

   @ 11, 13 BUTTON "&Ok" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 11, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
           
   ACTIVATE DIALOG oDlg CENTERED

return cExp

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

function LoadRecord()

   local aRecord := {}, n
   
   for n = 1 to FCount()
      AAdd( aRecord, { FieldName( n ), FieldGet( n ) } )
   next
   
return aRecord      
   
//----------------------------------------------------------------------------//

function Search( oBrw )

   local oDlg, oCbx, cSearch := Space( 50 )
   local nRecNo := RecNo(), lInc := .T.
   
   DEFINE DIALOG oDlg TITLE "Search: " + Alias() SIZE 400, 200
   
   @ 0.5, 1.5 SAY "Ordered by: " + OrdName() OF oDlg
   
   @ 1.2, 1.5 SAY "Key: " + OrdKey() OF oDlg
   
   @ 2.4, 1.2 COMBOBOX oCbx VAR cSearch ITEMS aSearches OF oDlg SIZE 180, 150 ;
     STYLE CBS_DROPDOWN
   
   oCbx:oGet:bChange = { || DbSeek( AllTrim( oCbx:GetText() ), lInc ), oBrw:Refresh() }
   
   @ 3.7, 1.5 CHECKBOX lInc PROMPT "&Incremental" OF oDlg SIZE 80, 10
   
   @ 4, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! DbSeek( AllTrim( cSearch ), lInc ), DbGoTo( nRecNo ),),;
               AAdd( aSearches, AllTrim( cSearch ) ), oDlg:End() )

   @ 4, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil  

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

function Relations()

   local oWnd, oBar, oBrw, aRelations := { { "", "", "", "" } }, n
   
   for n = 1 to DbInfo( DBI_CHILDCOUNT )
      AAdd( aRelations, { "exp", "child", ".F.", ".F." } )
   next  
   
   DEFINE WINDOW oWnd TITLE "Relations of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION MsgInfo( "Add" )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION MsgInfo( "del" )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRelations AUTOCOLS LINES ;
      HEADERS "Expression", "Child Alias", "Additive", "Scoped" ;
      COLSIZES 150, 400, 100, 100

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010

   ACTIVATE WINDOW oWnd

return nil

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

function SaveRecord( aRecord, nRecNo )

   local n

   ( Alias() )->( DbGoTo( nRecNo ) )
   
   if ( Alias() )->( DbRLock( nRecNo ) )
      for n = 1 to Len( aRecord )
         ( Alias() )->( FieldPut( n, aRecord[ n ][ 2 ] ) )
      next
      ( Alias() )->( DbUnLock() )
      MsgInfo( "Record updated" )
   else
      MsgAlert( "Record in use, please try it again" )
   endif        

return nil      

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

function Struct()

   local oDlg, oBrw, aFields := DbStruct()
   
   DEFINE DIALOG oDlg TITLE Alias() + " fields" SIZE 400, 400

   @ 0, 0 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 150, 50, 80, 80

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
     
   oDlg:oClient = oBrw
   
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( BuildStructBar( oDlg, oBrw ), oDlg:Resize(), oBrw:SetFocus() )
   
return nil  

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

function BuildStructBar( oDlg, oBrw )

   local oBar

   DEFINE BUTTONBAR oBar OF oDlg 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Code" RESOURCE "code" ;
      ACTION ( TxtStruct(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oDlg:End() GROUP

return nil

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

function TxtStruct()

   local cCode := "local aFields := { ", n
   
   for n = 1 to FCount()
      if n > 1
         cCode += Space( 27 )
      endif  
      cCode += '{ "' + FieldName( n ) + '", "' + ;
               FieldType( n ) + '", ' + ;
               AllTrim( Str( FieldLen( n ) ) ) + ", " + ;
               AllTrim( Str( FieldDec( n ) ) ) + " },;" + CRLF
   next
   
   cCode = SubStr( cCode, 1, Len( cCode ) - 4 ) + " }"
   
   MemoEdit( cCode, "Code" )

return nil

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

function View( cFileName, oWnd )

   local cExt := Lower( cFileExt( cFileName ) )
   
   do case
      case cExt == "bmp"
           WinExec( "mspaint" + " " + cFileName )
           
      case cExt == "txt"
           WinExec( "notepad" + " " + cFileName )    
           
      otherwise
           ShellExecute( oWnd:hWnd, "Open", cFileName )
   endcase
   
return nil                

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

function New()

   local oDlg, oGet, oBrw, oBtn
   local cFieldName := Space( 10 ), cType := "Character", nLen := 10, nDec := 0
   local aFields := { Array( 4 ) }, cDbfName := Space( 8 ), aTemp
   local oLen, oDec, aType := { "Character", "Number", "Date", "Logical", "Memo" }
   local bChange := {|| If( cType == "Character", (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        If( cType == "Number",    (nLen := 10, nDec := 0, oDec:Enable()  ),),;
                        If( cType == "Date",      (nLen := 8,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Logical",   (nLen := 1,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Memo",      (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        oDlg:Update() }
   local bEdit := {|| IF ( !Empty (aFields[1,1]) ,;
                      (oBtn:Enable (),;
                       cFieldName := aFields[oBrw:nArrayAt,1] ,;
                       cType := aFields[oBrw:nArrayAt,2] ,;
                       cType := aType[ aScan(aType, {|x| Left(x,1) = cType} )],;
                       Eval (bChange) ,;
                       nLen := aFields[oBrw:nArrayAt,3] ,;
                       nDec := aFields[oBrw:nArrayAt,4] ,;
                       oGet:SetPos( 0 ),;
                       oGet:SetFocus(),;
                       oDlg:Update() ) ,) ;
                     }
   local bSave := {|| oBtn:Disable (),;
                      aFields[oBrw:nArrayAt,1] := cFieldname,;
                      aFields[oBrw:nArrayAt,2] := Left (cType,1),;
                      aFields[oBrw:nArrayAt,3] := nLen,;
                      aFields[oBrw:nArrayAt,4] := nDec,;
                      oBrw:SetArray (aFields),;
                      cFieldName := Space( 10 ),;
                      Eval (bChange) ,;
                      oDlg:Update() ,;
                      oGet:SetPos( 0 ),;
                      oGet:SetFocus(),;
                      oBrw:GoBottom();
                      }

   DEFINE DIALOG oDlg TITLE "DBF builder" SIZE 415, 400

   @ 0.5,  2 SAY "Field Name" OF oDlg SIZE 40, 8
   @ 0.5, 10 SAY "Type" OF oDlg SIZE 40, 8
   @ 0.5, 17 SAY "Len" OF oDlg SIZE 40, 8
   @ 0.5, 22 SAY "Dec" OF oDlg SIZE 20, 8

   @ 1.4, 1 GET oGet VAR cFieldName PICTURE "!!!!!!!!!!" OF oDlg SIZE 41, 11 UPDATE

   @ 1.3, 6.5 COMBOBOX cType ITEMS aType ;
      OF oDlg ON CHANGE Eval (bChange) UPDATE

   @ 1.4, 11.9 GET oLen VAR nLen PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 1.4, 15.4 GET oDec VAR nDec PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 0.9, 26 BUTTON "&Add" OF oDlg SIZE 45, 13 ;
      ACTION AddField( @aFields, @cFieldName, @cType, @nLen, @nDec, oGet, oBrw )

   @ 2.4, 26 BUTTON oBtn PROMPT "&Edit" OF oDlg SIZE 45, 13 ;
     ACTION Eval (bSave)

   @ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
     ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

   @ 4.4, 26 BUTTON "Move &Up" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt > 1,;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt - 1 ],;
                   aFields[ oBrw:nArrayAt - 1 ] := aTemp,;
                   oBrw:GoUp() ),)

   @ 5.4, 26 BUTTON "Move D&own" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt < Len( aFields ),;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt + 1 ],;
                   aFields[ oBrw:nArrayAt + 1 ] := aTemp,;
                   oBrw:GoDown() ),)

   @ 6.4, 26 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 2.2, 2 SAY "Fields" OF oDlg SIZE 40, 8

   @ 3.2, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 90, 55, 40, 40 ;
      SIZE 140, 130 OF oDlg ;
      ON DBLCLICK Eval (bEdit)

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   @ 12.1, 2 SAY "DBF Name:" OF oDlg SIZE 30, 8

   @ 14, 6 GET cDbfName PICTURE "!!!!!!!!!!!!" OF oDlg SIZE 100, 11

   @ 10, 26 BUTTON "&Create" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! Empty( cDbfName ) .and. Len( aFields ) > 0,;
          DbCreate( AllTrim( cDbfName ), aFields ),), oDlg:End(),;
          Open( hb_CurDrive() + ":\" + CurDir() + "\" + AllTrim( cDbfName ) ) )

   ACTIVATE DIALOG oDlg CENTERED ON INIT (Eval (bChange), oBtn:Disable() ) ;
                                 VALID !GETKEYSTATE( VK_ESCAPE )

return nil

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

function AddField( aFields, cFieldName, cType, nLen, nDec, oGet, oBrw )

   if Empty( cFieldName )
      oGet:SetPos( 0 )
      return nil
   endif

   if Len( aFields ) == 1 .and. Empty( aFields[ 1 ][ 1 ] )
      aFields = { { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } }
   else
      AAdd( aFields, { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } )
   endif

   oBrw:SetArray( aFields )
   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()

return nil
       
//----------------------------------------------------------------------------//

function OrdTagsCount()

   local n, nCount := 0
   
   for n = 1 to 100
      if ! Empty( OrdName( n ) )
         nCount++
      endif  
   next
   
return nCount  
   
//----------------------------------------------------------------------------//  

function Paste()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Paste()
   endif  

return nil

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

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapirdd.h>

HB_FUNC( ORDCONDGET )
{
   AREAP pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer();
   
   if( pArea )
   {
      LPDBORDERCONDINFO lpdbOrdCondInfo = pArea->lpdbOrdCondInfo;
     
      if( lpdbOrdCondInfo && lpdbOrdCondInfo->abWhile )
         hb_retc( lpdbOrdCondInfo->abWhile );
      else
         hb_retc( "
" );  
   }
   else
      hb_retc( "
" );    
}

#pragma ENDDUMP

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

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

Re: FiveDBU for 32/64 bits

Postby StefanHaupt » Tue Jun 05, 2012 1:29 pm

ukoenig wrote:Stefan,

Function :

@ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

from Your first post is missing.


Uwe,

I didn´t make any changes to it, so I saw no need to post it again. :wink:

All is included in Antonio´s last version.
kind regards
Stefan
StefanHaupt
 
Posts: 824
Joined: Thu Oct 13, 2005 7:39 am
Location: Germany

Re: FiveDBU for 32/64 bits

Postby Antonio Linares » Tue Jun 05, 2012 4:04 pm

Enhanced version for indexes and relation review:

Code: Select all  Expand view  RUN

#include "FiveWin.ch"
#include "xbrowse.ch"
#include "dbinfo.ch"

#ifdef __XHARBOUR__
   #define hb_CurDrive() CurDrive()
#endif  

#define GENBLOCK(x)  &( "{ || " + x + " }" )

REQUEST DBFCDX

static oWndMain, oMruDBFs, aSearches := {}

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

function Main( cDbfName )

   local oBar, oBmpTiled
   
   SET DATE FORMAT TO "DD/MM/YYYY"

   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"

   DEFINE WINDOW oWndMain TITLE "FiveDBU" MDI MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION New()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION Open()

   DEFINE BUTTON OF oBar PROMPT "Copy" RESOURCE "copy" ACTION Copy() GROUP

   DEFINE BUTTON OF oBar PROMPT "Paste" RESOURCE "paste" ACTION Paste()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION oWndMain:PrevWindow() GROUP WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION oWndMain:NextWindow() WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   DEFINE MSGBAR PROMPT "FiveDBU 32/64 bits, (c) FiveTech Software 2012" ;
      OF oWndMain 2010 KEYBOARD DATE

   if ! Empty( cDbfName )
      Open( cDbfName )
   endif  

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )
   
   oBmpTiled:End()      

return nil

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

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Files"
      MENU
         MENUITEM "New..."
         MENUITEM "Open..." ACTION Open()
         SEPARATOR
         MENUITEM "Recent files"
         MENU
            MRU oMruDBFs ;
               FILENAME ".\FiveDBU.ini" ;    // .INI to manipulate. '\.' for local
               SECTION  "Recent DBF files" ; // The name of the INI section
               ACTION   Open( cMruItem ) ;   // cMruItem is automatically provided
               MESSAGE  "Open this file" ;   // The message for all of them
               SIZE     10
         ENDMENU      

         SEPARATOR
         MENUITEM "Exit" ACTION oWndMain:End()
      ENDMENU
     
      // oMenu:AddEdit()
      oMenu:AddMdi()
      oMenu:AddHelp( "FiveDBU", "(c) FiveTech Software 2012" )
   ENDMENU
   
return oMenu      

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

function Open( cFileName )

   local oWnd, oBar, oBrw, oMsgBar, oMsgDeleted, oMsgTagName
   local oPopup, cAlias, n, cClrBack, nTags
   
   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )
   
   if Empty( cFileName )
      return nil
   endif  
   
   if ! "." $ cFileName
      cFileName += ".dbf"
   endif  
   
   if ! File( cFileName )
      MsgStop( "File not found: " + cFileName )
      return nil
   endif
   
   if File( cFileNoExt( cFileName ) + ".ntx" )
      USE ( cFileName ) VIA "DBFNTX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
   else  
      USE ( cFileName ) VIA "DBFCDX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
      cAlias = Alias()
   endif        
   
   oMruDBFs:Save( cFileName )
   
   MENU oPopup POPUP
      MENUITEM "Natural order" ;
         ACTION ( ( cAlias )->( DbSetOrder( 0 ) ), oBrw:Refresh(), oBrw:SetFocus(),;
                  ( cAlias )->( Eval( oBrw:bChange ) ) )
     
      if ( nTags := ( cAlias )->( OrdTagsCount() ) ) > 0
         SEPARATOR
      endif  
     
      for n = 1 to nTags
         if ! Empty( OrdName( n ) )
            if ! Empty( OrdName( 1 ) )
               DbSetOrder( OrdName( 1 ) )
               DbGoTop()
            endif  
            MENUITEM OrdName( n ) ;
               ACTION ( ( cAlias )->( DbSetOrder( oMenuItem:cPrompt ) ),;
                        oBrw:Refresh(), ( cAlias )->( Eval( oBrw:bChange ) ), oBrw:SetFocus() )
         endif
      next    
   ENDMENU  
   
   DEFINE WINDOW oWnd TITLE "Browse " + cFileName MDICHILD

   oWnd:bCopy = { || MsgInfo( "copy" ) }

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( ( oBrw:cAlias )->( DbAppend() ), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( oBrw:cAlias )->( Edit() )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION ( obrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )

   DEFINE BUTTON OF oBar PROMPT "Search" RESOURCE "search" ;
      GROUP ACTION ( cAlias )->( Search( oBrw ) )

   DEFINE BUTTON OF oBar PROMPT "Index" RESOURCE "index" ;
      MENU oPopup ACTION ( cAlias )->( Indexes() )

   DEFINE BUTTON OF oBar PROMPT "Relations" RESOURCE "relation" ;
      ACTION ( cAlias )->( Relations() )

   DEFINE BUTTON OF oBar PROMPT "Top" RESOURCE "top" ;
      ACTION ( oBrw:GoTop(), oBrw:SetFocus() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Bottom" RESOURCE "bottom" ;
      ACTION ( oBrw:GoBottom(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Struct" RESOURCE "struct" ;
      ACTION ( oBrw:cAlias )->( Struct() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report()

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd LINES ;
      ON CHANGE ( oMsgBar:cMsgDef := "Alias: " + Alias() + ;
                                     " RecNo: " + AllTrim( Str( RecNo() ) ) + "/" + ;
                                     AllTrim( Str( RecCount() ) ),;
                                     oMsgBar:Refresh(),;
                                     oMsgTagName:SetText( "Ordered by: " + If( ! Empty( OrdName() ), OrdName(), "Natural order" ) ),;
                                     oMsgDeleted:SetText( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "DELETED", "NON DELETED" ) ),;
                                     oMsgDeleted:SetBitmap( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "deleted", "nondeleted" ) ) )

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 198, 255, 198 ) }, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                           RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]                                              
   oBrw:bClrSelFocus = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                              cClrBack } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   oBrw:bLDblClick = { || ( oBrw:cAlias )->( Edit() ) }                      
   
   oWnd:oClient = oBrw
   oWnd:oControl = oBrw

   DEFINE MSGBAR oMsgBar PROMPT "Alias: " + Alias() + " | RecNo: " + ;
      AllTrim( Str( RecNo() ) ) + "/" + ;
      AllTrim( Str( RecCount() ) ) ;
      OF oWnd 2010

   DEFINE MSGITEM oMsgTagName OF oMsgBar ;
          PROMPT "Ordered by: " + ;
          If( ! Empty( ( oBrw:cAlias )->( OrdName() ) ),;
              ( oBrw:cAlias )->( OrdName() ), "Natural order" ) ;
          SIZE 150

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( oBrw:cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS "nondeleted" ;
          ACTION ( oBrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
         
   ACTIVATE WINDOW oWnd ;
      VALID ( ( cAlias )->( DbCloseArea() ), oBrw:cAlias := "", .T. )
   
return nil  

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

function Copy()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Copy()
   endif  

return nil

//----------------------------------------------------------------------------//
 
function DelField( aFields, cFieldName, oGet, oBrw )

   if Len( aFields ) >= 1
      ADel( aFields, oBrw:nArrayAt, .T. )
      oBrw:SetArray( aFields )
   endif

   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()
               
return nil

//----------------------------------------------------------------------------//
       
function DelRecord( oBrw, oMsgDeleted )

   if ! Deleted()
      if ! MsgYesNo( "Want to delete this record ?" )
         return nil
      endif  
      DbRLock()  
      DbDelete()  
      DbUnlock()  
      oMsgDeleted:SetText( "DELETED" )
      oMsgDeleted:SetBitmap( "deleted" )
   else
      DbRLock()  
      DbRecall()  
      DbUnlock()        
      oMsgDeleted:SetText( "NON DELETED" )
      oMsgDeleted:SetBitmap( "nondeleted" )
      MsgInfo( "UnDeleted record" )
   endif
   
   Eval( oBrw:bChange )
   oBrw:Refresh()

return nil  

//----------------------------------------------------------------------------//
   
function Edit()

   local oWnd, aRecord := ( Alias() )->( LoadRecord() ), oBar, oBrw, oMsgBar
   local cAlias := Alias(), oBtnSave, nRecNo := ( Alias() )->( RecNo() )
   local oMsgDeleted
   
   DEFINE WINDOW oWnd TITLE "Edit " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" RESOURCE "save" ;
      ACTION ( ( cAlias )->( SaveRecord( aRecord, nRecNo ) ), oBtnSave:Disable() )

   oBtnSave:Disable()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION GoPrevRecord( oBrw, aRecord, oMsgDeleted ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP

   DEFINE BUTTON OF oBar PROMPT "View" RESOURCE "view" ;
      ACTION View( oBrw:aRow[ 2 ], oWnd )
     
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRecord AUTOCOLS LINES ;
      HEADERS "FieldName", "Value" COLSIZES 150, 400 FASTEDIT ;
      ON CHANGE ( ( cAlias )->( SetEditType( oBrw, oBtnSave ) ), oBrw:DrawLine( .T. ),;
                  oMsgBar:cMsgDef := " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + ;
                                 "/" + AllTrim( Str( ( cAlias )->( RecCount() ) ) ),;
                  oMsgBar:Refresh() )                

   oBrw:nEditTypes = EDIT_GET
   oBrw:aCols[ 1 ]:nEditType = 0 // Don't allow to edit first column
   oBrw:aCols[ 2 ]:bOnChange = { || oBtnSave:Enable() }
   oBrw:aCols[ 2 ]:lWillShowABtn = .T.
   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar ;
      PROMPT " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + "/" + ;
      AllTrim( Str( ( cAlias )->( RecCount() ) ) ) OF oWnd 2010

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS If( ( cAlias )->( Deleted() ), "deleted", "nondeleted" ) ;
          ACTION ( cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
   
   ACTIVATE WINDOW oWnd
   
return nil      

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

function GoPrevRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( -1 )
   
   oBrw:SetArray( aRecord := LoadRecord() )
   oBrw:SetFocus()
   Eval( oBrw:bChange )

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( 1 )
   
   If Eof()
      DbSkip( -1 )
   else
      oBrw:SetArray( aRecord := LoadRecord() )
      oBrw:SetFocus()
      Eval( oBrw:bChange )
   endif  

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function SetEditType( oBrw, oBtnSave )

   local cType := FieldType( oBrw:nArrayAt )
   
   do case
      case cType == "M"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { | c | c := oBrw:aRow[ 2 ],;
                                               MemoEdit( @oBrw:aRow[ 2 ], FieldName( oBrw:nArrayAt ) ),;
                                               If( ! c == oBrw:aRow[ 2 ], oBtnSave:Enable(),),;
                                               oBrw:aRow[ 2 ] }
   
      case cType == "D"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { || If( ! Empty( oBrw:aRow[ 2 ] ) .and. ;
                                                 ! AllTrim( oBrw:aRow[ 2 ] ) == "/  /",;
                                             DToC( MsgDate( CtoD( oBrw:aRow[ 2 ] ) ) ),;
                                             DToC( MsgDate( Date() ) ) ) }
   
      case cType == "L"
           oBrw:aCols[ 2 ]:nEditType = EDIT_LISTBOX
           oBrw:aCols[ 2 ]:aEditListTxt   = { ".T.", ".F." }
           
      otherwise
           oBrw:aCols[ 2 ]:nEditType = EDIT_GET
   endcase
   
return nil              

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

function IndexBuilder()

   local oDlg, cExp := Space( 80 ), cTo := Space( 80 ), cTag := Space( 20 )
   local cFor := Space( 80 ), cWhile := Space( 80 ), lUnique := .F.
   local lDescend := .F., lMemory := .F., cScope := "All", nRecNo
   local oPgr, nMeter := 0, nStep := 10, lTag := .T.
   
   DEFINE DIALOG oDlg TITLE "Index builder" SIZE 530, 380

   @ 0.4, 3 SAY "Expression:" OF oDlg SIZE 40, 8

   @ 0.5, 6 GET cExp OF oDlg SIZE 200, 11 ACTION ExpBuilder( @cExp ) ;
      VALID ! Empty( cExp )
   
   @ 1.5, 6 SAY "To:" OF oDlg SIZE 40, 8

   @ 1.7, 6 GET cTo OF oDlg SIZE 200, 11

   @ 2.6, 5.5 SAY "Tag:" OF oDlg SIZE 40, 8

   @   3, 6 GET cTag OF oDlg SIZE 100, 11
   
   @ 3.7, 5.9 SAY "For:" OF oDlg SIZE 40, 8

   @ 4.3, 6 GET cFor OF oDlg SIZE 200, 11 ACTION ExpBuilder()

   @ 4.8, 5 SAY "While:" OF oDlg SIZE 40, 8

   @ 5.6, 6 GET cWhile OF oDlg SIZE 200, 11 ACTION ExpBuilder()
   
   @ 6.8, 6.9 CHECKBOX lUnique PROMPT "&Unique" OF oDlg SIZE 50, 8

   @ 6.8, 13.9 CHECKBOX lDescend PROMPT "&Descending" OF oDlg SIZE 80, 8

   @ 6.8, 23 CHECKBOX lMemory PROMPT "&Memory" OF oDlg SIZE 80, 8

   @ 6.8, 8 SAY "Scope:" OF oDlg SIZE 40, 8
   
   @ 8.2, 6 COMBOBOX cScope ITEMS { "All", "Next", "Record", "Rest" } OF oDlg

   @ 6.8, 16.1 SAY "Record:" OF oDlg SIZE 40, 8

   @ 8.8, 12.1 GET nRecNo OF oDlg SIZE 30, 11

   @ 8.5, 8 SAY "Progress:" OF oDlg SIZE 40, 8
   
   @ 9.2, 8 PROGRESS oPgr OF oDlg SIZE 200, 10
   
   @ 9.2, 13 BUTTON "C&reate" OF oDlg SIZE 45, 13 ;
      ACTION ( OrdCondSet( If( ! Empty( cFor ), cFor,),;
                           If( ! Empty( cFor ), GENBLOCK( cFor ),),;
                           If( cScope == "All", .T.,),;
                           If( ! Empty( cWhile ), GENBLOCK( cWhile ),),;
                           { || nMeter += nStep, oPgr:SetPos( nMeter ), SysRefresh() },;
                           nStep, Recno(),;
                           If( cScope == "Next", nRecNo,),;
                           If( cScope == "Record", nRecNo,),;
                           If( cScope == "Rest", .T.,),;
                           If( lDescend, .T.,),;
                           lTag,, .F., .F., .F., .T., .F., .F. ),;
               OrdCreate( OrdBagName(), If( lTag, cTag,), cExp, GENBLOCK( cExp ),;
                          If( lUnique, .T.,) ), oDlg:End() )                                      

   @ 9.2, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
   
   ACTIVATE DIALOG oDlg CENTERED

return nil

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

function Indexes()

   local oWnd, oBar, oBrw, oMsgBar
   local cAlias := Alias(), aIndexes := { Array( 6 ) }
   
   DEFINE WINDOW oWnd TITLE "Indexes of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( IndexBuilder(), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION If( MsgYesNo( "Want to delete this tag ?" ),;
                ( ( cAlias )->( OrdDestroy( oBrw:nArrayAt ) ), oBrw:Refresh() ),)

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aIndexes AUTOCOLS LINES ;
      HEADERS "Order", "TagName", "Expression", "For", "BagName", "BagExt" ;
      COLSIZES 50, 100, 400, 240, 100, 100

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   oBrw:bKeyCount = { || ( cAlias )->( OrdTagsCount() ) }
   oBrw:aCols[ 1 ]:bStrData = { || oBrw:nArrayAt }
   oBrw:aCols[ 2 ]:bStrData = { || OrdName( oBrw:nArrayAt ) }
   oBrw:aCols[ 3 ]:bStrData = { || OrdKey( oBrw:nArrayAt ) }
   oBrw:aCols[ 4 ]:bStrData = { || OrdFor( oBrw:nArrayAt ) }
   oBrw:aCols[ 5 ]:bStrData = { || OrdBagName( oBrw:nArrayAt ) }
   oBrw:aCols[ 6 ]:bStrData = { || OrdBagExt( oBrw:nArrayAt ) }

   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010
   
   ACTIVATE WINDOW oWnd

return nil

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

function ExpBuilder( cExp )

   local oDlg, oBrw, aFields := DBStruct()
   local oExp, cFunction
   
   cExp = RTrim( cExp )
   
   DEFINE DIALOG oDlg TITLE "Expression builder" SIZE 480, 450
   
   @ 0.2, 1.5 SAY "Expression:" SIZE 80, 11 OF oDlg
   
   @ 1.1, 1 GET oExp VAR cExp MEMO SIZE 221, 27
   
   @ 3, 1.5 SAY "Fields" OF oDlg SIZE 40, 10
   
   @ 4, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES SIZE 120, 120 ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 95, 30, 30, 30
     
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:bLDblClick = { || cExp += oBrw:aRow[ 1 ], oExp:Refresh() }

   @ 3, 23.1 SAY "Operators" OF oDlg SIZE 40, 10

   @ 3.1, 23 BUTTON "=" OF oDlg SIZE 15, 15 ACTION ( cExp += " = ", oExp:Refresh() )

   @ 3.1, 26.2 BUTTON "<>" OF oDlg SIZE 15, 15 ACTION ( cExp += " <> ", oExp:Refresh() )

   @ 3.1, 29.4 BUTTON "+" OF oDlg SIZE 15, 15 ACTION ( cExp += " + ", oExp:Refresh() )

   @ 3.1, 32.6 BUTTON "(" OF oDlg SIZE 15, 15 ACTION ( cExp += " ( ", oExp:Refresh() )

   @ 3.1, 35.8 BUTTON ".T." OF oDlg SIZE 15, 15 ACTION ( cExp += " .T. ", oExp:Refresh() )

   @ 4.1, 23 BUTTON "<" OF oDlg SIZE 15, 15 ACTION ( cExp += " < ", oExp:Refresh() )

   @ 4.1, 26.2 BUTTON ">" OF oDlg SIZE 15, 15 ACTION ( cExp += " > ", oExp:Refresh() )

   @ 4.1, 29.4 BUTTON "-" OF oDlg SIZE 15, 15 ACTION ( cExp += " - ", oExp:Refresh() )

   @ 4.1, 32.6 BUTTON ")" OF oDlg SIZE 15, 15 ACTION ( cExp += " )", oExp:Refresh() )

   @ 4.1, 35.8 BUTTON ".F." OF oDlg SIZE 15, 15 ACTION ( cExp += " .F. ", oExp:Refresh() )

   @ 5.1, 23 BUTTON "<=" OF oDlg SIZE 15, 15 ACTION ( cExp += " <= ", oExp:Refresh() )

   @ 5.1, 26.2 BUTTON ">=" OF oDlg SIZE 15, 15 ACTION ( cExp += " >= ", oExp:Refresh() )

   @ 5.1, 29.4 BUTTON "*" OF oDlg SIZE 15, 15 ACTION ( cExp += " * ", oExp:Refresh() )

   @ 5.1, 32.6 BUTTON "/" OF oDlg SIZE 15, 15 ACTION ( cExp += " / ", oExp:Refresh() )

   @ 5.1, 35.8 BUTTON "$" OF oDlg SIZE 15, 15 ACTION ( cExp += " $ ", oExp:Refresh() )

   @ 6.1, 23 BUTTON '"' OF oDlg SIZE 15, 15 ACTION ( cExp += '"', oExp:Refresh() )

   @ 6.1, 26.2 BUTTON "!" OF oDlg SIZE 15, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 6.1, 29.4 BUTTON "SP" OF oDlg SIZE 15, 15 ACTION ( cExp += " ", oExp:Refresh() )

   @ 6.1, 32.6 BUTTON "," OF oDlg SIZE 15, 15 ACTION ( cExp += ", ", oExp:Refresh() )

   @ 6.1, 35.8 BUTTON ":" OF oDlg SIZE 15, 15 ACTION ( cExp += " : ", oExp:Refresh() )

   @ 7.1, 23 BUTTON "AND" OF oDlg SIZE 27, 15 ACTION ( cExp += " .and. ", oExp:Refresh() )

   @ 7.1, 28.4 BUTTON "OR" OF oDlg SIZE 27, 15 ACTION ( cExp += " .or. ", oExp:Refresh() )

   @ 7.1, 33.7 BUTTON "NOT" OF oDlg SIZE 27, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 10.3, 23.2 SAY "Functions" OF oDlg SIZE 84, 11

   @ 11.9, 17.3 COMBOBOX cFunction ITEMS { "AllTrim()", "Left()", "Right()", "SubStr()" } ;
      OF oDlg SIZE 92, 80 ON CHANGE ( cExp += Left( cFunction, Len( cFunction ) - 1 ) + " ",;
                                      oExp:Refresh() )

   @ 11, 13 BUTTON "&Ok" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 11, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
           
   ACTIVATE DIALOG oDlg CENTERED

return cExp

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

function LoadRecord()

   local aRecord := {}, n
   
   for n = 1 to FCount()
      AAdd( aRecord, { FieldName( n ), FieldGet( n ) } )
   next
   
return aRecord      
   
//----------------------------------------------------------------------------//

function Search( oBrw )

   local oDlg, oCbx, cSearch := Space( 50 )
   local nRecNo := RecNo(), lInc := .T.
   
   DEFINE DIALOG oDlg TITLE "Search: " + Alias() SIZE 400, 200
   
   @ 0.5, 1.5 SAY "Ordered by: " + OrdName() OF oDlg
   
   @ 1.2, 1.5 SAY "Key: " + OrdKey() OF oDlg
   
   @ 2.4, 1.2 COMBOBOX oCbx VAR cSearch ITEMS aSearches OF oDlg SIZE 180, 150 ;
     STYLE CBS_DROPDOWN
   
   oCbx:oGet:bChange = { || DbSeek( AllTrim( oCbx:GetText() ), lInc ), oBrw:Refresh() }
   
   @ 3.7, 1.5 CHECKBOX lInc PROMPT "&Incremental" OF oDlg SIZE 80, 10
   
   @ 4, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! DbSeek( AllTrim( cSearch ), lInc ), DbGoTo( nRecNo ),),;
               AAdd( aSearches, AllTrim( cSearch ) ), oDlg:End() )

   @ 4, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil  

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

function Relations()

   local oWnd, oBar, oBrw, aRelations := { Array( 5 ) }, n
   local nTarget
   
   DEFINE WINDOW oWnd TITLE "Relations of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION MsgInfo( "Add" )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION MsgInfo( "del" )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRelations AUTOCOLS LINES ;
      HEADERS "Rel.", "Expression", "Child Alias", "Additive", "Scoped" ;
      COLSIZES 40, 150, 400, 100, 100

   oBrw:bKeyCount = { || 8 }
   oBrw:aCols[ 1 ]:bStrData = { || oBrw:nArrayAt }
   oBrw:aCols[ 2 ]:bStrData = { || DbRelation( oBrw:nArrayAt ) }
   oBrw:aCols[ 3 ]:bStrData = { || If( DbRSelect( oBrw:nArrayAt ) != 0,;
                                       Alias( DbRSelect( oBrw:nArrayAt ) ), "" ) }
   oBrw:aCols[ 4 ]:bStrData = { || ".F." }
   oBrw:aCols[ 5 ]:bStrData = { || ".F." }

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010

   ACTIVATE WINDOW oWnd

return nil

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

function SaveRecord( aRecord, nRecNo )

   local n

   ( Alias() )->( DbGoTo( nRecNo ) )
   
   if ( Alias() )->( DbRLock( nRecNo ) )
      for n = 1 to Len( aRecord )
         ( Alias() )->( FieldPut( n, aRecord[ n ][ 2 ] ) )
      next
      ( Alias() )->( DbUnLock() )
      MsgInfo( "Record updated" )
   else
      MsgAlert( "Record in use, please try it again" )
   endif        

return nil      

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

function Struct()

   local oDlg, oBrw, aFields := DbStruct()
   
   DEFINE DIALOG oDlg TITLE Alias() + " fields" SIZE 400, 400

   @ 0, 0 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 150, 50, 80, 80

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
     
   oDlg:oClient = oBrw
   
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( BuildStructBar( oDlg, oBrw ), oDlg:Resize(), oBrw:SetFocus() )
   
return nil  

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

function BuildStructBar( oDlg, oBrw )

   local oBar

   DEFINE BUTTONBAR oBar OF oDlg 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Code" RESOURCE "code" ;
      ACTION ( TxtStruct(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oDlg:End() GROUP

return nil

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

function TxtStruct()

   local cCode := "local aFields := { ", n
   
   for n = 1 to FCount()
      if n > 1
         cCode += Space( 27 )
      endif  
      cCode += '{ "' + FieldName( n ) + '", "' + ;
               FieldType( n ) + '", ' + ;
               AllTrim( Str( FieldLen( n ) ) ) + ", " + ;
               AllTrim( Str( FieldDec( n ) ) ) + " },;" + CRLF
   next
   
   cCode = SubStr( cCode, 1, Len( cCode ) - 4 ) + " }"
   
   MemoEdit( cCode, "Code" )

return nil

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

function View( cFileName, oWnd )

   local cExt := Lower( cFileExt( cFileName ) )
   
   do case
      case cExt == "bmp"
           WinExec( "mspaint" + " " + cFileName )
           
      case cExt == "txt"
           WinExec( "notepad" + " " + cFileName )    
           
      otherwise
           ShellExecute( oWnd:hWnd, "Open", cFileName )
   endcase
   
return nil                

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

function New()

   local oDlg, oGet, oBrw, oBtn
   local cFieldName := Space( 10 ), cType := "Character", nLen := 10, nDec := 0
   local aFields := { Array( 4 ) }, cDbfName := Space( 8 ), aTemp
   local oLen, oDec, aType := { "Character", "Number", "Date", "Logical", "Memo" }
   local bChange := {|| If( cType == "Character", (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        If( cType == "Number",    (nLen := 10, nDec := 0, oDec:Enable()  ),),;
                        If( cType == "Date",      (nLen := 8,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Logical",   (nLen := 1,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Memo",      (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        oDlg:Update() }
   local bEdit := {|| IF ( !Empty (aFields[1,1]) ,;
                      (oBtn:Enable (),;
                       cFieldName := aFields[oBrw:nArrayAt,1] ,;
                       cType := aFields[oBrw:nArrayAt,2] ,;
                       cType := aType[ aScan(aType, {|x| Left(x,1) = cType} )],;
                       Eval (bChange) ,;
                       nLen := aFields[oBrw:nArrayAt,3] ,;
                       nDec := aFields[oBrw:nArrayAt,4] ,;
                       oGet:SetPos( 0 ),;
                       oGet:SetFocus(),;
                       oDlg:Update() ) ,) ;
                     }
   local bSave := {|| oBtn:Disable (),;
                      aFields[oBrw:nArrayAt,1] := cFieldname,;
                      aFields[oBrw:nArrayAt,2] := Left (cType,1),;
                      aFields[oBrw:nArrayAt,3] := nLen,;
                      aFields[oBrw:nArrayAt,4] := nDec,;
                      oBrw:SetArray (aFields),;
                      cFieldName := Space( 10 ),;
                      Eval (bChange) ,;
                      oDlg:Update() ,;
                      oGet:SetPos( 0 ),;
                      oGet:SetFocus(),;
                      oBrw:GoBottom();
                      }

   DEFINE DIALOG oDlg TITLE "DBF builder" SIZE 415, 400

   @ 0.5,  2 SAY "Field Name" OF oDlg SIZE 40, 8
   @ 0.5, 10 SAY "Type" OF oDlg SIZE 40, 8
   @ 0.5, 17 SAY "Len" OF oDlg SIZE 40, 8
   @ 0.5, 22 SAY "Dec" OF oDlg SIZE 20, 8

   @ 1.4, 1 GET oGet VAR cFieldName PICTURE "!!!!!!!!!!" OF oDlg SIZE 41, 11 UPDATE

   @ 1.3, 6.5 COMBOBOX cType ITEMS aType ;
      OF oDlg ON CHANGE Eval (bChange) UPDATE

   @ 1.4, 11.9 GET oLen VAR nLen PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 1.4, 15.4 GET oDec VAR nDec PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 0.9, 26 BUTTON "&Add" OF oDlg SIZE 45, 13 ;
      ACTION AddField( @aFields, @cFieldName, @cType, @nLen, @nDec, oGet, oBrw )

   @ 2.4, 26 BUTTON oBtn PROMPT "&Edit" OF oDlg SIZE 45, 13 ;
     ACTION Eval (bSave)

   @ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
     ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

   @ 4.4, 26 BUTTON "Move &Up" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt > 1,;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt - 1 ],;
                   aFields[ oBrw:nArrayAt - 1 ] := aTemp,;
                   oBrw:GoUp() ),)

   @ 5.4, 26 BUTTON "Move D&own" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt < Len( aFields ),;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt + 1 ],;
                   aFields[ oBrw:nArrayAt + 1 ] := aTemp,;
                   oBrw:GoDown() ),)

   @ 6.4, 26 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 2.2, 2 SAY "Fields" OF oDlg SIZE 40, 8

   @ 3.2, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 90, 55, 40, 40 ;
      SIZE 140, 130 OF oDlg ;
      ON DBLCLICK Eval (bEdit)

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   @ 12.1, 2 SAY "DBF Name:" OF oDlg SIZE 30, 8

   @ 14, 6 GET cDbfName PICTURE "!!!!!!!!!!!!" OF oDlg SIZE 100, 11

   @ 10, 26 BUTTON "&Create" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! Empty( cDbfName ) .and. Len( aFields ) > 0,;
          DbCreate( AllTrim( cDbfName ), aFields ),), oDlg:End(),;
          Open( hb_CurDrive() + ":\" + CurDir() + "\" + AllTrim( cDbfName ) ) )

   ACTIVATE DIALOG oDlg CENTERED ON INIT (Eval (bChange), oBtn:Disable() ) ;
                                 VALID !GETKEYSTATE( VK_ESCAPE )

return nil

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

function AddField( aFields, cFieldName, cType, nLen, nDec, oGet, oBrw )

   if Empty( cFieldName )
      oGet:SetPos( 0 )
      return nil
   endif

   if Len( aFields ) == 1 .and. Empty( aFields[ 1 ][ 1 ] )
      aFields = { { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } }
   else
      AAdd( aFields, { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } )
   endif

   oBrw:SetArray( aFields )
   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()

return nil
       
//----------------------------------------------------------------------------//

function OrdTagsCount()

   local n, nCount := 0
   
   for n = 1 to 100
      if ! Empty( OrdKey( n ) )
         nCount++
      endif  
   next
   
return nCount  
   
//----------------------------------------------------------------------------//  

function Paste()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Paste()
   endif  

return nil

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

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapirdd.h>

HB_FUNC( ORDCONDGET )
{
   AREAP pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer();
   
   if( pArea )
   {
      LPDBORDERCONDINFO lpdbOrdCondInfo = pArea->lpdbOrdCondInfo;
     
      if( lpdbOrdCondInfo && lpdbOrdCondInfo->abWhile )
         hb_retc( lpdbOrdCondInfo->abWhile );
      else
         hb_retc( "
" );  
   }
   else
      hb_retc( "
" );    
}

#pragma ENDDUMP

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

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

Re: FiveDBU for 32/64 bits

Postby Antonio Linares » Tue Jun 05, 2012 4:32 pm

Image

Code: Select all  Expand view  RUN

#include "FiveWin.ch"
#include "xbrowse.ch"
#include "dbinfo.ch"

#ifdef __XHARBOUR__
   #define hb_CurDrive() CurDrive()
#endif  

#define GENBLOCK(x)  &( "{ || " + x + " }" )

REQUEST DBFCDX

static oWndMain, oMruDBFs, aSearches := {}

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

function Main( cDbfName )

   local oBar, oBmpTiled
   
   SET DATE FORMAT TO "DD/MM/YYYY"

   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"

   DEFINE WINDOW oWndMain TITLE "FiveDBU" MDI MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION New()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION Open()

   DEFINE BUTTON OF oBar PROMPT "Copy" RESOURCE "copy" ACTION Copy() GROUP

   DEFINE BUTTON OF oBar PROMPT "Paste" RESOURCE "paste" ACTION Paste()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION oWndMain:PrevWindow() GROUP WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION oWndMain:NextWindow() WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   DEFINE MSGBAR PROMPT "FiveDBU 32/64 bits, (c) FiveTech Software 2012" ;
      OF oWndMain 2010 KEYBOARD DATE

   if ! Empty( cDbfName )
      Open( cDbfName )
   endif  

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )
   
   oBmpTiled:End()      

return nil

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

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Files"
      MENU
         MENUITEM "New..."
         MENUITEM "Open..." ACTION Open()
         SEPARATOR
         MENUITEM "Recent files"
         MENU
            MRU oMruDBFs ;
               FILENAME ".\FiveDBU.ini" ;    // .INI to manipulate. '\.' for local
               SECTION  "Recent DBF files" ; // The name of the INI section
               ACTION   Open( cMruItem ) ;   // cMruItem is automatically provided
               MESSAGE  "Open this file" ;   // The message for all of them
               SIZE     10
         ENDMENU      

         SEPARATOR
         MENUITEM "Exit" ACTION oWndMain:End()
      ENDMENU
     
      // oMenu:AddEdit()
      oMenu:AddMdi()
      oMenu:AddHelp( "FiveDBU", "(c) FiveTech Software 2012" )
   ENDMENU
   
return oMenu      

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

function Open( cFileName )

   local oWnd, oBar, oBrw, oMsgBar, oMsgRecNo, oMsgDeleted, oMsgTagName
   local oPopup, cAlias, n, cClrBack, nTags
   
   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )
   
   if Empty( cFileName )
      return nil
   endif  
   
   if ! "." $ cFileName
      cFileName += ".dbf"
   endif  
   
   if ! File( cFileName )
      MsgStop( "File not found: " + cFileName )
      return nil
   endif
   
   if File( cFileNoExt( cFileName ) + ".ntx" )
      USE ( cFileName ) VIA "DBFNTX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
   else  
      USE ( cFileName ) VIA "DBFCDX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
      cAlias = Alias()
   endif        
   
   oMruDBFs:Save( cFileName )
   
   MENU oPopup POPUP
      MENUITEM "Natural order" ;
         ACTION ( ( cAlias )->( DbSetOrder( 0 ) ), oBrw:Refresh(), oBrw:SetFocus(),;
                  ( cAlias )->( Eval( oBrw:bChange ) ) )
     
      if ( nTags := ( cAlias )->( OrdTagsCount() ) ) > 0
         SEPARATOR
      endif  
     
      for n = 1 to nTags
         if ! Empty( OrdName( n ) )
            if ! Empty( OrdName( 1 ) )
               DbSetOrder( OrdName( 1 ) )
               DbGoTop()
            endif  
            MENUITEM OrdName( n ) ;
               ACTION ( ( cAlias )->( DbSetOrder( oMenuItem:cPrompt ) ),;
                        oBrw:Refresh(), ( cAlias )->( Eval( oBrw:bChange ) ), oBrw:SetFocus() )
         endif
      next    
   ENDMENU  
   
   DEFINE WINDOW oWnd TITLE "Browse " + cAlias MDICHILD

   oWnd:bCopy = { || MsgInfo( "copy" ) }

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( ( oBrw:cAlias )->( DbAppend() ), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( oBrw:cAlias )->( Edit() )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION ( obrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )

   DEFINE BUTTON OF oBar PROMPT "Search" RESOURCE "search" ;
      GROUP ACTION ( cAlias )->( Search( oBrw ) )

   DEFINE BUTTON OF oBar PROMPT "Index" RESOURCE "index" ;
      MENU oPopup ACTION ( cAlias )->( Indexes() )

   DEFINE BUTTON OF oBar PROMPT "Relations" RESOURCE "relation" ;
      ACTION ( cAlias )->( Relations() )

   DEFINE BUTTON OF oBar PROMPT "Top" RESOURCE "top" ;
      ACTION ( oBrw:GoTop(), oBrw:SetFocus() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Bottom" RESOURCE "bottom" ;
      ACTION ( oBrw:GoBottom(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Struct" RESOURCE "struct" ;
      ACTION ( oBrw:cAlias )->( Struct() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report()

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd LINES ;
      ON CHANGE ( oMsgBar:cMsgDef := "FileName: " + cFileName,;
                                     oMsgBar:Refresh(),;
                                     oMsgRecNo:SetText( "RecNo: " + ;
                                                        AllTrim( Str( RecNo() ) ) + " / " + ;
                                                        AllTrim( Str( RecCount() ) ) ),;
                                     oMsgTagName:SetText( "Ordered by: " + If( ! Empty( OrdName() ), OrdName(), "Natural order" ) ),;
                                     oMsgDeleted:SetText( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "DELETED", "NON DELETED" ) ),;
                                     oMsgDeleted:SetBitmap( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "deleted", "nondeleted" ) ) )

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 198, 255, 198 ) }, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                           RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]                                              
   oBrw:bClrSelFocus = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                              cClrBack } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   oBrw:bLDblClick = { || ( oBrw:cAlias )->( Edit() ) }                      
   
   oWnd:oClient = oBrw
   oWnd:oControl = oBrw

   DEFINE MSGBAR oMsgBar PROMPT "FileName: " + cFileName OF oWnd 2010

   DEFINE MSGITEM oMsgRecNo OF oMsgBar ;
          PROMPT "RecNo: " + ;
          AllTrim( Str( RecNo() ) ) + " / " + ;
          AllTrim( Str( RecCount() ) ) ;
          SIZE 150

   DEFINE MSGITEM oMsgTagName OF oMsgBar ;
          PROMPT "Ordered by: " + ;
          If( ! Empty( ( oBrw:cAlias )->( OrdName() ) ),;
              ( oBrw:cAlias )->( OrdName() ), "Natural order" ) ;
          SIZE 150

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( oBrw:cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS "nondeleted" ;
          ACTION ( oBrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
         
   ACTIVATE WINDOW oWnd ;
      VALID ( ( cAlias )->( DbCloseArea() ), oBrw:cAlias := "", .T. )
   
return nil  

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

function Copy()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Copy()
   endif  

return nil

//----------------------------------------------------------------------------//
 
function DelField( aFields, cFieldName, oGet, oBrw )

   if Len( aFields ) >= 1
      ADel( aFields, oBrw:nArrayAt, .T. )
      oBrw:SetArray( aFields )
   endif

   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()
               
return nil

//----------------------------------------------------------------------------//
       
function DelRecord( oBrw, oMsgDeleted )

   if ! Deleted()
      if ! MsgYesNo( "Want to delete this record ?" )
         return nil
      endif  
      DbRLock()  
      DbDelete()  
      DbUnlock()  
      oMsgDeleted:SetText( "DELETED" )
      oMsgDeleted:SetBitmap( "deleted" )
   else
      DbRLock()  
      DbRecall()  
      DbUnlock()        
      oMsgDeleted:SetText( "NON DELETED" )
      oMsgDeleted:SetBitmap( "nondeleted" )
      MsgInfo( "UnDeleted record" )
   endif
   
   Eval( oBrw:bChange )
   oBrw:Refresh()

return nil  

//----------------------------------------------------------------------------//
   
function Edit()

   local oWnd, aRecord := ( Alias() )->( LoadRecord() ), oBar, oBrw, oMsgBar
   local cAlias := Alias(), oBtnSave, nRecNo := ( Alias() )->( RecNo() )
   local oMsgDeleted
   
   DEFINE WINDOW oWnd TITLE "Edit " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" RESOURCE "save" ;
      ACTION ( ( cAlias )->( SaveRecord( aRecord, nRecNo ) ), oBtnSave:Disable() )

   oBtnSave:Disable()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION GoPrevRecord( oBrw, aRecord, oMsgDeleted ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP

   DEFINE BUTTON OF oBar PROMPT "View" RESOURCE "view" ;
      ACTION View( oBrw:aRow[ 2 ], oWnd )
     
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRecord AUTOCOLS LINES ;
      HEADERS "FieldName", "Value" COLSIZES 150, 400 FASTEDIT ;
      ON CHANGE ( ( cAlias )->( SetEditType( oBrw, oBtnSave ) ), oBrw:DrawLine( .T. ),;
                  oMsgBar:cMsgDef := " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + ;
                                 "/" + AllTrim( Str( ( cAlias )->( RecCount() ) ) ),;
                  oMsgBar:Refresh() )                

   oBrw:nEditTypes = EDIT_GET
   oBrw:aCols[ 1 ]:nEditType = 0 // Don't allow to edit first column
   oBrw:aCols[ 2 ]:bOnChange = { || oBtnSave:Enable() }
   oBrw:aCols[ 2 ]:lWillShowABtn = .T.
   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar ;
      PROMPT " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + "/" + ;
      AllTrim( Str( ( cAlias )->( RecCount() ) ) ) OF oWnd 2010

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS If( ( cAlias )->( Deleted() ), "deleted", "nondeleted" ) ;
          ACTION ( cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
   
   ACTIVATE WINDOW oWnd
   
return nil      

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

function GoPrevRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( -1 )
   
   oBrw:SetArray( aRecord := LoadRecord() )
   oBrw:SetFocus()
   Eval( oBrw:bChange )

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( 1 )
   
   If Eof()
      DbSkip( -1 )
   else
      oBrw:SetArray( aRecord := LoadRecord() )
      oBrw:SetFocus()
      Eval( oBrw:bChange )
   endif  

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function SetEditType( oBrw, oBtnSave )

   local cType := FieldType( oBrw:nArrayAt )
   
   do case
      case cType == "M"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { | c | c := oBrw:aRow[ 2 ],;
                                               MemoEdit( @oBrw:aRow[ 2 ], FieldName( oBrw:nArrayAt ) ),;
                                               If( ! c == oBrw:aRow[ 2 ], oBtnSave:Enable(),),;
                                               oBrw:aRow[ 2 ] }
   
      case cType == "D"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { || If( ! Empty( oBrw:aRow[ 2 ] ) .and. ;
                                                 ! AllTrim( oBrw:aRow[ 2 ] ) == "/  /",;
                                             DToC( MsgDate( CtoD( oBrw:aRow[ 2 ] ) ) ),;
                                             DToC( MsgDate( Date() ) ) ) }
   
      case cType == "L"
           oBrw:aCols[ 2 ]:nEditType = EDIT_LISTBOX
           oBrw:aCols[ 2 ]:aEditListTxt   = { ".T.", ".F." }
           
      otherwise
           oBrw:aCols[ 2 ]:nEditType = EDIT_GET
   endcase
   
return nil              

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

function IndexBuilder()

   local oDlg, cExp := Space( 80 ), cTo := Space( 80 ), cTag := Space( 20 )
   local cFor := Space( 80 ), cWhile := Space( 80 ), lUnique := .F.
   local lDescend := .F., lMemory := .F., cScope := "All", nRecNo
   local oPgr, nMeter := 0, nStep := 10, lTag := .T.
   
   DEFINE DIALOG oDlg TITLE "Index builder" SIZE 530, 380

   @ 0.4, 3 SAY "Expression:" OF oDlg SIZE 40, 8

   @ 0.5, 6 GET cExp OF oDlg SIZE 200, 11 ACTION ExpBuilder( @cExp ) ;
      VALID ! Empty( cExp )
   
   @ 1.5, 6 SAY "To:" OF oDlg SIZE 40, 8

   @ 1.7, 6 GET cTo OF oDlg SIZE 200, 11

   @ 2.6, 5.5 SAY "Tag:" OF oDlg SIZE 40, 8

   @   3, 6 GET cTag OF oDlg SIZE 100, 11
   
   @ 3.7, 5.9 SAY "For:" OF oDlg SIZE 40, 8

   @ 4.3, 6 GET cFor OF oDlg SIZE 200, 11 ACTION ExpBuilder()

   @ 4.8, 5 SAY "While:" OF oDlg SIZE 40, 8

   @ 5.6, 6 GET cWhile OF oDlg SIZE 200, 11 ACTION ExpBuilder()
   
   @ 6.8, 6.9 CHECKBOX lUnique PROMPT "&Unique" OF oDlg SIZE 50, 8

   @ 6.8, 13.9 CHECKBOX lDescend PROMPT "&Descending" OF oDlg SIZE 80, 8

   @ 6.8, 23 CHECKBOX lMemory PROMPT "&Memory" OF oDlg SIZE 80, 8

   @ 6.8, 8 SAY "Scope:" OF oDlg SIZE 40, 8
   
   @ 8.2, 6 COMBOBOX cScope ITEMS { "All", "Next", "Record", "Rest" } OF oDlg

   @ 6.8, 16.1 SAY "Record:" OF oDlg SIZE 40, 8

   @ 8.8, 12.1 GET nRecNo OF oDlg SIZE 30, 11

   @ 8.5, 8 SAY "Progress:" OF oDlg SIZE 40, 8
   
   @ 9.2, 8 PROGRESS oPgr OF oDlg SIZE 200, 10
   
   @ 9.2, 13 BUTTON "C&reate" OF oDlg SIZE 45, 13 ;
      ACTION ( OrdCondSet( If( ! Empty( cFor ), cFor,),;
                           If( ! Empty( cFor ), GENBLOCK( cFor ),),;
                           If( cScope == "All", .T.,),;
                           If( ! Empty( cWhile ), GENBLOCK( cWhile ),),;
                           { || nMeter += nStep, oPgr:SetPos( nMeter ), SysRefresh() },;
                           nStep, Recno(),;
                           If( cScope == "Next", nRecNo,),;
                           If( cScope == "Record", nRecNo,),;
                           If( cScope == "Rest", .T.,),;
                           If( lDescend, .T.,),;
                           lTag,, .F., .F., .F., .T., .F., .F. ),;
               OrdCreate( OrdBagName(), If( lTag, cTag,), cExp, GENBLOCK( cExp ),;
                          If( lUnique, .T.,) ), oDlg:End() )                                      

   @ 9.2, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
   
   ACTIVATE DIALOG oDlg CENTERED

return nil

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

function Indexes()

   local oWnd, oBar, oBrw, oMsgBar
   local cAlias := Alias(), aIndexes := { Array( 6 ) }
   
   DEFINE WINDOW oWnd TITLE "Indexes of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( IndexBuilder(), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION If( MsgYesNo( "Want to delete this tag ?" ),;
                ( ( cAlias )->( OrdDestroy( oBrw:nArrayAt ) ), oBrw:Refresh() ),)

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aIndexes AUTOCOLS LINES ;
      HEADERS "Order", "TagName", "Expression", "For", "BagName", "BagExt" ;
      COLSIZES 50, 100, 400, 240, 100, 100

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   oBrw:bKeyCount = { || ( cAlias )->( OrdTagsCount() ) }
   oBrw:aCols[ 1 ]:bStrData = { || oBrw:nArrayAt }
   oBrw:aCols[ 2 ]:bStrData = { || OrdName( oBrw:nArrayAt ) }
   oBrw:aCols[ 3 ]:bStrData = { || OrdKey( oBrw:nArrayAt ) }
   oBrw:aCols[ 4 ]:bStrData = { || OrdFor( oBrw:nArrayAt ) }
   oBrw:aCols[ 5 ]:bStrData = { || OrdBagName( oBrw:nArrayAt ) }
   oBrw:aCols[ 6 ]:bStrData = { || OrdBagExt( oBrw:nArrayAt ) }

   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010
   
   ACTIVATE WINDOW oWnd

return nil

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

function ExpBuilder( cExp )

   local oDlg, oBrw, aFields := DBStruct()
   local oExp, cFunction
   
   cExp = RTrim( cExp )
   
   DEFINE DIALOG oDlg TITLE "Expression builder" SIZE 480, 450
   
   @ 0.2, 1.5 SAY "Expression:" SIZE 80, 11 OF oDlg
   
   @ 1.1, 1 GET oExp VAR cExp MEMO SIZE 221, 27
   
   @ 3, 1.5 SAY "Fields" OF oDlg SIZE 40, 10
   
   @ 4, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES SIZE 120, 120 ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 95, 30, 30, 30
     
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:bLDblClick = { || cExp += oBrw:aRow[ 1 ], oExp:Refresh() }

   @ 3, 23.1 SAY "Operators" OF oDlg SIZE 40, 10

   @ 3.1, 23 BUTTON "=" OF oDlg SIZE 15, 15 ACTION ( cExp += " = ", oExp:Refresh() )

   @ 3.1, 26.2 BUTTON "<>" OF oDlg SIZE 15, 15 ACTION ( cExp += " <> ", oExp:Refresh() )

   @ 3.1, 29.4 BUTTON "+" OF oDlg SIZE 15, 15 ACTION ( cExp += " + ", oExp:Refresh() )

   @ 3.1, 32.6 BUTTON "(" OF oDlg SIZE 15, 15 ACTION ( cExp += " ( ", oExp:Refresh() )

   @ 3.1, 35.8 BUTTON ".T." OF oDlg SIZE 15, 15 ACTION ( cExp += " .T. ", oExp:Refresh() )

   @ 4.1, 23 BUTTON "<" OF oDlg SIZE 15, 15 ACTION ( cExp += " < ", oExp:Refresh() )

   @ 4.1, 26.2 BUTTON ">" OF oDlg SIZE 15, 15 ACTION ( cExp += " > ", oExp:Refresh() )

   @ 4.1, 29.4 BUTTON "-" OF oDlg SIZE 15, 15 ACTION ( cExp += " - ", oExp:Refresh() )

   @ 4.1, 32.6 BUTTON ")" OF oDlg SIZE 15, 15 ACTION ( cExp += " )", oExp:Refresh() )

   @ 4.1, 35.8 BUTTON ".F." OF oDlg SIZE 15, 15 ACTION ( cExp += " .F. ", oExp:Refresh() )

   @ 5.1, 23 BUTTON "<=" OF oDlg SIZE 15, 15 ACTION ( cExp += " <= ", oExp:Refresh() )

   @ 5.1, 26.2 BUTTON ">=" OF oDlg SIZE 15, 15 ACTION ( cExp += " >= ", oExp:Refresh() )

   @ 5.1, 29.4 BUTTON "*" OF oDlg SIZE 15, 15 ACTION ( cExp += " * ", oExp:Refresh() )

   @ 5.1, 32.6 BUTTON "/" OF oDlg SIZE 15, 15 ACTION ( cExp += " / ", oExp:Refresh() )

   @ 5.1, 35.8 BUTTON "$" OF oDlg SIZE 15, 15 ACTION ( cExp += " $ ", oExp:Refresh() )

   @ 6.1, 23 BUTTON '"' OF oDlg SIZE 15, 15 ACTION ( cExp += '"', oExp:Refresh() )

   @ 6.1, 26.2 BUTTON "!" OF oDlg SIZE 15, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 6.1, 29.4 BUTTON "SP" OF oDlg SIZE 15, 15 ACTION ( cExp += " ", oExp:Refresh() )

   @ 6.1, 32.6 BUTTON "," OF oDlg SIZE 15, 15 ACTION ( cExp += ", ", oExp:Refresh() )

   @ 6.1, 35.8 BUTTON ":" OF oDlg SIZE 15, 15 ACTION ( cExp += " : ", oExp:Refresh() )

   @ 7.1, 23 BUTTON "AND" OF oDlg SIZE 27, 15 ACTION ( cExp += " .and. ", oExp:Refresh() )

   @ 7.1, 28.4 BUTTON "OR" OF oDlg SIZE 27, 15 ACTION ( cExp += " .or. ", oExp:Refresh() )

   @ 7.1, 33.7 BUTTON "NOT" OF oDlg SIZE 27, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 10.3, 23.2 SAY "Functions" OF oDlg SIZE 84, 11

   @ 11.9, 17.3 COMBOBOX cFunction ITEMS { "AllTrim()", "Left()", "Right()", "SubStr()" } ;
      OF oDlg SIZE 92, 80 ON CHANGE ( cExp += Left( cFunction, Len( cFunction ) - 1 ) + " ",;
                                      oExp:Refresh() )

   @ 11, 13 BUTTON "&Ok" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 11, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
           
   ACTIVATE DIALOG oDlg CENTERED

return cExp

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

function LoadRecord()

   local aRecord := {}, n
   
   for n = 1 to FCount()
      AAdd( aRecord, { FieldName( n ), FieldGet( n ) } )
   next
   
return aRecord      
   
//----------------------------------------------------------------------------//

function Search( oBrw )

   local oDlg, oCbx, cSearch := Space( 50 )
   local nRecNo := RecNo(), lInc := .T.
   
   DEFINE DIALOG oDlg TITLE "Search: " + Alias() SIZE 400, 200
   
   @ 0.5, 1.5 SAY "Ordered by: " + OrdName() OF oDlg
   
   @ 1.2, 1.5 SAY "Key: " + OrdKey() OF oDlg
   
   @ 2.4, 1.2 COMBOBOX oCbx VAR cSearch ITEMS aSearches OF oDlg SIZE 180, 150 ;
     STYLE CBS_DROPDOWN
   
   oCbx:oGet:bChange = { || DbSeek( AllTrim( oCbx:GetText() ), lInc ), oBrw:Refresh() }
   
   @ 3.7, 1.5 CHECKBOX lInc PROMPT "&Incremental" OF oDlg SIZE 80, 10
   
   @ 4, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! DbSeek( AllTrim( cSearch ), lInc ), DbGoTo( nRecNo ),),;
               AAdd( aSearches, AllTrim( cSearch ) ), oDlg:End() )

   @ 4, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil  

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

function Relations()

   local oWnd, oBar, oBrw, aRelations := { Array( 5 ) }, n
   local nTarget
   
   DEFINE WINDOW oWnd TITLE "Relations of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION MsgInfo( "Add" )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION MsgInfo( "del" )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRelations AUTOCOLS LINES ;
      HEADERS "Rel.", "Expression", "Child Alias", "Additive", "Scoped" ;
      COLSIZES 40, 150, 400, 100, 100

   oBrw:bKeyCount = { || 8 }
   oBrw:aCols[ 1 ]:bStrData = { || oBrw:nArrayAt }
   oBrw:aCols[ 2 ]:bStrData = { || DbRelation( oBrw:nArrayAt ) }
   oBrw:aCols[ 3 ]:bStrData = { || If( DbRSelect( oBrw:nArrayAt ) != 0,;
                                       Alias( DbRSelect( oBrw:nArrayAt ) ), "" ) }
   oBrw:aCols[ 4 ]:bStrData = { || ".F." }
   oBrw:aCols[ 5 ]:bStrData = { || ".F." }

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010

   ACTIVATE WINDOW oWnd

return nil

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

function SaveRecord( aRecord, nRecNo )

   local n

   ( Alias() )->( DbGoTo( nRecNo ) )
   
   if ( Alias() )->( DbRLock( nRecNo ) )
      for n = 1 to Len( aRecord )
         ( Alias() )->( FieldPut( n, aRecord[ n ][ 2 ] ) )
      next
      ( Alias() )->( DbUnLock() )
      MsgInfo( "Record updated" )
   else
      MsgAlert( "Record in use, please try it again" )
   endif        

return nil      

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

function Struct()

   local oDlg, oBrw, aFields := DbStruct()
   
   DEFINE DIALOG oDlg TITLE Alias() + " fields" SIZE 400, 400

   @ 0, 0 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 150, 50, 80, 80

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
     
   oDlg:oClient = oBrw
   
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( BuildStructBar( oDlg, oBrw ), oDlg:Resize(), oBrw:SetFocus() )
   
return nil  

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

function BuildStructBar( oDlg, oBrw )

   local oBar

   DEFINE BUTTONBAR oBar OF oDlg 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Code" RESOURCE "code" ;
      ACTION ( TxtStruct(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oDlg:End() GROUP

return nil

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

function TxtStruct()

   local cCode := "local aFields := { ", n
   
   for n = 1 to FCount()
      if n > 1
         cCode += Space( 27 )
      endif  
      cCode += '{ "' + FieldName( n ) + '", "' + ;
               FieldType( n ) + '", ' + ;
               AllTrim( Str( FieldLen( n ) ) ) + ", " + ;
               AllTrim( Str( FieldDec( n ) ) ) + " },;" + CRLF
   next
   
   cCode = SubStr( cCode, 1, Len( cCode ) - 4 ) + " }"
   
   MemoEdit( cCode, "Code" )

return nil

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

function View( cFileName, oWnd )

   local cExt := Lower( cFileExt( cFileName ) )
   
   do case
      case cExt == "bmp"
           WinExec( "mspaint" + " " + cFileName )
           
      case cExt == "txt"
           WinExec( "notepad" + " " + cFileName )    
           
      otherwise
           ShellExecute( oWnd:hWnd, "Open", cFileName )
   endcase
   
return nil                

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

function New()

   local oDlg, oGet, oBrw, oBtn
   local cFieldName := Space( 10 ), cType := "Character", nLen := 10, nDec := 0
   local aFields := { Array( 4 ) }, cDbfName := Space( 8 ), aTemp
   local oLen, oDec, aType := { "Character", "Number", "Date", "Logical", "Memo" }
   local bChange := {|| If( cType == "Character", (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        If( cType == "Number",    (nLen := 10, nDec := 0, oDec:Enable()  ),),;
                        If( cType == "Date",      (nLen := 8,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Logical",   (nLen := 1,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Memo",      (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        oDlg:Update() }
   local bEdit := {|| IF ( !Empty (aFields[1,1]) ,;
                      (oBtn:Enable (),;
                       cFieldName := aFields[oBrw:nArrayAt,1] ,;
                       cType := aFields[oBrw:nArrayAt,2] ,;
                       cType := aType[ aScan(aType, {|x| Left(x,1) = cType} )],;
                       Eval (bChange) ,;
                       nLen := aFields[oBrw:nArrayAt,3] ,;
                       nDec := aFields[oBrw:nArrayAt,4] ,;
                       oGet:SetPos( 0 ),;
                       oGet:SetFocus(),;
                       oDlg:Update() ) ,) ;
                     }
   local bSave := {|| oBtn:Disable (),;
                      aFields[oBrw:nArrayAt,1] := cFieldname,;
                      aFields[oBrw:nArrayAt,2] := Left (cType,1),;
                      aFields[oBrw:nArrayAt,3] := nLen,;
                      aFields[oBrw:nArrayAt,4] := nDec,;
                      oBrw:SetArray (aFields),;
                      cFieldName := Space( 10 ),;
                      Eval (bChange) ,;
                      oDlg:Update() ,;
                      oGet:SetPos( 0 ),;
                      oGet:SetFocus(),;
                      oBrw:GoBottom();
                      }

   DEFINE DIALOG oDlg TITLE "DBF builder" SIZE 415, 400

   @ 0.5,  2 SAY "Field Name" OF oDlg SIZE 40, 8
   @ 0.5, 10 SAY "Type" OF oDlg SIZE 40, 8
   @ 0.5, 17 SAY "Len" OF oDlg SIZE 40, 8
   @ 0.5, 22 SAY "Dec" OF oDlg SIZE 20, 8

   @ 1.4, 1 GET oGet VAR cFieldName PICTURE "!!!!!!!!!!" OF oDlg SIZE 41, 11 UPDATE

   @ 1.3, 6.5 COMBOBOX cType ITEMS aType ;
      OF oDlg ON CHANGE Eval (bChange) UPDATE

   @ 1.4, 11.9 GET oLen VAR nLen PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 1.4, 15.4 GET oDec VAR nDec PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 0.9, 26 BUTTON "&Add" OF oDlg SIZE 45, 13 ;
      ACTION AddField( @aFields, @cFieldName, @cType, @nLen, @nDec, oGet, oBrw )

   @ 2.4, 26 BUTTON oBtn PROMPT "&Edit" OF oDlg SIZE 45, 13 ;
     ACTION Eval (bSave)

   @ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
     ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

   @ 4.4, 26 BUTTON "Move &Up" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt > 1,;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt - 1 ],;
                   aFields[ oBrw:nArrayAt - 1 ] := aTemp,;
                   oBrw:GoUp() ),)

   @ 5.4, 26 BUTTON "Move D&own" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt < Len( aFields ),;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt + 1 ],;
                   aFields[ oBrw:nArrayAt + 1 ] := aTemp,;
                   oBrw:GoDown() ),)

   @ 6.4, 26 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 2.2, 2 SAY "Fields" OF oDlg SIZE 40, 8

   @ 3.2, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 90, 55, 40, 40 ;
      SIZE 140, 130 OF oDlg ;
      ON DBLCLICK Eval (bEdit)

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   @ 12.1, 2 SAY "DBF Name:" OF oDlg SIZE 30, 8

   @ 14, 6 GET cDbfName PICTURE "!!!!!!!!!!!!" OF oDlg SIZE 100, 11

   @ 10, 26 BUTTON "&Create" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! Empty( cDbfName ) .and. Len( aFields ) > 0,;
          DbCreate( AllTrim( cDbfName ), aFields ),), oDlg:End(),;
          Open( hb_CurDrive() + ":\" + CurDir() + "\" + AllTrim( cDbfName ) ) )

   ACTIVATE DIALOG oDlg CENTERED ON INIT (Eval (bChange), oBtn:Disable() ) ;
                                 VALID !GETKEYSTATE( VK_ESCAPE )

return nil

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

function AddField( aFields, cFieldName, cType, nLen, nDec, oGet, oBrw )

   if Empty( cFieldName )
      oGet:SetPos( 0 )
      return nil
   endif

   if Len( aFields ) == 1 .and. Empty( aFields[ 1 ][ 1 ] )
      aFields = { { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } }
   else
      AAdd( aFields, { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } )
   endif

   oBrw:SetArray( aFields )
   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()

return nil
       
//----------------------------------------------------------------------------//

function OrdTagsCount()

   local n, nCount := 0
   
   for n = 1 to 100
      if ! Empty( OrdKey( n ) )
         nCount++
      endif  
   next
   
return nCount  
   
//----------------------------------------------------------------------------//  

function Paste()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Paste()
   endif  

return nil

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

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapirdd.h>

HB_FUNC( ORDCONDGET )
{
   AREAP pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer();
   
   if( pArea )
   {
      LPDBORDERCONDINFO lpdbOrdCondInfo = pArea->lpdbOrdCondInfo;
     
      if( lpdbOrdCondInfo && lpdbOrdCondInfo->abWhile )
         hb_retc( lpdbOrdCondInfo->abWhile );
      else
         hb_retc( "
" );  
   }
   else
      hb_retc( "
" );    
}

#pragma ENDDUMP

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

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

Re: FiveDBU for 32/64 bits

Postby ukoenig » Tue Jun 05, 2012 4:49 pm

Some Cosmetics :
Created a Set of Images for small dialog-buttons ( from Resource )
Added a Dialog to select a Skin-set.

New :

Image

Old :

Image

Skin-selector :
The Set-number is saved to a INI-file. 0 = NO Skin

Image

Best Regards
Uwe :lol:
Last edited by ukoenig on Tue Jun 05, 2012 8:34 pm, edited 6 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
ukoenig
 
Posts: 4043
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany

Re: FiveDBU for 32/64 bits

Postby mastintin » Tue Jun 05, 2012 7:07 pm

IndexBuilder function added in fivedbu for Mac .
minor changes in code from windows.
Image

Code: Select all  Expand view  RUN

function IndexBuilder()

   local oDlg, cExp := Space( 80 ), cTo := Space( 80 ), cTag := Space( 20 )
   local cFor := Space( 80 ), cWhile := Space( 80 ), lUnique := .F.
   local lDescend := .F., lMemory := .F., cScope := "All", nRecNo
   local oPgr, nMeter := 0, nStep := 10, lTag := .T.
   
   DEFINE DIALOG oDlg TITLE "Index builder"

   oDlg:setSize(530, 380 )

   @ 317, 14 SAY "Expression:" OF oDlg SIZE 80, 20

   @ 317, 100 GET cExp OF oDlg SIZE 380, 20 ;
      VALID ! Empty( cExp )

   @ 317, 488 BUTTON "..." SIZE 20, 20 ACTION .t. ;// ExpBuilder( @cExp )
   STYLE 10
   
   @ 287, 60 SAY "To:" OF oDlg SIZE 80, 20

   @ 287, 100 GET cTo OF oDlg SIZE 380, 20

   @ 257, 54 SAY "Tag:" OF oDlg SIZE 80, 20

   @ 257, 100 GET cTag OF oDlg SIZE 260, 20
   
   @ 227, 54 SAY "For:" OF oDlg SIZE 80, 20

   @ 227, 100 GET cFor OF oDlg SIZE 380, 20  

   @ 227, 488 BUTTON "..." SIZE 20, 20 ACTION .t. ;// ExpBuilder( @cExp )
   STYLE 10

   @ 197, 46 SAY "While:" OF oDlg SIZE 80, 20

   @ 197, 100 GET cWhile OF oDlg SIZE 380, 20

   @ 197, 488 BUTTON "..." SIZE 20, 20 ACTION .t. ;// ExpBuilder( @cExp )
     STYLE 10
   
   @ 167, 100 CHECKBOX lUnique PROMPT "Unique" OF oDlg SIZE 100, 20

   @ 167, 230 CHECKBOX lDescend PROMPT "Descending" OF oDlg SIZE 100, 20

   @ 167, 360 CHECKBOX lMemory PROMPT "Memory" OF oDlg SIZE 100, 20

   @ 136, 100 SAY "Scope:" OF oDlg SIZE 80, 20
   
   @ 107, 100 COMBOBOX cScope ITEMS { "All", "Next", "Record", "Rest" } OF oDlg

   @ 136, 200 SAY "Record:" OF oDlg SIZE 80, 20

   @ 111, 200 GET nRecNo OF oDlg SIZE 180, 22

   @ 83 , 100 SAY "Progress:" OF oDlg SIZE 100, 20
   
   @ 62 , 100 PROGRESS oPgr OF oDlg SIZE 380, 20
   
   @ 14, 280 BUTTON "Create" OF oDlg SIZE 100 , 24;
      ACTION ( OrdCondSet( If( ! Empty( cFor ), cFor,),;
                           If( ! Empty( cFor ), GENBLOCK( cFor ),),;
                           If( cScope == "All", .T.,),;
                           If( ! Empty( cWhile ), GENBLOCK( cWhile ),),;
                           { || nMeter += nStep, oPgr:SetPos( nMeter ) },;
                           nStep, Recno(),;
                           If( cScope == "Next", nRecNo,),;
                           If( cScope == "Record", nRecNo,),;
                           If( cScope == "Rest", .T.,),;
                           If( lDescend, .T.,),;
                           lTag,, .F., .F., .F., .T., .F., .F. ),;
               OrdCreate( OrdBagName(), If( lTag, cTag,), cExp, GENBLOCK( cExp ),;
                          If( lUnique, .T.,) ), oDlg:End() )                                      

   @ 14, 400 BUTTON "Cancel" OF oDlg SIZE 100, 24 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED

return nil

 
User avatar
mastintin
 
Posts: 1516
Joined: Thu May 27, 2010 2:06 pm

Re: FiveDBU for 32/64 bits

Postby Eoeo » Tue Jun 05, 2012 7:36 pm

just an Idea ....Why not implent a Expression Builder wit a dialog and only a xbrowse .... and save the filter expression to a Ini file ?

I explain You :

see his image


Image


On first dialog we save all expressions for that dbf

on second dialog we create therows of expression filter

name of the filter ( to save the file Ini)

then an array with 4 fields

Operator

Field

Condition

Expression


At Init we add on an array all fields and insert this on a combobox to select

the first row not have the operator ( and OR NOT ) but only from second line

On secon combobox we insert the relation


::acOpRelacion := { " ", ;
"<> desigual ", ;
"!= desigual ", ;
"# desigual ", ;
"$ contiene ", ;
"< menor que ", ;
"<= menor o igual que", ;
"> mayor que ", ;
">= mayor o igual que", ;
"= igual ", ;
"== exactamente igual" }



and we can save the first exression row on xbrowse then we can select the operator ( and not or ) to insert the second row of expression into xbrowse
using only an array

then we can save all on a inifile and call it with dbsetfilter function

we can save for that dbf many expressions we want , we can use it also for the report



just an idea .....
User avatar
Eoeo
 
Posts: 222
Joined: Mon Jun 04, 2012 12:00 pm

Re: FiveDBU for 32/64 bits

Postby Antonio Linares » Wed Jun 06, 2012 10:34 am

Enhanced version with preferences support, goto recno, shown Rdd in use, etc :-)

Code: Select all  Expand view  RUN


#include "FiveWin.ch"
#include "xbrowse.ch"
#include "dbinfo.ch"

#ifdef __XHARBOUR__
   #define hb_CurDrive() CurDrive()
#endif  

#define GENBLOCK(x)  &( "{ || " + x + " }" )

REQUEST DBFCDX

static oWndMain, oMruDBFs, aSearches := {}, cDefRdd := "DBFCDX"

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

function Main( cDbfName )

   local oBar, oBmpTiled
   
   SET DATE FORMAT TO "DD/MM/YYYY"
   LoadPreferences()

   SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )

   DEFINE BITMAP oBmpTiled RESOURCE "background"

   DEFINE WINDOW oWndMain TITLE "FiveDBU" MDI MENU BuildMenu()

   DEFINE BUTTONBAR oBar OF oWndMain 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "new" ACTION New()

   DEFINE BUTTON OF oBar PROMPT "Open" RESOURCE "open" ACTION Open()

   DEFINE BUTTON OF oBar PROMPT "Copy" RESOURCE "copy" ACTION Copy() GROUP

   DEFINE BUTTON OF oBar PROMPT "Paste" RESOURCE "paste" ACTION Paste()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION oWndMain:PrevWindow() GROUP WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION oWndMain:NextWindow() WHEN Len( oWndMain:oWndClient:aWnd ) > 1

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWndMain:End() GROUP

   DEFINE MSGBAR PROMPT "FiveDBU 32/64 bits, (c) FiveTech Software 2012" ;
      OF oWndMain 2010 KEYBOARD DATE

   if ! Empty( cDbfName )
      Open( cDbfName )
   endif  

   ACTIVATE WINDOW oWndMain MAXIMIZED ;
      VALID MsgYesNo( "Want to end ?" ) ;
      ON PAINT DrawTiled( hDC, oWndMain, oBmpTiled )
   
   oBmpTiled:End()      

return nil

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

function BuildMenu()

   local oMenu
   
   MENU oMenu
      MENUITEM "Files"
      MENU
         MENUITEM "New..."
         MENUITEM "Open..." ACTION Open()
         SEPARATOR
         MENUITEM "Recent files"
         MENU
            MRU oMruDBFs ;
               FILENAME ".\FiveDBU.ini" ;    // .INI to manipulate. '\.' for local
               SECTION  "Recent DBF files" ; // The name of the INI section
               ACTION   Open( cMruItem ) ;   // cMruItem is automatically provided
               MESSAGE  "Open this file" ;   // The message for all of them
               SIZE     10
         ENDMENU      

         SEPARATOR
         
         MENUITEM "Preferences..." ACTION Preferences()
         
         SEPARATOR
         
         MENUITEM "Exit" ACTION oWndMain:End()
      ENDMENU
     
      // oMenu:AddEdit()
      oMenu:AddMdi()
      oMenu:AddHelp( "FiveDBU", "(c) FiveTech Software 2012" )
   ENDMENU
   
return oMenu      

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

function Open( cFileName )

   local oWnd, oBar, oBrw
   local oMsgBar, oMsgRecNo, oMsgDeleted, oMsgTagName, oMsgRdd
   local oPopup, cAlias, n, cClrBack, nTags
   
   DEFAULT cFileName := cGetFile( "*.dbf", "Please select a DBF" )
   
   if Empty( cFileName )
      return nil
   endif  
   
   if ! "." $ cFileName
      cFileName += ".dbf"
   endif  
   
   if ! File( cFileName )
      MsgStop( "File not found: " + cFileName )
      return nil
   endif
   
   if File( cFileNoExt( cFileName ) + ".ntx" )
      USE ( cFileName ) VIA "DBFNTX" NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
   else  
      USE ( cFileName ) VIA cDefRdd NEW SHARED ;
         ALIAS ( cGetNewAlias( cFileName( cFileNoExt( cFileName ) ) ) )
      cAlias = Alias()
   endif        
   
   oMruDBFs:Save( cFileName )
   
   MENU oPopup POPUP
      MENUITEM "Natural order" ;
         ACTION ( ( cAlias )->( DbSetOrder( 0 ) ), oBrw:Refresh(), oBrw:SetFocus(),;
                  ( cAlias )->( Eval( oBrw:bChange ) ) )
     
      if ( nTags := ( cAlias )->( OrdCount() ) ) > 0
         SEPARATOR
      endif  
     
      for n = 1 to nTags
         if ! Empty( OrdName( n ) )
            if ! Empty( OrdName( 1 ) )
               DbSetOrder( OrdName( 1 ) )
               DbGoTop()
            endif  
            MENUITEM OrdName( n ) ;
               ACTION ( ( cAlias )->( DbSetOrder( oMenuItem:cPrompt ) ),;
                        oBrw:Refresh(), ( cAlias )->( Eval( oBrw:bChange ) ), oBrw:SetFocus() )
         endif
      next    
   ENDMENU  
   
   DEFINE WINDOW oWnd TITLE "Browse " + cAlias MDICHILD

   oWnd:bCopy = { || MsgInfo( "copy" ) }

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( ( oBrw:cAlias )->( DbAppend() ), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( oBrw:cAlias )->( Edit() )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION ( obrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )

   DEFINE BUTTON OF oBar PROMPT "Search" RESOURCE "search" ;
      GROUP ACTION ( cAlias )->( Search( oBrw ) )

   DEFINE BUTTON OF oBar PROMPT "Index" RESOURCE "index" ;
      MENU oPopup ACTION ( cAlias )->( Indexes() )

   DEFINE BUTTON OF oBar PROMPT "Relations" RESOURCE "relation" ;
      ACTION ( cAlias )->( Relations() )

   DEFINE BUTTON OF oBar PROMPT "Top" RESOURCE "top" ;
      ACTION ( oBrw:GoTop(), oBrw:SetFocus() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Bottom" RESOURCE "bottom" ;
      ACTION ( oBrw:GoBottom(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Struct" RESOURCE "struct" ;
      ACTION ( oBrw:cAlias )->( Struct() ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report()

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd LINES ;
      ON CHANGE ( oMsgBar:cMsgDef := "FileName: " + cFileName,;
                                     oMsgBar:Refresh(),;
                                     oMsgRecNo:SetText( "RecNo: " + ;
                                                        AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + " / " + ;
                                                        AllTrim( Str( ( cAlias )->( RecCount() ) ) ) ),;
                                     oMsgTagName:SetText( "Ordered by: " + If( ! Empty( OrdName() ), OrdName(), "Natural order" ) ),;
                                     oMsgDeleted:SetText( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "DELETED", "NON DELETED" ) ),;
                                     oMsgDeleted:SetBitmap( If( ( oBrw:cAlias )->( Deleted() ),;
                                     "deleted", "nondeleted" ) ) )

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 198, 255, 198 ) }, ;
                         { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
                           RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                           RGB( 0x33, 0x66, 0xCC ) } }
   cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]                                              
   oBrw:bClrSelFocus = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
                              cClrBack } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   oBrw:bLDblClick = { || ( oBrw:cAlias )->( Edit() ) }                      
   
   oWnd:oClient = oBrw
   oWnd:oControl = oBrw

   DEFINE MSGBAR oMsgBar PROMPT "FileName: " + cFileName OF oWnd 2010

   DEFINE MSGITEM oMsgRecNo OF oMsgBar ;
          PROMPT "RecNo: " + ;
          AllTrim( Str( RecNo() ) ) + " / " + ;
          AllTrim( Str( RecCount() ) ) ;
          SIZE 150 ;
          ACTION ( cAlias )->( DlgGoTo( oBrw ) )

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( oBrw:cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 120 ;
          BITMAPS "nondeleted" ;
          ACTION ( oBrw:cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  

   DEFINE MSGITEM oMsgTagName OF oMsgBar ;
          PROMPT "Ordered by: " + ;
          If( ! Empty( ( oBrw:cAlias )->( OrdName() ) ),;
              ( oBrw:cAlias )->( OrdName() ), "Natural order" ) ;
          SIZE 150

   DEFINE MSGITEM oMsgRdd OF oMsgBar ;
          PROMPT "Rdd: " + ( cAlias )->( RddName() ) ;
          SIZE 120
         
   ACTIVATE WINDOW oWnd ;
      VALID ( ( cAlias )->( DbCloseArea() ), oBrw:cAlias := "", .T. )
   
return nil  

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

function Copy()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Copy()
   endif  

return nil

//----------------------------------------------------------------------------//
 
function DelField( aFields, cFieldName, oGet, oBrw )

   if Len( aFields ) >= 1
      ADel( aFields, oBrw:nArrayAt, .T. )
      oBrw:SetArray( aFields )
   endif

   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()
               
return nil

//----------------------------------------------------------------------------//
       
function DelRecord( oBrw, oMsgDeleted )

   if ! Deleted()
      if ! MsgYesNo( "Want to delete this record ?" )
         return nil
      endif  
      DbRLock()  
      DbDelete()  
      DbUnlock()  
      oMsgDeleted:SetText( "DELETED" )
      oMsgDeleted:SetBitmap( "deleted" )
   else
      DbRLock()  
      DbRecall()  
      DbUnlock()        
      oMsgDeleted:SetText( "NON DELETED" )
      oMsgDeleted:SetBitmap( "nondeleted" )
      MsgInfo( "UnDeleted record" )
   endif
   
   Eval( oBrw:bChange )
   oBrw:Refresh()

return nil  

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

function DlgGoTo( oBrw )

   local oDlg, nRecNo := RecNo()
   
   DEFINE DIALOG oDlg TITLE Alias() + " go to record" SIZE 400, 200

   @ 1.2, 1.5 SAY "Current record: " + AllTrim( Str( RecNo() ) ) + ;
      " / " + AllTrim( Str( RecCount() ) ) OF oDlg
   
   @ 2.4, 1.2 GET nRecNo OF oDlg SIZE 180, 11
   
   @ 4, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( DbGoTo( nRecNo ), oBrw:Refresh(), oDlg:End() )

   @ 4, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil  

//----------------------------------------------------------------------------//
   
function Edit()

   local oWnd, aRecord := ( Alias() )->( LoadRecord() ), oBar, oBrw, oMsgBar
   local cAlias := Alias(), oBtnSave, nRecNo := ( Alias() )->( RecNo() )
   local oMsgDeleted
   
   DEFINE WINDOW oWnd TITLE "Edit " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70
   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" RESOURCE "save" ;
      ACTION ( ( cAlias )->( SaveRecord( aRecord, nRecNo ) ), oBtnSave:Disable() )

   oBtnSave:Disable()

   DEFINE BUTTON OF oBar PROMPT "Prev" RESOURCE "prev" ;
      ACTION GoPrevRecord( oBrw, aRecord, oMsgDeleted ) GROUP

   DEFINE BUTTON OF oBar PROMPT "Next" RESOURCE "next" ;
      ACTION GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP

   DEFINE BUTTON OF oBar PROMPT "View" RESOURCE "view" ;
      ACTION View( oBrw:aRow[ 2 ], oWnd )
     
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRecord AUTOCOLS LINES ;
      HEADERS "FieldName", "Value" COLSIZES 150, 400 FASTEDIT ;
      ON CHANGE ( ( cAlias )->( SetEditType( oBrw, oBtnSave ) ), oBrw:DrawLine( .T. ),;
                  oMsgBar:cMsgDef := " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + ;
                                 "/" + AllTrim( Str( ( cAlias )->( RecCount() ) ) ),;
                  oMsgBar:Refresh() )                

   oBrw:nEditTypes = EDIT_GET
   oBrw:aCols[ 1 ]:nEditType = 0 // Don't allow to edit first column
   oBrw:aCols[ 2 ]:bOnChange = { || oBtnSave:Enable() }
   oBrw:aCols[ 2 ]:lWillShowABtn = .T.
   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar ;
      PROMPT " RecNo: " + AllTrim( Str( ( cAlias )->( RecNo() ) ) ) + "/" + ;
      AllTrim( Str( ( cAlias )->( RecCount() ) ) ) OF oWnd 2010

   DEFINE MSGITEM oMsgDeleted OF oMsgBar ;
          PROMPT If( ( cAlias )->( Deleted() ), "DELETED", "NON DELETED" ) ;
          SIZE 130 ;
          BITMAPS If( ( cAlias )->( Deleted() ), "deleted", "nondeleted" ) ;
          ACTION ( cAlias )->( DelRecord( oBrw, oMsgDeleted ) )  
   
   ACTIVATE WINDOW oWnd
   
return nil      

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

function GoPrevRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( -1 )
   
   oBrw:SetArray( aRecord := LoadRecord() )
   oBrw:SetFocus()
   Eval( oBrw:bChange )

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function GoNextRecord( oBrw, aRecord, oMsgDeleted )

   DbSkip( 1 )
   
   If Eof()
      DbSkip( -1 )
   else
      oBrw:SetArray( aRecord := LoadRecord() )
      oBrw:SetFocus()
      Eval( oBrw:bChange )
   endif  

   oMsgDeleted:SetText( If( Deleted(), "DELETED", "NON DELETED" ) )
   oMsgDeleted:SetBitmap( If( Deleted(), "deleted", "nondeleted" ) )
   
return nil

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

function SetEditType( oBrw, oBtnSave )

   local cType := FieldType( oBrw:nArrayAt )
   
   do case
      case cType == "M"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { | c | c := oBrw:aRow[ 2 ],;
                                               MemoEdit( @oBrw:aRow[ 2 ], FieldName( oBrw:nArrayAt ) ),;
                                               If( ! c == oBrw:aRow[ 2 ], oBtnSave:Enable(),),;
                                               oBrw:aRow[ 2 ] }
   
      case cType == "D"
           oBrw:aCols[ 2 ]:nEditType = EDIT_BUTTON
           oBrw:aCols[ 2 ]:bEditBlock = { || If( ! Empty( oBrw:aRow[ 2 ] ) .and. ;
                                                 ! AllTrim( oBrw:aRow[ 2 ] ) == "/  /",;
                                             DToC( MsgDate( CtoD( oBrw:aRow[ 2 ] ) ) ),;
                                             DToC( MsgDate( Date() ) ) ) }
   
      case cType == "L"
           oBrw:aCols[ 2 ]:nEditType = EDIT_LISTBOX
           oBrw:aCols[ 2 ]:aEditListTxt   = { ".T.", ".F." }
           
      otherwise
           oBrw:aCols[ 2 ]:nEditType = EDIT_GET
   endcase
   
return nil              

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

function IndexBuilder()

   local oDlg, cExp := Space( 80 ), cTo := Space( 80 ), cTag := Space( 20 )
   local cFor := Space( 80 ), cWhile := Space( 80 ), lUnique := .F.
   local lDescend := .F., lMemory := .F., cScope := "All", nRecNo
   local oPgr, nMeter := 0, nStep := 10, lTag := .T.
   
   DEFINE DIALOG oDlg TITLE "Index builder" SIZE 530, 380

   @ 0.4, 3 SAY "Expression:" OF oDlg SIZE 40, 8

   @ 0.5, 6 GET cExp OF oDlg SIZE 200, 11 ACTION ExpBuilder( @cExp ) ;
      VALID ! Empty( cExp )
   
   @ 1.5, 6 SAY "To:" OF oDlg SIZE 40, 8

   @ 1.7, 6 GET cTo OF oDlg SIZE 200, 11

   @ 2.6, 5.5 SAY "Tag:" OF oDlg SIZE 40, 8

   @   3, 6 GET cTag OF oDlg SIZE 100, 11
   
   @ 3.7, 5.9 SAY "For:" OF oDlg SIZE 40, 8

   @ 4.3, 6 GET cFor OF oDlg SIZE 200, 11 ACTION ExpBuilder()

   @ 4.8, 5 SAY "While:" OF oDlg SIZE 40, 8

   @ 5.6, 6 GET cWhile OF oDlg SIZE 200, 11 ACTION ExpBuilder()
   
   @ 6.8, 6.9 CHECKBOX lUnique PROMPT "&Unique" OF oDlg SIZE 50, 8

   @ 6.8, 13.9 CHECKBOX lDescend PROMPT "&Descending" OF oDlg SIZE 80, 8

   @ 6.8, 23 CHECKBOX lMemory PROMPT "&Memory" OF oDlg SIZE 80, 8

   @ 6.8, 8 SAY "Scope:" OF oDlg SIZE 40, 8
   
   @ 8.2, 6 COMBOBOX cScope ITEMS { "All", "Next", "Record", "Rest" } OF oDlg

   @ 6.8, 16.1 SAY "Record:" OF oDlg SIZE 40, 8

   @ 8.8, 12.1 GET nRecNo OF oDlg SIZE 30, 11

   @ 8.5, 8 SAY "Progress:" OF oDlg SIZE 40, 8
   
   @ 9.2, 8 PROGRESS oPgr OF oDlg SIZE 200, 10
   
   @ 9.2, 13 BUTTON "C&reate" OF oDlg SIZE 45, 13 ;
      ACTION ( OrdCondSet( If( ! Empty( cFor ), cFor,),;
                           If( ! Empty( cFor ), GENBLOCK( cFor ),),;
                           If( cScope == "All", .T.,),;
                           If( ! Empty( cWhile ), GENBLOCK( cWhile ),),;
                           { || nMeter += nStep, oPgr:SetPos( nMeter ), SysRefresh() },;
                           nStep, Recno(),;
                           If( cScope == "Next", nRecNo,),;
                           If( cScope == "Record", nRecNo,),;
                           If( cScope == "Rest", .T.,),;
                           If( lDescend, .T.,),;
                           lTag,, .F., .F., .F., .T., .F., .F. ),;
               OrdCreate( OrdBagName(), If( lTag, cTag,), cExp, GENBLOCK( cExp ),;
                          If( lUnique, .T.,) ), oDlg:End() )                                      

   @ 9.2, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
   
   ACTIVATE DIALOG oDlg CENTERED

return nil

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

function Indexes()

   local oWnd, oBar, oBrw, oMsgBar
   local cAlias := Alias(), aIndexes := Array( OrdCount() )
   
   DEFINE WINDOW oWnd TITLE "Indexes of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION ( IndexBuilder(), oBrw:Refresh(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION If( MsgYesNo( "Want to delete this tag ?" ),;
                ( ( cAlias )->( OrdDestroy( oBrw:nArrayAt ) ), oBrw:Refresh() ),)

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aIndexes AUTOCOLS LINES ;
      HEADERS "Order", "TagName", "Expression", "For", "BagName", "BagExt" ;
      COLUMNS { || oBrw:nArrayAt },;
              { || ( cAlias )->( OrdName( oBrw:nArrayAt ) ) },;
              { || ( cAlias )->( OrdKey ( oBrw:nArrayAt ) ) },;
              { || ( cAlias )->( OrdFor ( oBrw:nArrayAt ) ) },;
              { || ( cAlias )->( OrdBagName( oBrw:nArrayAt ) ) } ;
      COLSIZES 50, 100, 400, 240, 100, 100

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010
   
   ACTIVATE WINDOW oWnd

return nil

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

function ExpBuilder( cExp )

   local oDlg, oBrw, aFields := DBStruct()
   local oExp, cFunction
   
   cExp = RTrim( cExp )
   
   DEFINE DIALOG oDlg TITLE "Expression builder" SIZE 480, 450
   
   @ 0.2, 1.5 SAY "Expression:" SIZE 80, 11 OF oDlg
   
   @ 1.1, 1 GET oExp VAR cExp MEMO SIZE 221, 27
   
   @ 3, 1.5 SAY "Fields" OF oDlg SIZE 40, 10
   
   @ 4, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES SIZE 120, 120 ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 95, 30, 30, 30
     
   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:bLDblClick = { || cExp += oBrw:aRow[ 1 ], oExp:Refresh() }

   @ 3, 23.1 SAY "Operators" OF oDlg SIZE 40, 10

   @ 3.1, 23 BUTTON "=" OF oDlg SIZE 15, 15 ACTION ( cExp += " = ", oExp:Refresh() )

   @ 3.1, 26.2 BUTTON "<>" OF oDlg SIZE 15, 15 ACTION ( cExp += " <> ", oExp:Refresh() )

   @ 3.1, 29.4 BUTTON "+" OF oDlg SIZE 15, 15 ACTION ( cExp += " + ", oExp:Refresh() )

   @ 3.1, 32.6 BUTTON "(" OF oDlg SIZE 15, 15 ACTION ( cExp += " ( ", oExp:Refresh() )

   @ 3.1, 35.8 BUTTON ".T." OF oDlg SIZE 15, 15 ACTION ( cExp += " .T. ", oExp:Refresh() )

   @ 4.1, 23 BUTTON "<" OF oDlg SIZE 15, 15 ACTION ( cExp += " < ", oExp:Refresh() )

   @ 4.1, 26.2 BUTTON ">" OF oDlg SIZE 15, 15 ACTION ( cExp += " > ", oExp:Refresh() )

   @ 4.1, 29.4 BUTTON "-" OF oDlg SIZE 15, 15 ACTION ( cExp += " - ", oExp:Refresh() )

   @ 4.1, 32.6 BUTTON ")" OF oDlg SIZE 15, 15 ACTION ( cExp += " )", oExp:Refresh() )

   @ 4.1, 35.8 BUTTON ".F." OF oDlg SIZE 15, 15 ACTION ( cExp += " .F. ", oExp:Refresh() )

   @ 5.1, 23 BUTTON "<=" OF oDlg SIZE 15, 15 ACTION ( cExp += " <= ", oExp:Refresh() )

   @ 5.1, 26.2 BUTTON ">=" OF oDlg SIZE 15, 15 ACTION ( cExp += " >= ", oExp:Refresh() )

   @ 5.1, 29.4 BUTTON "*" OF oDlg SIZE 15, 15 ACTION ( cExp += " * ", oExp:Refresh() )

   @ 5.1, 32.6 BUTTON "/" OF oDlg SIZE 15, 15 ACTION ( cExp += " / ", oExp:Refresh() )

   @ 5.1, 35.8 BUTTON "$" OF oDlg SIZE 15, 15 ACTION ( cExp += " $ ", oExp:Refresh() )

   @ 6.1, 23 BUTTON '"' OF oDlg SIZE 15, 15 ACTION ( cExp += '"', oExp:Refresh() )

   @ 6.1, 26.2 BUTTON "!" OF oDlg SIZE 15, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 6.1, 29.4 BUTTON "SP" OF oDlg SIZE 15, 15 ACTION ( cExp += " ", oExp:Refresh() )

   @ 6.1, 32.6 BUTTON "," OF oDlg SIZE 15, 15 ACTION ( cExp += ", ", oExp:Refresh() )

   @ 6.1, 35.8 BUTTON ":" OF oDlg SIZE 15, 15 ACTION ( cExp += " : ", oExp:Refresh() )

   @ 7.1, 23 BUTTON "AND" OF oDlg SIZE 27, 15 ACTION ( cExp += " .and. ", oExp:Refresh() )

   @ 7.1, 28.4 BUTTON "OR" OF oDlg SIZE 27, 15 ACTION ( cExp += " .or. ", oExp:Refresh() )

   @ 7.1, 33.7 BUTTON "NOT" OF oDlg SIZE 27, 15 ACTION ( cExp += " ! ", oExp:Refresh() )

   @ 10.3, 23.2 SAY "Functions" OF oDlg SIZE 84, 11

   @ 11.9, 17.3 COMBOBOX cFunction ITEMS { "AllTrim()", "Left()", "Right()", "SubStr()" } ;
      OF oDlg SIZE 92, 80 ON CHANGE ( cExp += Left( cFunction, Len( cFunction ) - 1 ) + " ",;
                                      oExp:Refresh() )

   @ 11, 13 BUTTON "&Ok" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 11, 24 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End() CANCEL
           
   ACTIVATE DIALOG oDlg CENTERED

return cExp

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

function LoadRecord()

   local aRecord := {}, n
   
   for n = 1 to FCount()
      AAdd( aRecord, { FieldName( n ), FieldGet( n ) } )
   next
   
return aRecord      
   
//----------------------------------------------------------------------------//

function Search( oBrw )

   local oDlg, oCbx, cSearch := Space( 50 )
   local nRecNo := RecNo(), lInc := .T.
   
   DEFINE DIALOG oDlg TITLE "Search: " + Alias() SIZE 400, 200
   
   @ 0.5, 1.5 SAY "Ordered by: " + OrdName() OF oDlg
   
   @ 1.2, 1.5 SAY "Key: " + OrdKey() OF oDlg
   
   @ 2.4, 1.2 COMBOBOX oCbx VAR cSearch ITEMS aSearches OF oDlg SIZE 180, 150 ;
     STYLE CBS_DROPDOWN
   
   oCbx:oGet:bChange = { || DbSeek( AllTrim( oCbx:GetText() ), lInc ), oBrw:Refresh() }
   
   @ 3.7, 1.5 CHECKBOX lInc PROMPT "&Incremental" OF oDlg SIZE 80, 10
   
   @ 4, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! DbSeek( AllTrim( cSearch ), lInc ), DbGoTo( nRecNo ),),;
               AAdd( aSearches, AllTrim( cSearch ) ), oDlg:End() )

   @ 4, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil  

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

function Preferences()

   local oDlg
   
   DEFINE DIALOG oDlg TITLE "Preferences" SIZE 400, 200

   @ 1.2, 1.5 SAY "Default RDD: " + cDefRdd OF oDlg
   
   @ 2.4, 1.2 COMBOBOX cDefRdd ITEMS { "DBFNTX", "DBFCDX", "RDDADS" } ;
      OF oDlg SIZE 180, 150
   
   @ 4, 7 BUTTON "&Ok" OF oDlg SIZE 45, 13 ;
      ACTION ( SavePreferences(), oDlg:End() )

   @ 4, 18 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil  

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

function Relations()

   local oWnd, oBar, oBrw, aRelations := Array( 8 ), oMsgBar
   local nTarget, cAlias := Alias()
   
   DEFINE WINDOW oWnd TITLE "Relations of " + Alias() MDICHILD

   oWndMain:oBar:AEvalWhen()

   DEFINE BUTTONBAR oBar OF oWnd 2010 SIZE 70, 70

   DEFINE BUTTON OF oBar PROMPT "Add" RESOURCE "add" ;
      ACTION MsgInfo( "Add" )

   DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
      ACTION ( MsgInfo( "Edit" ) )

   DEFINE BUTTON OF oBar PROMPT "Del" RESOURCE "del" ;
      ACTION MsgInfo( "del" )

   DEFINE BUTTON OF oBar PROMPT "Report" RESOURCE "report" ;
      ACTION oBrw:Report() GROUP
   
   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oWnd:End() GROUP

   @ 0, 0 XBROWSE oBrw OF oWnd ARRAY aRelations AUTOCOLS LINES ;
      HEADERS "Rel.", "Expression", "Child Alias", "Additive", "Scoped" ;
      COLUMNS { || oBrw:nArrayAt },;
              { || ( cAlias )->( DbRelation( oBrw:nArrayAt ) ) },;
              { || If( ( cAlias )->( DbRSelect( oBrw:nArrayAt ) ) != 0,;
                   Alias( ( cAlias )->( DbRSelect( oBrw:nArrayAt ) ) ), "" ) },;
              { || ".F." }, { || ".F." } ;    
      COLSIZES 40, 150, 400, 100, 100

   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()
   oBrw:SetFocus()
   
   oWnd:oClient = oBrw

   DEFINE MSGBAR oMsgBar 2010

   ACTIVATE WINDOW oWnd

return nil

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

function LoadPreferences()

   local oIni

   if File( "./fivedbu.ini" )
      INI oIni FILE "./fivedbu.ini"
         GET cDefRdd SECTION "Default" ENTRY "RDD" OF oIni
      ENDINI      
   endif  

return nil

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

function SavePreferences()

   local oIni

   INI oIni FILE "./fivedbu.ini"
      SET SECTION "Default" ENTRY "RDD" OF oIni TO cDefRdd
   ENDINI      

return nil

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

function SaveRecord( aRecord, nRecNo )

   local n

   ( Alias() )->( DbGoTo( nRecNo ) )
   
   if ( Alias() )->( DbRLock( nRecNo ) )
      for n = 1 to Len( aRecord )
         ( Alias() )->( FieldPut( n, aRecord[ n ][ 2 ] ) )
      next
      ( Alias() )->( DbUnLock() )
      MsgInfo( "Record updated" )
   else
      MsgAlert( "Record in use, please try it again" )
   endif        

return nil      

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

function Struct()

   local oDlg, oBrw, aFields := DbStruct()
   
   DEFINE DIALOG oDlg TITLE Alias() + " fields" SIZE 400, 400

   @ 0, 0 XBROWSE oBrw ARRAY aFields AUTOCOLS LINES ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 150, 50, 80, 80

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW  
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }                      
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   
   oBrw:CreateFromCode()
     
   oDlg:oClient = oBrw
   
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( BuildStructBar( oDlg, oBrw ), oDlg:Resize(), oBrw:SetFocus() )
   
return nil  

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

function BuildStructBar( oDlg, oBrw )

   local oBar

   DEFINE BUTTONBAR oBar OF oDlg 2010 SIZE 70, 70
   
   DEFINE BUTTON OF oBar PROMPT "Code" RESOURCE "code" ;
      ACTION ( TxtStruct(), oBrw:SetFocus() )

   DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
      ACTION oDlg:End() GROUP

return nil

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

function TxtStruct()

   local cCode := "local aFields := { ", n
   
   for n = 1 to FCount()
      if n > 1
         cCode += Space( 27 )
      endif  
      cCode += '{ "' + FieldName( n ) + '", "' + ;
               FieldType( n ) + '", ' + ;
               AllTrim( Str( FieldLen( n ) ) ) + ", " + ;
               AllTrim( Str( FieldDec( n ) ) ) + " },;" + CRLF
   next
   
   cCode = SubStr( cCode, 1, Len( cCode ) - 4 ) + " }"
   
   MemoEdit( cCode, "Code" )

return nil

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

function View( cFileName, oWnd )

   local cExt := Lower( cFileExt( cFileName ) )
   
   do case
      case cExt == "bmp"
           WinExec( "mspaint" + " " + cFileName )
           
      case cExt == "txt"
           WinExec( "notepad" + " " + cFileName )    
           
      otherwise
           ShellExecute( oWnd:hWnd, "Open", cFileName )
   endcase
   
return nil                

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

function New()

   local oDlg, oGet, oBrw, oBtn
   local cFieldName := Space( 10 ), cType := "Character", nLen := 10, nDec := 0
   local aFields := { Array( 4 ) }, cDbfName := Space( 8 ), aTemp
   local oLen, oDec, aType := { "Character", "Number", "Date", "Logical", "Memo" }
   local bChange := {|| If( cType == "Character", (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        If( cType == "Number",    (nLen := 10, nDec := 0, oDec:Enable()  ),),;
                        If( cType == "Date",      (nLen := 8,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Logical",   (nLen := 1,  nDec := 0, oDec:Disable() ),),;
                        If( cType == "Memo",      (nLen := 10, nDec := 0, oDec:Disable() ),),;
                        oDlg:Update() }
   local bEdit := {|| IF ( !Empty (aFields[1,1]) ,;
                      (oBtn:Enable (),;
                       cFieldName := aFields[oBrw:nArrayAt,1] ,;
                       cType := aFields[oBrw:nArrayAt,2] ,;
                       cType := aType[ aScan(aType, {|x| Left(x,1) = cType} )],;
                       Eval (bChange) ,;
                       nLen := aFields[oBrw:nArrayAt,3] ,;
                       nDec := aFields[oBrw:nArrayAt,4] ,;
                       oGet:SetPos( 0 ),;
                       oGet:SetFocus(),;
                       oDlg:Update() ) ,) ;
                     }
   local bSave := {|| oBtn:Disable (),;
                      aFields[oBrw:nArrayAt,1] := cFieldname,;
                      aFields[oBrw:nArrayAt,2] := Left (cType,1),;
                      aFields[oBrw:nArrayAt,3] := nLen,;
                      aFields[oBrw:nArrayAt,4] := nDec,;
                      oBrw:SetArray (aFields),;
                      cFieldName := Space( 10 ),;
                      Eval (bChange) ,;
                      oDlg:Update() ,;
                      oGet:SetPos( 0 ),;
                      oGet:SetFocus(),;
                      oBrw:GoBottom();
                      }

   DEFINE DIALOG oDlg TITLE "DBF builder" SIZE 415, 400

   @ 0.5,  2 SAY "Field Name" OF oDlg SIZE 40, 8
   @ 0.5, 10 SAY "Type" OF oDlg SIZE 40, 8
   @ 0.5, 17 SAY "Len" OF oDlg SIZE 40, 8
   @ 0.5, 22 SAY "Dec" OF oDlg SIZE 20, 8

   @ 1.4, 1 GET oGet VAR cFieldName PICTURE "!!!!!!!!!!" OF oDlg SIZE 41, 11 UPDATE

   @ 1.3, 6.5 COMBOBOX cType ITEMS aType ;
      OF oDlg ON CHANGE Eval (bChange) UPDATE

   @ 1.4, 11.9 GET oLen VAR nLen PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 1.4, 15.4 GET oDec VAR nDec PICTURE "999" OF oDlg SIZE 25, 11 UPDATE

   @ 0.9, 26 BUTTON "&Add" OF oDlg SIZE 45, 13 ;
      ACTION AddField( @aFields, @cFieldName, @cType, @nLen, @nDec, oGet, oBrw )

   @ 2.4, 26 BUTTON oBtn PROMPT "&Edit" OF oDlg SIZE 45, 13 ;
     ACTION Eval (bSave)

   @ 3.4, 26 BUTTON "&Delete" OF oDlg SIZE 45, 13 ;
     ACTION DelField (@aFields, @cFieldName, oGet, oBrw)

   @ 4.4, 26 BUTTON "Move &Up" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt > 1,;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt - 1 ],;
                   aFields[ oBrw:nArrayAt - 1 ] := aTemp,;
                   oBrw:GoUp() ),)

   @ 5.4, 26 BUTTON "Move D&own" OF oDlg SIZE 45, 13 ;
      ACTION If( oBrw:nArrayAt < Len( aFields ),;
                 ( aTemp := aFields[ oBrw:nArrayAt ],;
                   aFields[ oBrw:nArrayAt ] := aFields[ oBrw:nArrayAt + 1 ],;
                   aFields[ oBrw:nArrayAt + 1 ] := aTemp,;
                   oBrw:GoDown() ),)

   @ 6.4, 26 BUTTON "&Cancel" OF oDlg SIZE 45, 13 ACTION oDlg:End()

   @ 2.2, 2 SAY "Fields" OF oDlg SIZE 40, 8

   @ 3.2, 1 XBROWSE oBrw ARRAY aFields AUTOCOLS ;
      HEADERS "Name", "Type", "Len", "Dec" ;
      COLSIZES 90, 55, 40, 40 ;
      SIZE 140, 130 OF oDlg ;
      ON DBLCLICK Eval (bEdit)

   oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
   oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
                         { CLR_BLACK, RGB( 198, 255, 198 ) }, ;
                         { CLR_BLACK, RGB( 232, 255, 232 ) } ) }
   oBrw:bClrSel = { || { CLR_WHITE, RGB( 0x33, 0x66, 0xCC ) } }
   oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
   oBrw:CreateFromCode()

   @ 12.1, 2 SAY "DBF Name:" OF oDlg SIZE 30, 8

   @ 14, 6 GET cDbfName PICTURE "!!!!!!!!!!!!" OF oDlg SIZE 100, 11

   @ 10, 26 BUTTON "&Create" OF oDlg SIZE 45, 13 ;
      ACTION ( If( ! Empty( cDbfName ) .and. Len( aFields ) > 0,;
          DbCreate( AllTrim( cDbfName ), aFields ),), oDlg:End(),;
          Open( hb_CurDrive() + ":\" + CurDir() + "\" + AllTrim( cDbfName ) ) )

   ACTIVATE DIALOG oDlg CENTERED ON INIT (Eval (bChange), oBtn:Disable() ) ;
                                 VALID !GETKEYSTATE( VK_ESCAPE )

return nil

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

function AddField( aFields, cFieldName, cType, nLen, nDec, oGet, oBrw )

   if Empty( cFieldName )
      oGet:SetPos( 0 )
      return nil
   endif

   if Len( aFields ) == 1 .and. Empty( aFields[ 1 ][ 1 ] )
      aFields = { { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } }
   else
      AAdd( aFields, { cFieldName, Upper( Left( cType, 1 ) ), nLen, nDec } )
   endif

   oBrw:SetArray( aFields )
   oGet:VarPut( cFieldName := Space( 10 ) )
   oGet:SetPos( 0 )
   oGet:SetFocus()
   oBrw:GoBottom()

return nil
       
//----------------------------------------------------------------------------//

function Paste()

   if oWndMain:oWndActive != nil
      oWndMain:oWndActive:Paste()
   endif  

return nil

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

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

Re: FiveDBU for 32/64 bits

Postby ukoenig » Wed Jun 06, 2012 11:19 am

Antonio,

could it be possible, to move changed or new Functions to
the Bottom like :

----------------------------------------------------
---------------- NEW / Changed ---------------
Function ......


because of my own changes, it is hard to find out positions, I have to replace.
At the End, it could be sorted again.

Best 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
ukoenig
 
Posts: 4043
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany

PreviousNext

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 36 guests