Control Models and Shapes

From Apache OpenOffice Wiki
Jump to: navigation, search



There is more to know about form components in a document.

From Shapes, you already know about shapes. They are also part of a document model. The control shapes, com.sun.star.drawing.ControlShape are made to be tied to control models. They are specialized to fully integrate form control models into a document.

In theory, there can be a control shape without a model tied to it, or a control model which is part of the form component hierarchy, but not associated with any shape. In the first case, an empty shape is displayed in the document view. In the second case, you see nothing. It is possible to have a shape which is properly tied to a control model, but the control model is not part of the form component hierarchy. The model can not interact with the rest of the form layer. For example, it is unable to take advantage of its data awareness capabilities.

Documentation caution.png The user interface of Apache OpenOffice does not allow the creation of orphaned objects, but you can create them using the API. When dealing with controls through the API, ensure that there is always a valid relationship between forms, control models, and shapes.

A complete object structure in a document model with respect to the components relevant for our form layer looks the following:

A complete object structure

Programmatic Creation of Controls

As a consequence from the previous paragraph, we now know that to insert a form control, we need to insert a control shape and control model into the document's model.

The following code fragment accomplishes that:

  /** creates a control in the document
 
      <nowiki><p>Note that <em>control<em> here is an incorrect terminology. What the method really does is
      it creates a control shape, together with a control model, and inserts them into the document model.
      This will result in every view to this document creating a control described by the model-shape
      pair.</p></nowiki>
 
      @param sFormComponentService
          the service name of the form component to create, e.g. "TextField"
      @param nXPos
          the abscissa of the position of the newly inserted shape
      @param nXPos
          the ordinate of the position of the newly inserted shape
      @param nWidth
          the width of the newly inserted shape
      @param nHeight
          the height of the newly inserted shape
      @return
          the property access to the control's model
   */
  public static XPropertySet createControlAndShape(String sFormComponentService, int nXPos,
          int nYPos, int nWidth, int nHeight) throws java.lang.Exception {
      // let the document create a shape
      XMultiServiceFactory xDocAsFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(
          XMultiServiceFactory.class, s_aDocument);
       XControlShape xShape = (XControlShape)UnoRuntime.queryInterface(XControlShape.class,
          xDocAsFactory.createInstance("com.sun.star.drawing.ControlShape"));
 
      // position and size of the shape
      xShape.setSize(new Size(nWidth * 100, nHeight * 100));
      xShape.setPosition(new Point(nXPos * 100, nYPos * 100));
 
      // and in a OOo Writer doc, the anchor can be adjusted
      XPropertySet xShapeProps = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xShape);
      TextContentAnchorType eAnchorType = TextContentAnchorType.AT_PAGE;
      if (classifyDocument(s_aDocument) == DocumentType.WRITER) {
          eAnchorType = TextContentAnchorType.AT_PARAGRAPH;
      }
      xShapeProps.setPropertyValue("AnchorType", eAnchorType);
 
      // create the form component (the model of a form control)
      String sQualifiedComponentName = "com.sun.star.form.component." + sFormComponentService;
      XControlModel xModel = (XControlModel)UnoRuntime.queryInterface(XControlModel.class,
          s_aMSF.createInstance(sQualifiedComponentName));
 
      // knitt them
      xShape.setControl(xModel);
 
      // add the shape to the shapes collection of the document
      XShapes xDocShapes = (XShapes)UnoRuntime.queryInterface(XShapes.class, getDocumentDrawPage());
      xDocShapes.add(xShape);
 
      // and outta here with the XPropertySet interface of the model
      XPropertySet xModelProps = (XpropertySet)UnoRuntime.queryInterface(
          XpropertySet.class, xModel);
      return xModelProps;
  }

Looking at the example above, the basic procedure is:

  • create and initialize a shape
  • create a control model
  • announce the control model to the shape
  • insert the shape into the shapes collection of a draw page

The above does not mention inserting the control model into the form component hierarchy, which is a contradiction of our previous discussion. We have previously said that every control model must be part of this hierarchy to prevent corrupted documents, but it is not harmful.

In every document, when a new control shape is inserted into the document, through the API or an interaction with a document's view, the control model is checked if it is a member of the model hierarchy. If it is not, it is automatically inserted. Moreover, if the hierarchy does not exist or is incomplete, for example, if the draw page does not have a forms collection, or this collection does not contain a form, this is also corrected automatically.

With the code fragment above applied to a new document, a logical form is created automatically, inserted into the forms hierarchy, and the control model is inserted into this form.

Documentation note.png Note that this is an implementation detail. Internally, there is an instance listening at the page's shapes, that reacts upon insertions. In theory, there could be other implementations of Apache OpenOffice API that do not contain this mechanism. In practice, the only known implementation is Apache OpenOffice.
Documentation caution.png Note that the order of operations is important. If you insert the shape into the page's shape collection, and tie it to its control model after, the document would be corrupted: Nobody would know about this new model then, and it would not be inserted properly into the form component hierarchy, unless you do this.

You may have noticed that there is nothing about the view. We only created a control model. As you can see in the complete example for this chapter, when you have an open document, and insert a model and a shape, a control (the visual representation) is also created or else you would not see anything that looks like a control.

The control and model have a model-view relationship. If the document window is open, this window is the document view. If the document or the model is modified by inserting a control model, the view for every open view for this document reacts appropriately and creates a control as described by the model. The DefaultControl property describes the service to be instantiated when automatically creating a control for a model.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages