1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 import com.sun.star.uno.UnoRuntime;
28 
29 import com.sun.star.beans.XPropertySet;
30 import com.sun.star.beans.XPropertySetInfo;
31 import com.sun.star.container.XIndexContainer;
32 import com.sun.star.container.XIndexAccess;
33 import com.sun.star.lang.XMultiServiceFactory;
34 import com.sun.star.drawing.XControlShape;
35 import com.sun.star.drawing.XShapes;
36 import com.sun.star.awt.Size;
37 import com.sun.star.awt.Point;
38 import com.sun.star.awt.XControlModel;
39 import com.sun.star.text.TextContentAnchorType;
40 import com.sun.star.drawing.XDrawPage;
41 
42 /**
43  *
44  * @author  fs@openoffice.org
45  */
46 public class FormLayer
47 {
48     private DocumentHelper  m_document;
49     private int             m_insertPage;
50 
51     /* ------------------------------------------------------------------ */
52     /** Creates a new instance of FormLayer */
53     public FormLayer( DocumentHelper _document )
54     {
55         m_document = _document;
56         m_insertPage = -1;
57     }
58 
59     /* ------------------------------------------------------------------ */
60     /** sets the page which is to be used for subsequent insertions of controls/shapes
61      */
62     void setInsertPage( int page )
63     {
64         m_insertPage = page;
65     }
66 
67     /* ------------------------------------------------------------------ */
68     /** retrieves the page which is to be used for subsequent insertions of controls/shapes
69      */
70     final int getInsertPage( )
71     {
72         return m_insertPage;
73     }
74 
75     /* ------------------------------------------------------------------ */
76     /** creates a control in the document
77 
78         <p>Note that <em>control<em> here is an incorrect terminology. What the method really does is
79         it creates a control shape, together with a control model, and inserts them into the document model.
80         This will result in every view to this document creating a control described by the model-shape pair.
81         </p>
82 
83         @param sFormComponentService
84             the service name of the form component to create, e.g. "TextField"
85         @param nXPos
86             the abscissa of the position of the newly inserted shape
87         @param nXPos
88             the ordinate of the position of the newly inserted shape
89         @param nWidth
90             the width of the newly inserted shape
91         @param nHeight
92             the height of the newly inserted shape
93         @param xParentForm
94             the form to use as parent for the newly create form component. May be null, in this case
95             a default parent is chosen by the implementation
96         @return
97             the property access to the control's model
98     */
99     protected XPropertySet createControlAndShape( String sFormComponentService, int nXPos,
100         int nYPos, int nWidth, int nHeight, XIndexContainer xParentForm ) throws java.lang.Exception
101     {
102         // let the document create a shape
103         XMultiServiceFactory xDocAsFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(
104             XMultiServiceFactory.class, m_document.getDocument() );
105         XControlShape xShape = (XControlShape)UnoRuntime.queryInterface( XControlShape.class,
106             xDocAsFactory.createInstance( "com.sun.star.drawing.ControlShape" ) );
107 
108         // position and size of the shape
109         xShape.setSize( new Size( nWidth * 100, nHeight * 100 ) );
110         xShape.setPosition( new Point( nXPos * 100, nYPos * 100 ) );
111 
112         // adjust the anchor so that the control is tied to the page
113         XPropertySet xShapeProps = UNO.queryPropertySet( xShape );
114         TextContentAnchorType eAnchorType = TextContentAnchorType.AT_PARAGRAPH;
115         xShapeProps.setPropertyValue( "AnchorType", eAnchorType );
116 
117         // create the form component (the model of a form control)
118         String sQualifiedComponentName = "com.sun.star.form.component." + sFormComponentService;
119         XControlModel xModel = (XControlModel)UnoRuntime.queryInterface( XControlModel.class,
120             m_document.getOrb().createInstance( sQualifiedComponentName ) );
121 
122         // insert the model into the form component hierarchy, if the caller gave us a location
123         if ( null != xParentForm )
124         {
125             xParentForm.insertByIndex( xParentForm.getCount(), xModel );
126         }
127 
128         // knitt them
129         xShape.setControl( xModel );
130 
131         // add the shape to the shapes collection of the document
132         XDrawPage pageWhereToInsert = ( m_insertPage != -1 ) ? m_document.getDrawPage( m_insertPage ) : m_document.getMainDrawPage();
133 
134         XShapes xDocShapes = (XShapes)UnoRuntime.queryInterface( XShapes.class, pageWhereToInsert );
135         xDocShapes.add( xShape );
136 
137         // some initializations which are the same for all controls
138         XPropertySet xModelProps = UNO.queryPropertySet( xModel );
139         try
140         {
141             XPropertySetInfo xPSI = xModelProps.getPropertySetInfo();
142             if ( xPSI.hasPropertyByName( "Border" ) )
143             {
144                 if ( ((Short)xModelProps.getPropertyValue( "Border" )).shortValue() == com.sun.star.awt.VisualEffect.LOOK3D )
145                     xModelProps.setPropertyValue( "Border", new Short( com.sun.star.awt.VisualEffect.FLAT ) );
146             }
147             if ( xPSI.hasPropertyByName( "VisualEffect" ) )
148                 xModelProps.setPropertyValue( "VisualEffect", new Short( com.sun.star.awt.VisualEffect.FLAT ) );
149             if ( m_document.classify() != DocumentType.CALC )
150                 if ( xPSI.hasPropertyByName( "BorderColor" ) )
151                     xModelProps.setPropertyValue( "BorderColor", new Integer( 0x00C0C0C0 ) );
152         }
153         catch( com.sun.star.uno.Exception e )
154         {
155             System.err.println(e);
156             e.printStackTrace( System.err );
157         }
158         return xModelProps;
159     }
160 
161     /* ------------------------------------------------------------------ */
162     /** creates a control in the document
163 
164         <p>Note that <em>control<em> here is an incorrect terminology. What the method really does is
165         it creates a control shape, together with a control model, and inserts them into the document model.
166         This will result in every view to this document creating a control described by the model-shape pair.
167         </p>
168 
169         @param sFormComponentService
170             the service name of the form component to create, e.g. "TextField"
171         @param nXPos
172             the abscissa of the position of the newly inserted shape
173         @param nXPos
174             the ordinate of the position of the newly inserted shape
175         @param nWidth
176             the width of the newly inserted shape
177         @param nHeight
178             the height of the newly inserted shape
179         @return
180             the property access to the control's model
181     */
182     protected XPropertySet createControlAndShape( String sFormComponentService, int nXPos,
183         int nYPos, int nWidth, int nHeight ) throws java.lang.Exception
184     {
185         return createControlAndShape( sFormComponentService, nXPos, nYPos, nWidth, nHeight, null );
186     }
187 
188     /* ------------------------------------------------------------------ */
189     /** creates a line of controls, consisting of a label and a field for data input.
190 
191         <p>In opposite to the second form of this method, here the height of the field,
192         as well as the abscissa of the label, are under the control of the caller.</p>
193 
194         @param sControlType
195             specifies the type of the data input control
196         @param sFieldName
197             specifies the field name the text field should be bound to
198         @param sControlNamePostfix
199             specifies a postfix to append to the logical control names
200         @param nYPos
201             specifies the Y position of the line to start at
202         @param nHeight
203             the height of the field
204         @return
205             the control model of the created data input field
206     */
207     protected XPropertySet insertControlLine( String sControlType, String sFieldName, String sControlNamePostfix, int nXPos, int nYPos, int nHeight )
208         throws java.lang.Exception
209     {
210         // insert the label control
211         XPropertySet xLabelModel = createControlAndShape( "FixedText", nXPos, nYPos, 25, 6 );
212         xLabelModel.setPropertyValue( "Label", sFieldName );
213 
214         // insert the text field control
215         XPropertySet xFieldModel = createControlAndShape( sControlType, nXPos + 26, nYPos, 40, nHeight );
216         xFieldModel.setPropertyValue( "DataField", sFieldName );
217         // knit it to it's label component
218         xFieldModel.setPropertyValue( "LabelControl", xLabelModel );
219 
220         // some names, so later on we can find them
221         xLabelModel.setPropertyValue( "Name", sFieldName + sControlNamePostfix + "_Label" );
222         xFieldModel.setPropertyValue( "Name", sFieldName + sControlNamePostfix );
223 
224         return xFieldModel;
225     }
226 
227     /* ------------------------------------------------------------------ */
228     /** creates a line of controls, consisting of a label and a field for data input.
229 
230         @param sControlType
231             specifies the type of the data input control
232         @param sFieldName
233             specifies the field name the text field should be bound to
234         @param nYPos
235             specifies the Y position of the line to start at
236         @return
237             the control model of the created data input field
238     */
239     protected XPropertySet insertControlLine( String sControlType, String sFieldName, String sControlNamePostfix, int nYPos )
240         throws java.lang.Exception
241     {
242         return insertControlLine( sControlType, sFieldName, sControlNamePostfix, 2, nYPos, 6 );
243     }
244 
245     /* ------------------------------------------------------------------ */
246     /** retrieves the radio button model with the given name and the given ref value
247      *  @param form
248      *      the parent form of the radio button model to find
249      *  @param name
250      *      the name of the radio button
251      *  @param refValue
252      *      the reference value of the radio button
253     */
254     public XPropertySet getRadioModelByRefValue( XPropertySet form, String name, String refValue ) throws com.sun.star.uno.Exception, java.lang.Exception
255     {
256         XIndexAccess indexAccess = (XIndexAccess)UnoRuntime.queryInterface( XIndexAccess.class,
257             form );
258 
259         for ( int i=0; i<indexAccess.getCount(); ++i )
260         {
261             XPropertySet control = UNO.queryPropertySet( indexAccess.getByIndex( i ) );
262 
263             if ( ((String)control.getPropertyValue( "Name" )).equals( name ) )
264                 if ( ((String)control.getPropertyValue( "RefValue" )).equals( refValue ) )
265                     return control;
266         }
267         return null;
268     }
269 
270     /* ------------------------------------------------------------------ */
271     /** retrieves the radio button model with the given name and the given tag
272      *  @param form
273      *      the parent form of the radio button model to find
274      *  @param name
275      *      the name of the radio button
276      *  @param refValue
277      *      the tag of the radio button
278     */
279     public XPropertySet getRadioModelByTag( XPropertySet form, String name, String tag ) throws com.sun.star.uno.Exception, java.lang.Exception
280     {
281         XIndexAccess indexAccess = (XIndexAccess)UnoRuntime.queryInterface( XIndexAccess.class,
282             form );
283 
284         for ( int i=0; i<indexAccess.getCount(); ++i )
285         {
286             XPropertySet control = UNO.queryPropertySet( indexAccess.getByIndex( i ) );
287 
288             if ( ((String)control.getPropertyValue( "Name" )).equals( name ) )
289                 if ( ((String)control.getPropertyValue( "Tag" )).equals( tag ) )
290                     return control;
291         }
292         return null;
293     }
294 }
295