Commit inicial: fuentes MBS ERP (Genero 6) + .gitignore + docs/SETUP_PC_MBS.md
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
Form wizard
|
||||
-----------
|
||||
|
||||
This is an example to mimic the main component of the Microsoft Access form wizard, the dialog to choose which database columns should be handled in the generated form.
|
||||
It turned out that it is pretty easy to mimic with the help of the multiple dialogs; it behaves exactly like the original dialog (with the same logic behind and all Keyboard shortcuts).
|
||||
The code to do this is pretty short and readable.
|
||||
This dialog is used in the $FGLDIR/demo/tools/fglped program to generate a form from a list of chosen columns.
|
||||
|
||||
formwizard_old
|
||||
This example shows what you would have to do (theoretically) to program a similar dialog in 4GL without multiple dialogs available. As you can see in the wizard() function, 3 tradional dialogs are called in a loop and a lot of actions are needed to jump from one dialog to the other. 3 additional buttons are inside the form to leave the current active dialog and jump to a different dialog...pure headache!
|
||||
Unfortunately the GDC by default renders non-active tables in the same way as active tables, so the end user may think that he could click on a table and edit there; but, bummer, you must use the "Edit Left/Right" button or <Tab> to leave the current active table (Shift-Tab is not even possible).
|
||||
This example also shows why it is not sufficient to add a trigger like
|
||||
ON OTHERTABLECLICKED (demanded by a lot of our customers).
|
||||
Although it makes the "Edit Left/Right" button unnecessary, it still forces you to write such a big state loop of traditional dialogs.
|
||||
|
||||
Further Differences
|
||||
-------------------
|
||||
If you look at the code in formwizard.4gl and formwizard_old.4gl there are also differences in performing the actions.
|
||||
|
||||
|
||||
FUNCTION right(d) --multiple dialog variant
|
||||
DEFINE d ui.Dialog
|
||||
DEFINE idx,lastC INT
|
||||
--get index of the left array; cannot use arr_curr() here because arr_curr()
|
||||
--returns the index of the current active row in the current focused table
|
||||
--which is not necessarily the right hand side array
|
||||
--the "right" action is always active regardless of the focus
|
||||
LET idx = d.getCurrentRow("a")
|
||||
LET lastC=cfields.getLength()+1
|
||||
LET cfields[lastC].ctable=afields[idx].atable
|
||||
LET cfields[lastC].ccol=afields[idx].acol
|
||||
CALL afields.deleteElement(idx)
|
||||
--set the current line to the last index
|
||||
CALL d.setCurrentRow("c",lastC)
|
||||
END FUNCTION
|
||||
|
||||
You may also note that you don't need to refresh the arrays on the screen; this is done with the ATTRIBUTES(UNBUFFERED) flag of the entire dialog. Since all arrays are active, you won't need to refresh one of them manually.
|
||||
Please note that you can do this only for DISPLAY ARRAY; for INPUT ARRAY it is strongly recommended that you don't manipulate the bound arrays with the array methods (deleteElement(), insertElement()) because this conflicts with the built-in triggers of INPUT ARRAY.
|
||||
|
||||
Now the "right" function from the formwizard_old example:
|
||||
|
||||
--move the current item to the right hand side and delete it on the left hand side
|
||||
FUNCTION right(d)
|
||||
DEFINE d ui.Dialog
|
||||
DEFINE idx,lastC,i INT
|
||||
LET idx = arr_curr()
|
||||
LET lastC=cfields.getLength()+1
|
||||
LET cfields[lastC].ctable=afields[idx].atable
|
||||
LET cfields[lastC].ccol=afields[idx].acol
|
||||
CALL afields.deleteElement(idx)
|
||||
FOR i=1 TO cfields.getLength()
|
||||
DISPLAY cfields[i].* TO c[i].*
|
||||
END FOR
|
||||
END FUNCTION
|
||||
|
||||
The "right" action is only active if the focus is inside the left hand side array; that's why it's possible to use arr_curr(). At the end of the function we need to redisplay the right hand side array, because it's not active (we are in a DISPLAY ARRAY of the left hand side).
|
||||
Reference in New Issue
Block a user