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