see also gui.htm
This document describes the PowerPlant interface for OOFILE.
The PowerPlant application structure follows the generic structure described in gui.htm of dbEditHelper and dbBrowseHelper classes, coordinated with a single dbGUI per dbTable.
The first thing to remember is that we have a double-buffering situation. The edit controls have their own internal storage, which is what the user edits. The second level of buffering is the loaded record which retains the "original" value of each field.
We thus need to copy from edit control to record, then save the record to disk, before the changes are permanent.
This situation is complicated by the need to have user-defined calculated fields displayed on screen. If we just copy values back on leaving the screen, the calculations will always be performed on the old values. eg: if we enter BirthDate, an Age calculated field will not be updated to reflect the new value in the control, but keep calculating from the original BirthDate field value.
To cope with such situations, OOFILE copies the value back from the fields on exit. Thus the dbTable's fields in memory reflect the values in the edit controls, apart from the current field in which the user is typing.
The copying is achieved by having a concrete instance of a dbFieldLink for each pair of database field and edit control. These lightweight controls know how to map the contents of the field to and from the edit control. The time to copy is driven by the dbLinkDirtier classes described below.
On creation, each dbFieldLink adds an attachment to the edit control that will respond to appropriate actions. We have to add our own mechanism as the PowerPlant controls lack any "dirty" tracking mechanism. The attachment has other uses as described below.
A dbEditLinkDirtier will respond to any typing other than arrow keys or page-up/down, as well as the Cut, Paste and Clear menus commands. It is attached to classes such as LEditField and LTextEdit. It detects changes in fields by msg_Click and cmd_TabSelect which indicate we should check if the current dirtier is the one noted as being the current field.
For other panes, the default attachment is dbClickLinkDirtier which just responds to a click. The act of clicking on such controls as a checkbox, radio button etc. indicates possibly departing the previous field.
When a control is left, its value is compared with the current one in the dbField. If they differ, the value is copied back to the dbField and the field marked as dirty.
The dbEditHelper triggers a leaveLink for the current control when we attempt to leave the record.
The attachment used to detect modification of a field is also used to lock it. With edit controls, we want to allow for copying and therefore selection of the text so can't just disable the pane. Instead we must intercept all other actions that would change the content.
The dbEditLinkDirtier therefore checks the status of the dbFieldLink to see if it is set to read only, and thus decides what actions to allow.
The dbClickLinkDirtier will enable or disable the pane, depending on the read-only state. This allows you to change the state of the screen in response to a user action.