xref: /AOO41X/main/odk/examples/DevelopersGuide/Drawing/DrawingDemo.java (revision 27b2fc91b67b282ef25e5c8fc07f05afd8a62640)
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