data aware form master form sub form How can a complex form be created? /* get the service manager */ xContext = UNO.connect() --connect to server and retrieve the XContext object xMcf = xContext~getServiceManager -- retrieve XMultiComponentFactory oDesktop = UNO.createDesktop() -- get the UNO Desktop service object /* get componentLoader interface */ xComponentLoader = oDesktop~{%see com.sun.star.frame.XDesktop%XDesktop}~{%see com.sun.star.frame.XComponentLoader%XComponentLoader} /* create a new Writer file */ url = "private:factory/swriter" xComponent = xComponentLoader~loadComponentFromURL(- url, "_blank", 0, .UNO~noProps) /* Save some objects which are often used in the following routines into the directory object '.local'. So they can be accessed from the whole Rexx program like global variables */ .local~xMcf = xMcf .local~xContext = xContext .local~{%see com.sun.star.lang.XComponent%xComponent} = xComponent /************************** create form components **************************/ label1 = createControlAndShape("FixedText", 25, 6, 5, 5) label1~setPropertyValue("Label", "Customer ID:") --assign the display-text textfield1 = createControlAndShape("TextField", 25, 6, 35, 5) textfield1~setPropertyValue("DataField", "cid") --assign to a field in the db textfield1~setPropertyValue("Name", "cid_textfield") --assign a name label2 = createControlAndShape("FixedText", 25, 6, 5, 20) label2~setPropertyValue("Label", "Customer Name:") --assign the display-text textfield21 = createControlAndShape("TextField", 25, 6, 35, 20) textfield21~setPropertyValue("DataField", "firstname") textfield21~setPropertyValue("Name", "firstname_textfield") --assign a name textfield22 = createControlAndShape("TextField", 25, 6, 70, 20) textfield22~setPropertyValue("DataField", "lastname") textfield22~setPropertyValue("Name", "lastname_textfield") --assign a name label3 = createControlAndShape("FixedText", 25, 6, 5, 35) label3~setPropertyValue("Label", "Date of Birth:") --assign the display-text textfield3 = createControlAndShape("TextField", 25, 6, 35, 35) textfield3~setPropertyValue("DataField", "birthdate") textfield3~setPropertyValue("Name", "birthdate_textfield") --assign a name /************************** bind MasterForm to the database *****************/ /* get the parent of any control model inserted previously to obtain the control model of the form, this form was automaticaly created while inserting the first control model of a form component. The masterForm is like every form component a 'XPropertySet' */ masterForm = label1~{%see com.sun.star.container.XChild%XChild}~getParent~{%see com.sun.star.beans.XPropertySet%XPropertySet} masterForm~setPropertyValue("DataSourceName", "mysql-test") masterForm~setPropertyValue("CommandType", box(- "int",bsf.getStaticValue("{%see com.sun.star.sdb.CommandType}", "COMMAND"))) masterForm~setPropertyValue("Command", "select * from test.customer") masterForm~setPropertyValue("Name", "customers_form") /************************** create sub form (sales) *************************/ /* masterContainer is an XIndexContainer */ masterContainer = masterForm~{%see com.sun.star.container.XIndexContainer%XIndexContainer} /* create a new form */ salesForm = .xMcf~createInstanceWithContext(- "{%see com.sun.star.form.component.DataForm}", xContext) /* insert it into the parentContainer */ masterContainer~insertByIndex(masterContainer~getCount, salesForm ) salesForm~{%see com.sun.star.beans.XPropertySet%XPropertySet}~setPropertyValue("Name", "sales_form") /************************** bind SubForm to the database ********************/ /* salesFormProps is a XPropertySet */ salesFormProps = salesForm~{%see com.sun.star.beans.XPropertySet%XPropertySet} salesFormProps~setPropertyValue("DataSourceName", "mysql-test") salesFormProps~setPropertyValue("CommandType", box("int",bsf.getStaticValue(- "{%see com.sun.star.sdb.CommandType}", "COMMAND"))) command = "select * from test.sales where cid = :c" salesFormProps~setPropertyValue("Command",command) /************************** establish masterForm-SubForm connection**********/ strArray = bsf.createArray("String.class", 1) strArray[1] = "cid" salesFormProps~setPropertyValue("MasterFields", strArray) strArray[1] = "c" salesFormProps~setPropertyValue("DetailFields", strArray) /* now create the grid model and insert it into the salesContainer*/ /* get the XIndexContainer interface of the salesForm salesContainer is a XIndexContainer */ salesContainer = salesForm~{%see com.sun.star.container.XIndexContainer%XIndexContainer} call createControlAndShape "GridControl", 162, 40, 5, 50, salesContainer gridControl = result gridControl~setPropertyValue("Name", "sales_table") call newGridColumn gridControl, "TextField", "sid", "invoice number" call newGridColumn gridControl, "ListBox", "name", "product name" productName = result --save the 'product name' column to set some more props /* initialize the 'product name' ListBox to provide a choice of product names*/ productName~setPropertyValue( "ListSourceType", bsf.getConstant(- "{%see com.sun.star.form.ListSourceType}","SQL")) productName~setPropertyValue("BoundColumn", box("sh","1")) sListSource = "SELECT product.name, product.name FROM test.product" strArray[1] = sListSource productName~setPropertyValue( "ListSource", strArray) call newGridColumn gridControl, "TextField", "quantity", "quantity" /* switch to live mode */ call toggleFormDesignMode say "Form Document created!" /* save form and close document*/ xComponent~{%see com.sun.star.frame.XStorable%XStorable}~storeAsURL(- uno.ConvertToURL("c:/odbfiles/shop_form.odt"), .UNO~noProps) xComponent~{%see com.sun.star.sdbc.XCloseable%XCloseable}~close(.true) ::requires UNO.cls -- get UNO support ---------------------------------ROUTINEs------------------------------------ ----------------------------------------------------------------------------- /* routine switches between the life-mode and the design mode */ ::routine toggleFormDesignMode URL = bsf.import('{%see com.sun.star.util.URL}') aToggleURL = bsf.createArray(URL, 1) aToggleURL[1] = URL~new aToggleURL[1]~Complete = ".uno:SwitchControlDesignMode" --need an URLTransformer frameDesktop = .xMcf~createInstanceWithContext(- "{%see com.sun.star.util.URLTransformer}",.xContext) frameDesktop~{%see com.sun.star.util.XURLTransformer%XURLTransformer}~parseStrict(aToggleURL) /* get the XController interface of the controller service */ xController = .xComponent~{%see com.sun.star.xforms.XModel%XModel}~getCurrentController~{%see com.sun.star.frame.XController%XController} --go get the dispatch provider of it's frame xDispatchProvider = xController~getFrame~{%see com.sun.star.frame.XDispatchProvider%XDispatchProvider} xDispatch = xDispatchProvider~queryDispatch( aToggleURL[1],"", 0 ) xDispatch~dispatch( aToggleURL[1], .UNO~noProps ) ----------------------------------------------------------------------------- /* creates a control shape, together with a control model, and inserts them into the document model */ /* ARG(1) - name: String sQualifiedComponentName (f.e. TextField) ARG(2) - width: int Size ARG(3) - height: int Size ARG(4) - x: int Position - X-axis ARG(5) - y: int Position - Y-axis ARG(6) - parent: XIndexContainer xParentForm OPTIONAL */ ::routine createControlAndShape use arg arg_name, arg_width, arg_height, arg_x, arg_y, arg_parent /********** create and initialize the shape **********/ /* let the document create a shape */ xDocAsMultiServiceFactory = .xComponent~{%see com.sun.star.lang.XMultiServiceFactory%XMultiServiceFactory} xControlShape = xDocAsMultiServiceFactory~createInstance(- "{%see com.sun.star.drawing.ControlShape}")~{%see com.sun.star.drawing.XControlShape%XControlShape} /* set position and size of the shape */ xControlShape~setSize(.bsf~new(- "{%see com.sun.star.awt.Size}", arg_width*100, arg_height*100)) --in 100th/mm xControlShape~setPosition(.bsf~new(- "{%see com.sun.star.awt.Point}", arg_x*100, arg_y*100)) /* adjust the anchor so that the control is tied to the page */ xPropertySet = xControlShape~{%see com.sun.star.beans.XPropertySet%XPropertySet} xPropertySet~setPropertyValue("AnchorType", bsf.getConstant(- "{%see com.sun.star.text.TextContentAnchorType}", "AT_PARAGRAPH")) /********** create a control model **********/ /* create the form component (the model of a form control) */ sQualifiedComponentName = "{%see com.sun.star.form.component.}"arg_name xControlModel = .xMcf~createInstanceWithContext(- sQualifiedComponentName,.xContext)~{%see com.sun.star.awt.XControlModel%XControlModel} /* if "ARG(6):xParentForm" is given insert the form component into the appropriate location of the form hierarchy if the argument is not given the form component is automatically inserted into the root form */ IF arg_parent <> "ARG_PARENT" THEN DO arg_parent~insertByIndex( arg_parent~getCount, xControlModel ) END /********** announce the control model to the shape **********/ /* knitt them */ xControlShape~setControl(xControlModel) /******* insert the shape into the shapes collection of a draw page ********/ /* add the shape to the shapes collection of the document */ xDrawPageSupplier = .xComponent~{%see com.sun.star.drawing.XDrawPageSupplier%XDrawPageSupplier} xDrawPageSupplier~getDrawPage~{%see com.sun.star.drawing.XShapes%XShapes}~add(xControlShape) /* return the XPropertySet interface of the ControlModel. With it it's possible to make several adjustments at the ControlModel */ return xControlModel~{%see com.sun.star.beans.XPropertySet%XPropertySet} ----------------------------------------------------------------------------- /* creates a new Column inside a 'GridControl' */ /* ARG(1) - container: grid control ARG(2) - name: String componentName ARG(3) - field: String dataField ARG(4) - label: String label */ ::routine newGridColumn use arg arg_container, arg_factory, arg_name, arg_field, arg_label /* query for the container to insert columns into */ xIndexContainer = arg_container~{%see com.sun.star.container.XIndexContainer%XIndexContainer} /* query for the factory for creating the column models */ xGridColumnFactory = arg_container~{%see com.sun.star.form.XGridColumnFactory%XGridColumnFactory} /* create a new column */ newColumn = xGridColumnFactory~createColumn(arg_factory) xPropertySet= newColumn~{%see com.sun.star.beans.XPropertySet%XPropertySet} xPropertySet~setPropertyValue("DataField", arg_name) xPropertySet~setPropertyValue("Label", arg_field) /* insert the column */ xIndexContainer~insertByIndex(xIndexContainer~getCount, newColumn) return xPropertySet --return the created column