Skip to content

IsDirty and checkneedsave()

Forums Forums SIMPOL Programming IsDirty and checkneedsave()

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #158
    JD Kromkowski
    Participant

    Not sure anymore if writing here make sense. I have a function as part of test based on the application framework to switch between two forms. (Below) Before I switch forms, I obviously need to check to see if any changes were made and save them BEFORE I switch forms. I am using checkneedsave() function. (btw, the getappwindowfromwindow is great!). This works but only “sort of”. If I have cursor in the field which was changed; it does not save the change. If I make a change and “tab” to next field or use mouse to setfocus to another field, then it does save the change. checkneedsave() uses appw.form.checkdirtyrecords() I can’t seem to actually find checkdirtyrecords() or any documention. I do see that .dirty is a property of a dataform1 and that you can “set” its state. But it is not clear to me what actually constitutes “dirty”. If I have cursor in the field which was changed and “exit” or use any of the “selects” from toolbar, the record is properly identified as dirty and the “Do you want to save” dialog from checkneedsave() comes up. Is something different happening? Does the using a menuitem or toolbar remove focus and thus enable a field (edittext) to be considered “dirty”. I suppose I could always change the focus before I call checkneedsave(), or maybe this is bug (or feature)? function ChangeForms(wxmenuitem me, type (application) app) appwindow appw appw =@ getappwindowfromwindow(getmenuitemwindow(me)) checkneedsave(appw) if sSecondForm == appw.form.filename appw.mb!data.menu!EmployeeForm.setenabled(.false) appw.mb!data.menu!DailyRecordForm.setenabled(.true) appw.openformdirect(sFirstForm,sAPPMSGTITLE) else appw.mb!data.menu!EmployeeForm.setenabled(.true) appw.mb!data.menu!DailyRecordForm.setenabled(.false) appw.openformdirect(sSecondForm,sAPPMSGTITLE) end if end function

    #1937
    Michael
    Keymaster

    On 16/05/2012 23:12, John D Kromkowski wrote:
    > Not sure anymore if writing here make sense.

    Absolutely!

    > I have a function as part of test based on the application framework to switch between two forms. (Below) Before I switch
    > forms, I obviously need to check to see if any changes were made and save them BEFORE I switch forms.
    >
    > I am using checkneedsave() function. (btw, the getappwindowfromwindow is great!). This works but only "sort of".
    >
    > If I have cursor in the field which was changed; it does not save the change. If I make a change and "tab" to next field or
    > use mouse to setfocus to another field, then it does save the change.
    >
    > checkneedsave() uses appw.form.checkdirtyrecords()

    Basically, you need to use the defer() mechanism. This will allow the system to remove focus from the field, which will fire the
    onlostfocus event which then assigns the values to the underlying control. If you look at selrec() in toolbar.sma in the
    AddressBook tutorial sample, you can see what is happening. Basically, the way this works is this:

    This technique takes advantage of the fact that in SIMPOL you don't have to pass all the parameters and the ones you don't pass
    will either be .nul or have the assigned default value. So the first time the following event handler is called, dodefer is not
    passed (because the event handling code will only pass the first two parameters at most). That gets trapped early and causes the
    defer() call to be made. As you can see, one of the requirements is to pass the wxform object. This allows the defer() function to
    call the clearfocus() method on the form, to make sure the onlostfocus will fire. It then calls deferprocessing() using
    !beginthread which inserts a 200ms delay as its first act and because it is a separate thread, the original call to selrec() has
    time to complete and exit on the main thread, which means the previous call to clearfocus() will also have time to cause the
    onlostfocus event to fire on the main thread. After the delay in the deferprocessing() thread, a call is made to the original
    function passing in the same parameters it got the first time, but with the dodefer flag set to .false.

    Using the defer() mechanism is absolutely key to not losing data in the way that you described.

    function defer(function func, type(*) mevar, type(*) ref, wxform form) information "[simpol::return::]" export
    if form !@= .nul
    form.clearfocus()
    end if
    !beginthread(deferprocessing, func, mevar, ref)
    end function

    function deferprocessing(function func, type(*) mevar, type(*) ref, integer delay=200000) information "[simpol::return::]" export
    if func !@= .nul and mevar !@= .nul
    !wait(delay)
    if ref !@= .nul
    func(mevar, ref, dodefer=.false)
    else
    func(mevar, dodefer=.false)
    end if
    end if
    end function

    function selrec(wxtool me, appwindow appw, boolean dodefer=.true)
    string op

    if dodefer
    if appw.form !@= .nul
    defer(selrec, me, appw, appw.form.currentpage.wxformpage)
    end if
    else
    appw.fastselection = .false
    if me.name == "tSelFirst"
    // … cut for brevity
    end if
    // … cut for brevity
    end if
    end function

    > I can't seem to actually find checkdirtyrecords() or any documention.

    the checkdirtyrecords() method is part of the dataform1 object so look in the databaseforms library source code.

    > I do see that .dirty is a property of a dataform1 and that you can "set" its state. But it is not clear to me what actually
    > constitutes "dirty".

    In that case, .dirty refers to the form itself having been changed, like in the form designer, or programmatically.

    > If I have cursor in the field which was changed and "exit" or use any of the "selects" from toolbar, the record is properly
    > identified as dirty and the "Do you want to save" dialog from checkneedsave() comes up.

    Because they use the defer() mechanism.

    > Is something different happening? Does the using a menuitem or toolbar remove focus and thus enable a field (edittext) to be
    > considered "dirty".
    >
    > I suppose I could always change the focus before I call checkneedsave(), or maybe this is bug (or feature)?
    >
    > function ChangeForms(wxmenuitem me, type (application) app) appwindow appw appw =@
    > getappwindowfromwindow(getmenuitemwindow(me)) checkneedsave(appw) if sSecondForm == appw.form.filename
    > appw.mb!data.menu!EmployeeForm.setenabled(.false) appw.mb!data.menu!DailyRecordForm.setenabled(.true)
    > appw.openformdirect(sFirstForm,sAPPMSGTITLE) else appw.mb!data.menu!EmployeeForm.setenabled(.true)
    > appw.mb!data.menu!DailyRecordForm.setenabled(.false) appw.openformdirect(sSecondForm,sAPPMSGTITLE) end if end function

    Not needed, just see above and use the same defer() approach that the menu and toolbar event handlers use.

    This does mean that when debugging, the second time through you will need to switch to the correct thread before anything works.

    Ciao, Neil

    #1940
    JD Kromkowski
    Participant

    going to take some time for me to digest this.

Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.