# Property of Four Js* # (c) Copyright Four Js 1995, 2019. All Rights Reserved. # * Trademark of Four Js Development Tools Europe Ltd # in the United States and elsewhere # # Four Js and its suppliers do not warrant or guarantee that these # samples are accurate and suitable for your purposes. Their inclusion is # purely for information purposes only. TYPE schema_rec RECORD table_name STRING, -- customer field_name STRING, -- customer_name field_type SMALLINT, -- 0 field_strtype STRING, -- CHAR(30) field_length SMALLINT -- 80 END RECORD DEFINE col_arr DYNAMIC ARRAY OF schema_rec DEFINE tab_arr DYNAMIC ARRAY OF STRING DEFINE currtable STRING --current table in combobox --a(vailable) fields DEFINE afields DYNAMIC ARRAY OF RECORD atable STRING, acol STRING END RECORD --c(hosen) fields DEFINE cfields DYNAMIC ARRAY OF RECORD ctable STRING, ccol STRING END RECORD MAIN CLOSE WINDOW screen CALL wizard() END MAIN --contains the wizard dialog build with traditional 4GL dialogs called in a loop --the common actions must be cloned into each dialog FUNCTION wizard() DEFINE i INT DEFINE state STRING CALL readTables("stores.sch") OPEN WINDOW formwizard WITH FORM "formwizard_old" CALL init_tables() OPTIONS FIELD ORDER FORM LET state="combo" WHILE state<>"exit" AND state<>"accept" CASE state WHEN "combo" LET state="left" INPUT BY NAME currtable WITHOUT DEFAULTS ATTRIBUTES(UNBUFFERED) ON CHANGE currtable CALL on_change_currtable() ON ACTION gocombo LET state="combo" EXIT INPUT ON ACTION goleft LET state="left" EXIT INPUT ON ACTION goright LET state="right" EXIT INPUT ON ACTION cancel LET state="exit" EXIT INPUT ON ACTION accept LET state="accept" EXIT INPUT END INPUT WHEN "left" LET state="right" DISPLAY ARRAY afields TO a.* ATTRIBUTES(UNBUFFERED) ON ACTION right CALL right(DIALOG) ON KEY(RIGHT) CALL right(DIALOG) ON ACTION allright CALL allright(DIALOG) ON KEY(TAB) EXIT DISPLAY ON ACTION gocombo LET state="combo" EXIT DISPLAY ON ACTION goleft LET state="left" EXIT DISPLAY ON ACTION goright LET state="right" EXIT DISPLAY ON ACTION cancel LET state="exit" EXIT DISPLAY ON ACTION accept LET state="accept" EXIT DISPLAY END DISPLAY WHEN "right" LET state="combo" DISPLAY ARRAY cfields TO c.* ATTRIBUTES(UNBUFFERED) ON ACTION left CALL left(DIALOG) ON KEY(LEFT) CALL left(DIALOG) ON ACTION allleft CALL allleft(DIALOG) ON KEY(TAB) EXIT DISPLAY ON ACTION gocombo LET state="combo" EXIT DISPLAY ON ACTION goleft LET state="left" EXIT DISPLAY ON ACTION goright LET state="right" EXIT DISPLAY ON ACTION cancel LET state="exit" EXIT DISPLAY ON ACTION accept LET state="accept" EXIT DISPLAY ON ACTION prevwiz LET state="exit" EXIT DISPLAY ON ACTION nextwiz LET state="exit" EXIT DISPLAY END DISPLAY END CASE END WHILE --we just show all chosen columns in the terminal IF state=="accept" THEN FOR i=1 TO cfields.getLength() DISPLAY sfmt("table:%1,column:%2",cfields[i].ctable,cfields[i].ccol) END FOR END IF CLOSE WINDOW formwizard END FUNCTION --fill the combobox with all table names FUNCTION init_tables() DEFINE cb ui.ComboBox DEFINE i INTEGER LET cb = ui.ComboBox.forName("formonly.currtable") IF cb IS NULL THEN CALL myerror("combobox not found") END IF FOR i=1 TO tab_arr.getLength() CALL cb.addItem(tab_arr[i],tab_arr[i]) END FOR LET currtable=tab_arr[1] CALL on_change_currtable() END FUNCTION --combo value has changed,refill the left array and omit --values of the right hand side FUNCTION on_change_currtable() DEFINE tab,col STRING DEFINE col_len,used_col_len,idx,i,j,foundUsed,tabSize INT CALL afields.clear() LET idx=0 LET col_len=col_arr.getLength() FOR i=1 TO col_len LET tab=col_arr[i].table_name LET col=col_arr[i].field_name LET used_col_len=cfields.getLength() LET foundUsed=FALSE FOR j=1 TO used_col_len IF cfields[j].ctable=tab AND cfields[j].ccol=col THEN LET foundUsed=TRUE EXIT FOR END IF END FOR IF NOT foundUsed AND tab=currtable THEN LET idx=idx+1 LET afields[idx].atable=tab LET afields[idx].acol=col END IF END FOR LET tabSize=tableSize("a") FOR i=1 TO tabSize DISPLAY "" TO a[i].acol END FOR FOR i=1 TO afields.getLength() DISPLAY afields[i].* TO a[i].* END FOR END FUNCTION --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 --move all items to the right hand side FUNCTION allright(d) DEFINE d ui.Dialog DEFINE lastC,i INT LET lastC=cfields.getLength() FOR i=1 TO afields.getLength() LET lastC=lastC+1 LET cfields[lastC].ctable=afields[i].atable LET cfields[lastC].ccol=afields[i].acol END FOR CALL afields.clear() FOR i=1 TO cfields.getLength() DISPLAY cfields[i].* TO c[i].* END FOR END FUNCTION --remove the current item from the right hand side and refill the left hand side FUNCTION left(d) DEFINE d ui.Dialog CALL cfields.deleteElement(arr_curr()) CALL on_change_currtable() END FUNCTION --remove all items from the right hand side and refill the left hand side FUNCTION allleft(d) DEFINE d ui.Dialog CALL cfields.clear() CALL on_change_currtable() END FUNCTION --read in a schema file FUNCTION readTables(schemaFile) DEFINE schemaFile STRING DEFINE ch base.channel DEFINE prevTabName STRING DEFINE sch schema_rec CALL col_arr.clear() CALL tab_arr.clear() LET ch = base.channel.create() WHENEVER ERROR CONTINUE CALL ch.openFile(schemaFile, "r") WHENEVER ERROR STOP IF STATUS!=0 THEN CALL myerror( "error: could not open schema file '"||schemaFile||"'") END IF CALL ch.setdelimiter("^") LET prevTabName=NULL WHILE ch.read(sch) IF sch.table_name.getIndexOf("sys",1)==1 THEN CONTINUE WHILE END IF LET col_arr[col_arr.getLength()+1].* = sch.* IF prevTabName IS NULL OR sch.table_name <> prevTabName THEN LET tab_arr[tab_arr.getLength()+1]=sch.table_name LET prevTabName=sch.table_name END IF END WHILE CALL ch.close() IF tab_arr.getLength()==0 THEN CALL myerror("did not find any coluns in "||schemaFile) END IF END FUNCTION FUNCTION myerror(str) DEFINE str STRING DISPLAY "ERROR:",str EXIT PROGRAM 1 END FUNCTION FUNCTION tableSize(screenRec) DEFINE screenRec STRING DEFINE nl om.NodeList DEFINE root,tab om.DomNode DEFINE doc om.DomDocument DEFINE currWinId,bufferSize INT LET root=ui.Interface.getRootNode() LET currWinId=root.getAttribute("currentWindow") LET doc =ui.Interface.getDocument() LET root=doc.getElementById(currWinId) LET nl=root.selectByPath(sfmt("//Table[@tabName=\"%1\"]",screenRec)) IF nl.getLength()>0 THEN LET tab=nl.item(1) LET bufferSize=tab.getAttribute("bufferSize") ELSE DISPLAY "can't find Table" END IF RETURN bufferSize END FUNCTION