Commit inicial: fuentes MBS ERP (Genero 6) + .gitignore + docs/SETUP_PC_MBS.md

This commit is contained in:
2026-08-18 20:59:52 -04:00
commit 454973e269
5978 changed files with 2664094 additions and 0 deletions
+56
View File
@@ -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).