Checking changes in folder

Checking changes in folder

Postby Marco Turco » Sat Jun 28, 2008 10:33 am

Hi,
I need to check if the value of some controls (get, combobox..) in a folder has changed in order to request a confirm to the customer before exit.

Due the outlook interface I am using the customer can loose the data simply selecting another record so a confirm exit is needed.

See image at www.softwarexp.co.uk/beta/sample.jpg

I made the following routine to check it that providing the oFld as parameter will scan all GET controls inside and check the ::oGet:Changed() value.

Function CheckChanged(oFld)
local aArray,i,n,nPrompts,lChanged

lChanged:=.f.
nPrompts:=len(oFld:aPrompts)

for n:=1 to nPrompts
aArray:=oFld:aDialogs[n]:aControls
for i:=1 to len(aArray)
if oFld:aDialogs[n]:aControls[i]:Classname="TGET"
if oFld:aDialogs[n]:aControls[i]:oGet:Changed()
lChanged:=.t. && has changed
exit
endif
endif
next
next
return(lChanged)

The problem is that I only can check changes in GET controls but I need to check the combobox and tcbrowse also.
Any ideas to make this ? As I know the ::Changed() data is only applied on GET controls.

Thanks iin advance.
Best Regards,

Marco Turco
SOFTWARE XP LLP
User avatar
Marco Turco
 
Posts: 858
Joined: Fri Oct 07, 2005 12:00 pm
Location: London

Postby driessen » Sat Jun 28, 2008 12:50 pm

Marco,

This is the way I do this check :
Code: Select all  Expand view  RUN
LOCAL cFIELD1, oFIELD1
LOCAL cFIELD2, oFIELD2
....
cFIELD1 := oFIELD1 := FILE->FIELD1
cFIELD2 := oFIELD2 := FILE->FIELD2
....
DEFINE DIALOG ....
....
REDEFINE GET cFIELD1 ID 101 OF ....
REDEFINE CHECKBOX cFIELD2 ID 102 OF ....
....
ACTIVATE DIALOG ....

IF cFIELD1 = oFIELD1 .AND. cFIELD2 = oFIELD2
    .... data has not been changed ....
ELSE
    .... data has been changed ....
ENDIF


It doesn't matter what the kind of cFIELD1 or cFIELD2 is : a GET, a CHECKBOX, a RADIO BUTTON, ...

It always works.

Good luck
Regards,

Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 24.07 - Harbour 3.2.0 (February 2024) - xHarbour Builder (January 2020) - Bcc773
User avatar
driessen
 
Posts: 1422
Joined: Mon Oct 10, 2005 11:26 am
Location: Genk, Belgium

Postby Marco Turco » Sat Jun 28, 2008 2:33 pm

Hi Driessen,
you are right but I have a lot of variables to check so I would like find an automatic check without manage each control.
Best Regards,

Marco Turco
SOFTWARE XP LLP
User avatar
Marco Turco
 
Posts: 858
Joined: Fri Oct 07, 2005 12:00 pm
Location: London

Postby Antonio Linares » Sat Jun 28, 2008 3:06 pm

Marco,

Do you use a Class TDataBase for fields editing ?

If yes, then you can simply check oDataBase:Modified() :-)
regards, saludos

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

Postby Marco Turco » Sat Jun 28, 2008 3:49 pm

Antonio Linares wrote:Marco,

Do you use a Class TDataBase for fields editing ?

If yes, then you can simply check oDataBase:Modified() :-)


Unfortunately that data file is not in a dbf format.
Best Regards,

Marco Turco
SOFTWARE XP LLP
User avatar
Marco Turco
 
Posts: 858
Joined: Fri Oct 07, 2005 12:00 pm
Location: London

Postby Antonio Linares » Sat Jun 28, 2008 3:57 pm

Marco,

If you use locals, then I am thinking that we could implement an easy and very powerfull solution :-)

if you keep the locals together, then we could step through them and build an array from them, and later on, compare the original values with the array. Thats what Class TDataBase does basically.

There are some functions in [x]Harbour to step through the local variables by their position (order) and no by its name. So it can be done :-)
regards, saludos

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

Postby Antonio Linares » Sat Jun 28, 2008 6:55 pm

Marco,

Here you have a working sample. It can be very much simplified, as I have included some code so testers can understand the virtual machine stack structure. Also the "locals" checker code could be placed into an external function:
Code: Select all  Expand view  RUN
#include "FiveWin.ch"

function Main()

   Test( "one", "two", "three" )

return nil

function Test( x, y, z )

   local local1 := "first", local2 := "second", aBegin := HB_DBG_VMSTKLLIST(), aEnd, n
   
   MsgInfo( "Name of the function: " + aBegin[ 1 ] )
   MsgInfo( "Is this a function or a method ? " + If( aBegin[ 2 ] != nil, "Method", "function" ) )

   for n = 1 to PCount()
      MsgInfo( "parameter " + AllTrim( Str( n ) ) + ": " + cValToChar( aBegin[ 2 + n ] ) )
   next   
   
   n++
   while n < Len( aBegin ) - 1
      MsgInfo( "local " + AllTrim( Str( n - PCount() - 1 ) ) + ": " + cValToChar( aBegin[ n + 1 ] ) )
      n++
   end   

   local2 := "changed!" // we change a local value

   aEnd = HB_DBG_VMSTKLLIST()
   for n = PCount() + 1 to Len( aEnd ) - 1
      if aBegin[ n ] != aEnd[ n ]
         MsgInfo( "local " + AllTrim( Str( n - PCount() - 2 ) ) + " has changed!" )
      endif
   next
         
return nil
regards, saludos

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

Postby Antonio Linares » Sat Jun 28, 2008 7:04 pm

A simplified version:
Code: Select all  Expand view  RUN
#include "FiveWin.ch"

function Main()

   Test( "one", "two", "three" )

return nil

function Test( x, y, z )

   local local1 := "first", local2 := "second", aBegin := HB_DBG_VMSTKLLIST(), aEnd, n

   // your code...
   
   local2 := "changed!" // we change a local value
   
   // Now we check for changes in locals variables

   aEnd = HB_DBG_VMSTKLLIST()
   for n = PCount() + 1 to Len( aEnd ) - 1
      if aBegin[ n ] != aEnd[ n ]
         MsgInfo( "local " + AllTrim( Str( n - PCount() - 2 ) ) + " has changed!" )
      endif
   next
         
return nil
regards, saludos

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

Postby demont frank » Sun Jun 29, 2008 8:18 am

Maybe this will work , also when folders are nested

Frank

Code: Select all  Expand view  RUN

#include "FiveWin.ch"
#include "common.ch"

function Main()

   local oDlg, oFld
LOCAL Num := 100
LOCAL MemInpVal[0]
LOCAL n := 1 , oRadMenu , oGet
   DEFINE DIALOG oDlg RESOURCE "test"

   REDEFINE FOLDER oFld ID 110 OF oDlg ;
      DIALOGS "dlg1", "dlg2" PROMPTS "One", "Two"
   REDEFINE GET oGet VAR Num OF oFld:aDialogs[1] ID 100
   REDEFINE RADIO oRadMenu VAR n ID 110 , 120 OF oFld:aDialogs[2]
   
    REDEFINE BUTTON ID 120 OF oDlg ACTION CompInputValue(oDlg , @MemInpVal )

   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT (SaveInputValue(oDlg , @MemInpVal))

return nil

PROC SaveInputValue(oDlg , Arr)
*************************
LOCAL el , elem , oRadMenu[0]
FOR EACH el IN oDlg:aControls
  IF el:ClassName == "TFOLDER"
    FOR EACH elem IN el:aDialogs                               
      SaveInputValue(elem , @Arr)
    NEXT
  ELSE
    IF el:ClassName = "TRADIO"
      IF ASCAN(oRadMenu , {|j|j==el:oRadMenu}) == 0
        AADD(oRadMenu , el:oRadMenu)
        AADD(Arr,el:oRadMenu:nOption())
      END
    ELSEIF __ObjHasMethod(el,"VarGet")
    // Maybe better : IF el:ClassName IN {"TGET","TCHECK", ......}
       AADD(Arr,el:VarGet()   )
     END
  END
NEXT
RETURN
**********************************************************************************************
FUNC CompInputValue(oDlg , MemInpVal )
***************************************
LOCAL Arr[0] , i
LOCAL lOk := .T.
SaveInputValue(oDlg,@Arr)
FOR i := 1 TO Len(MemInpVal)
  IF Arr[i] <> MemInpVal[i]
    lOk := .F.
    EXIT   
  END
NEXT
RETURN lOk
************************************************************
Test DIALOG 19, 47, 233, 124
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "FiveWin Folders"
{
CONTROL "", 110, "SysTabControl32", 0 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 4, 5, 225, 99
PUSHBUTTON "&OK", 120, 98, 108, 37, 14
}

dlg1 DIALOG 18, 18, 205, 80
STYLE WS_CHILD | 4
{
LTEXT    "Number : ", 90, 10 , 2 , 40 , 10 //, WS_BORDER | WS_TABSTOP
EDITTEXT 100, 37 , 2, 20 , 10, WS_BORDER | WS_TABSTOP
CONTROL "First", 110, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 37, 30, 28, 12
}

dlg2 DIALOG 18, 18, 205, 80
STYLE WS_CHILD | 4
{
CONTROL "Second", 110, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 37, 30, 28, 12
CONTROL "Third", 120, "BUTTON", BS_AUTORADIOBUTTON | WS_TABSTOP, 37, 43, 28, 12
}

demont frank
 
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Postby demont frank » Sun Jun 29, 2008 6:23 pm

Antonio

In many cases we are using arrays , or why not , nested arrays , or arrays are mixted with others.

In this case i suppose that this code is much more complicated and has to
be changed .

Frank

Antonio Linares wrote:A simplified version:
Code: Select all  Expand view  RUN
#include "FiveWin.ch"

function Main()

   Test( "one", "two", "three" )

return nil

function Test( x, y, z )

   local local1 := "first", local2 := "second", aBegin := HB_DBG_VMSTKLLIST(), aEnd, n

   // your code...
   
   local2 := "changed!" // we change a local value
   
   // Now we check for changes in locals variables

   aEnd = HB_DBG_VMSTKLLIST()
   for n = PCount() + 1 to Len( aEnd ) - 1
      if aBegin[ n ] != aEnd[ n ]
         MsgInfo( "local " + AllTrim( Str( n - PCount() - 2 ) ) + " has changed!" )
      endif
   next
         
return nil
demont frank
 
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Postby Marco Turco » Tue Jul 01, 2008 9:20 am

Hi Frank,
your code is the easyest solution for my case.

Thanks to all for the tips.
Best Regards,

Marco Turco
SOFTWARE XP LLP
User avatar
Marco Turco
 
Posts: 858
Joined: Fri Oct 07, 2005 12:00 pm
Location: London


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 63 guests