xref: /trunk/main/odk/examples/DevelopersGuide/Drawing/DrawingDemo.java (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  *  The Contents of this file are made available subject to the terms of
4  *  the BSD license.
5  *
6  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18  *     contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *************************************************************************/
34 
35 // __________ Imports __________
36 
37 import com.sun.star.uno.UnoRuntime;
38 import com.sun.star.lang.XComponent;
39 
40 import com.sun.star.awt.Point;
41 import com.sun.star.awt.Size;
42 
43 import com.sun.star.beans.PropertyValue;
44 import com.sun.star.beans.XPropertySet;
45 
46 import com.sun.star.container.XNamed;
47 
48 import com.sun.star.drawing.PolygonFlags;
49 import com.sun.star.drawing.PolyPolygonBezierCoords;
50 import com.sun.star.drawing.XShape;
51 import com.sun.star.drawing.XShapes;
52 import com.sun.star.drawing.XShapeGrouper;
53 import com.sun.star.drawing.XDrawPage;
54 
55 import java.util.Random;
56 
57 
58 // __________ Implementation __________
59 
60 /** drawing demo
61     @author Sven Jacobi
62  */
63 
64 // This drawing demo will create/load a document, and show how to
65 // handle pages and shapes using the Office API,
66 
67 // Calling this demo two parameter can be used. The first parameter
68 // describes if a document is to create or load: "draw" creates a
69 // draw document, "impress" creates an impress document, any other
70 // parameter is interpreted as URL and loads the corresponding
71 // document. ( example for a URL is: "file:///c:/test.odp" )
72 // The second parameter is the connection that is to use. If no parameter
73 // is given a standard impress document is created by using following
74 // connection: "uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager";
75 
76 public class DrawingDemo
77 {
78     public static void main( String args[] )
79     {
80         XComponent xDrawDoc = null;
81         try
82         {
83             // get the remote office context of a running office (a new office
84             // instance is started if necessary)
85             com.sun.star.uno.XComponentContext xOfficeContext = Helper.connect();
86 
87             String sURL;
88             if ( args.length == 0 )
89                 sURL = "impress";
90             else
91                 sURL = args[ 0 ];
92 
93             if ( sURL.equals( "draw" ) )
94                 sURL = "private:factory/sdraw";
95             else if ( sURL.equals( "impress" ) )
96                 sURL = "private:factory/simpress";
97 
98             // suppress Presentation Autopilot when opening the document
99             // properties are the same as described for
100             // com.sun.star.document.MediaDescriptor
101             PropertyValue[] pPropValues = new PropertyValue[ 1 ];
102             pPropValues[ 0 ] = new PropertyValue();
103             pPropValues[ 0 ].Name = "Silent";
104             pPropValues[ 0 ].Value = new Boolean( true );
105 
106             xDrawDoc = Helper.createDocument( xOfficeContext,
107                 sURL, "_blank", 0, pPropValues );
108         }
109         catch( Exception ex )
110         {
111             System.out.println( ex );
112             System.exit( 0 );
113         }
114 
115 
116         Demo_PageCreation( xDrawDoc, 10 );
117         Demo_PageNaming( xDrawDoc, "this page is called: LastPage" );
118         Demo_ShapeCreation( xDrawDoc );
119         Demo_PolyPolygonBezier( xDrawDoc );
120         Demo_Group1( xDrawDoc );
121         Demo_Group2( xDrawDoc );
122         System.exit( 0 );
123     }
124 
125     // This method appends draw pages to the document, so that a
126     // minimum of n draw pages will be available.
127     // For each second draw page also a new master page is created.
128     public static void Demo_PageCreation( XComponent xDrawDoc, int n )
129     {
130         try
131         {
132             // If the document has less than n draw pages, append them,
133             // a minimum of n draw pages will be available
134             int i, nDrawPages;
135             for ( nDrawPages = PageHelper.getDrawPageCount( xDrawDoc );
136                 nDrawPages < n; nDrawPages++ )
137                 PageHelper.insertNewDrawPageByIndex( xDrawDoc, nDrawPages );
138             // Create a master page for each second drawpage
139             int nMasterPages;
140             for ( nMasterPages = PageHelper.getMasterPageCount( xDrawDoc );
141                 nMasterPages < ( ( nDrawPages + 1 ) / 2 ); nMasterPages++ )
142                 PageHelper.insertNewMasterPageByIndex( xDrawDoc, nMasterPages );
143 
144             // Now connect master page 1 to draw page 1 and 2,
145             // master page 2 to draw page 3 and 4 and so on.
146             for ( i = 0; i < nDrawPages; i++ )
147             {
148                 XDrawPage xDrawPage = PageHelper.getDrawPageByIndex( xDrawDoc, i );
149                 XDrawPage xMasterPage = PageHelper.getMasterPageByIndex(
150                     xDrawDoc, i / 2 );
151                 PageHelper.setMasterPage( xDrawPage, xMasterPage );
152             }
153         }
154         catch( Exception ex )
155         {
156             System.out.println("Demo_PageCreation: I have a page creation problem");
157         }
158     }
159 
160     // this method shows how to name a page, this is exemplary
161     // be done for the last draw page
162     public static void Demo_PageNaming(
163         XComponent xDrawDoc, String sLastPageName )
164     {
165         try
166         {
167             XDrawPage xLastPage = PageHelper.getDrawPageByIndex( xDrawDoc,
168                 PageHelper.getDrawPageCount( xDrawDoc ) - 1 );
169 
170             // each drawpage is supporting an XNamed interface
171             XNamed xNamed = (XNamed)UnoRuntime.queryInterface(
172                 XNamed.class, xLastPage );
173 
174             // beware, the page must have an unique name
175             xNamed.setName( sLastPageName );
176         }
177         catch( Exception ex )
178         {
179             System.out.println( "Demo_PageNaming: can't set page name" );
180         }
181     }
182 
183     // This method will add one rectangle shape into the lower left quarter of
184     // every page that is available,
185     public static void Demo_ShapeCreation( XComponent xDrawDoc )
186     {
187         try
188         {
189             boolean bIsImpressDocument = PageHelper.isImpressDocument( xDrawDoc );
190 
191             int nDrawingPages = PageHelper.getDrawPageCount( xDrawDoc );
192             int nMasterPages =  PageHelper.getMasterPageCount( xDrawDoc );
193             int nGlobalPageCount = nDrawingPages + nMasterPages;
194 
195             if ( bIsImpressDocument )
196             {
197                 // in impress each draw page also has a notes page
198                 nGlobalPageCount += nDrawingPages;
199                 // for each drawing master is also a notes master available
200                 nGlobalPageCount += nMasterPages;
201                 // one handout is existing
202                 nGlobalPageCount += 1;
203             }
204 
205             // create and fill a container with all draw pages
206             XDrawPage[] pPages = new XDrawPage[ nGlobalPageCount ];
207             int i, nCurrentPageIndex = 0;
208 
209             // insert handout page
210             if ( bIsImpressDocument )
211                 pPages[ nCurrentPageIndex++ ] = PageHelper.getHandoutMasterPage(
212                     xDrawDoc );
213 
214             // inserting all master pages
215             for( i = 0; i < nMasterPages; i++ )
216             {
217                 XDrawPage xMasterPage = PageHelper.getMasterPageByIndex(
218                     xDrawDoc, i );
219                 pPages[ nCurrentPageIndex++ ] = xMasterPage;
220 
221                 // if the document is an impress, get the corresponding notes
222                 // master page
223                 if ( bIsImpressDocument )
224                     pPages[ nCurrentPageIndex++ ] = PageHelper.getNotesPage(
225                         xMasterPage );
226             }
227             for ( i = 0; i < nDrawingPages; i++ )
228             {
229                 XDrawPage xDrawPage = PageHelper.getDrawPageByIndex( xDrawDoc, i );
230                 pPages[ nCurrentPageIndex++ ] = xDrawPage;
231 
232                 // if the document is an impress, get the corresponding notes page
233                 if ( bIsImpressDocument )
234                     pPages[ nCurrentPageIndex++ ] = PageHelper.getNotesPage(
235                         xDrawPage );
236             }
237 
238             // Now a complete list of pages is available in pPages.
239             // The following code will insert a rectangle into each page.
240             for ( i = 0; i < nGlobalPageCount; i++ )
241             {
242                 Size aPageSize = PageHelper.getPageSize( pPages[ i ] );
243                 int nHalfWidth  = aPageSize.Width / 2;
244                 int nHalfHeight = aPageSize.Height / 2;
245 
246                 Random aRndGen = new Random();
247                 int nRndObjWidth  = aRndGen.nextInt( nHalfWidth );
248                 int nRndObjHeight = aRndGen.nextInt( nHalfHeight );
249 
250                 int nRndObjPosX = aRndGen.nextInt( nHalfWidth - nRndObjWidth );
251                 int nRndObjPosY = aRndGen.nextInt( nHalfHeight - nRndObjHeight )
252                     + nHalfHeight;
253 
254                 XShapes xShapes = (XShapes)
255                     UnoRuntime.queryInterface( XShapes.class, pPages[ i ] );
256                 ShapeHelper.createAndInsertShape( xDrawDoc, xShapes,
257                     new Point( nRndObjPosX, nRndObjPosY ),
258                         new Size( nRndObjWidth, nRndObjHeight ),
259                             "com.sun.star.drawing.RectangleShape" );
260             }
261         }
262         catch( Exception ex )
263         {
264             System.out.println( "Demo_ShapeCreation:" + ex );
265         }
266     }
267 
268     // This method will show how to create a PolyPolygonBezier that lies is in the
269     // topleft quarter of the page and positioned at the back
270     public static void Demo_PolyPolygonBezier( XComponent xDrawDoc )
271     {
272         try
273         {
274             XShape xPolyPolygonBezier = ShapeHelper.createShape( xDrawDoc,
275                 new Point( 0, 0 ),
276                     new Size( 0, 0 ),
277                         "com.sun.star.drawing.ClosedBezierShape" );
278 
279             // the fact that the shape must have been added to the page before
280             // it is possible to apply changes to the PropertySet, it is a good
281             // proceeding to add the shape as soon as possible
282             XDrawPage xDrawPage;
283             // if possible insert our new shape in the master page
284             if ( PageHelper.isImpressDocument( xDrawDoc ) )
285                 xDrawPage = PageHelper.getMasterPageByIndex( xDrawDoc, 0 );
286             else
287                 xDrawPage = PageHelper.getDrawPageByIndex( xDrawDoc, 0 );
288             XShapes xShapes = (XShapes)
289                 UnoRuntime.queryInterface( XShapes.class, xDrawPage );
290             xShapes.add( xPolyPolygonBezier );
291 
292             XPropertySet xShapeProperties = (XPropertySet)
293                 UnoRuntime.queryInterface( XPropertySet.class, xPolyPolygonBezier );
294 
295             // get pagesize
296             XPropertySet xPageProperties = (XPropertySet)
297                 UnoRuntime.queryInterface( XPropertySet.class, xDrawPage );
298             int nPageWidth = ((Integer)xPageProperties.getPropertyValue( "Width" )).intValue() / 2;
299             int nPageHeight = ((Integer)xPageProperties.getPropertyValue( "Height" )).intValue() / 2;
300 
301             PolyPolygonBezierCoords aCoords = new PolyPolygonBezierCoords();
302             // allocating the outer sequence
303             int nPolygonCount = 50;
304             aCoords.Coordinates = new Point[ nPolygonCount ][ ];
305             aCoords.Flags = new PolygonFlags[ nPolygonCount ][ ];
306             int i, n, nY;
307             // fill the inner point sequence now
308             for ( nY = 0, i = 0; i < nPolygonCount; i++, nY += nPageHeight / nPolygonCount )
309             {
310                 // create a polygon using two normal and two control points
311                 // allocating the inner sequence
312                 int nPointCount = 8;
313                 Point[]         pPolyPoints = new Point[ nPointCount ];
314                 PolygonFlags[]  pPolyFlags  = new PolygonFlags[ nPointCount ];
315 
316                 for ( n = 0; n < nPointCount; n++ )
317                     pPolyPoints[ n ] = new Point();
318 
319                 pPolyPoints[ 0 ].X = 0;
320                 pPolyPoints[ 0 ].Y = nY;
321                 pPolyFlags[ 0 ] = PolygonFlags.NORMAL;
322                 pPolyPoints[ 1 ].X = nPageWidth / 2;
323                 pPolyPoints[ 1 ].Y = nPageHeight;
324                 pPolyFlags[ 1 ] = PolygonFlags.CONTROL;
325                 pPolyPoints[ 2 ].X = nPageWidth / 2;;
326                 pPolyPoints[ 2 ].Y = nPageHeight;
327                 pPolyFlags[ 2 ] = PolygonFlags.CONTROL;
328                 pPolyPoints[ 3 ].X = nPageWidth;
329                 pPolyPoints[ 3 ].Y = nY;
330                 pPolyFlags[ 3 ] = PolygonFlags.NORMAL;
331 
332                 pPolyPoints[ 4 ].X = nPageWidth - 1000;
333                 pPolyPoints[ 4 ].Y = nY;
334                 pPolyFlags[ 4 ] = PolygonFlags.NORMAL;
335                 pPolyPoints[ 5 ].X = nPageWidth / 2;
336                 pPolyPoints[ 5 ].Y = nPageHeight / 2;
337                 pPolyFlags[ 5 ] = PolygonFlags.CONTROL;
338                 pPolyPoints[ 6 ].X = nPageWidth / 2;;
339                 pPolyPoints[ 6 ].Y = nPageHeight / 2;
340                 pPolyFlags[ 6 ] = PolygonFlags.CONTROL;
341                 pPolyPoints[ 7 ].X = 1000;
342                 pPolyPoints[ 7 ].Y = nY;
343                 pPolyFlags[ 7 ] = PolygonFlags.NORMAL;
344 
345                 aCoords.Coordinates[ i ]= pPolyPoints;
346                 aCoords.Flags[ i ]      = pPolyFlags;
347             }
348             xShapeProperties.setPropertyValue( "PolyPolygonBezier", aCoords );
349 
350             // move the shape to the back by changing the ZOrder
351             xShapeProperties.setPropertyValue( "ZOrder", new Integer( 1 ) );
352         }
353         catch ( Exception ex )
354         {
355             System.out.println( "Demo_PolyPolygonBezier:" + ex );
356         }
357     }
358 
359     // This method will create a group containing two ellipses
360     // the shapes will be added into the top right corner of the first
361     // draw page
362     public static void Demo_Group1( XComponent xDrawDoc )
363     {
364         try
365         {
366             XShape xGroup = ShapeHelper.createShape( xDrawDoc,
367                 new Point( 0, 0 ),
368                     new Size( 0, 0 ),
369                         "com.sun.star.drawing.GroupShape" );
370 
371             // before it is possible to insert shapes,
372             // the group must have been added to the page
373             XDrawPage xDrawPage = PageHelper.getDrawPageByIndex( xDrawDoc, 0 );
374             XShapes xShapes = (XShapes)
375                 UnoRuntime.queryInterface( XShapes.class, xDrawPage );
376             xShapes.add( xGroup );
377 
378             XShapes xShapesGroup = (XShapes)
379                 UnoRuntime.queryInterface( XShapes.class, xGroup );
380 
381             Size aPageSize = PageHelper.getPageSize( xDrawPage );
382 
383             int nWidth  = 4000;
384             int nHeight = 2000;
385             int nPosX = ( aPageSize.Width * 3 ) / 4 - nWidth / 2;
386             int nPosY1 = 2000;
387             int nPosY2 = aPageSize.Height / 2 - ( nPosY1 + nHeight );
388             XShape xRect1 = ShapeHelper.createShape( xDrawDoc,
389                 new Point( nPosX, nPosY1 ),
390                     new Size( nWidth, nHeight ),
391                         "com.sun.star.drawing.EllipseShape" );
392             XShape xRect2 = ShapeHelper.createShape( xDrawDoc,
393                 new Point( nPosX, nPosY2 ),
394                     new Size( nWidth, nHeight ),
395                         "com.sun.star.drawing.EllipseShape" );
396 
397             xShapesGroup.add( xRect1 );
398             xShapesGroup.add( xRect2 );
399         }
400         catch ( Exception ex )
401         {
402             System.out.println( "Demo_Group1:" + ex );
403         }
404     }
405 
406     // This method will group all available objects on the
407     // first page.
408     public static void Demo_Group2( XComponent xDrawDoc )
409     {
410         try
411         {
412             XDrawPage xDrawPage = PageHelper.getDrawPageByIndex( xDrawDoc, 0 );
413             XShapeGrouper xShapeGrouper = (XShapeGrouper)
414                 UnoRuntime.queryInterface( XShapeGrouper.class, xDrawPage );
415 
416             XShapes xShapesPage = (XShapes)
417                 UnoRuntime.queryInterface( XShapes.class, xDrawPage );
418 
419             xShapeGrouper.group( xShapesPage );
420         }
421         catch ( Exception ex )
422         {
423             System.out.println( "Demo_Group2:" + ex );
424         }
425     }
426 }
427