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 import com.sun.star.awt.Rectangle;
35 
36 import com.sun.star.beans.PropertyValue;
37 import com.sun.star.beans.XPropertySet;
38 
39 import com.sun.star.chart.XDiagram;
40 import com.sun.star.chart.XChartDocument;
41 
42 import com.sun.star.container.XNameAccess;
43 import com.sun.star.container.XIndexAccess;
44 
45 import com.sun.star.document.XEmbeddedObjectSupplier;
46 
47 import com.sun.star.frame.XComponentLoader;
48 
49 import com.sun.star.lang.XComponent;
50 import com.sun.star.lang.XMultiServiceFactory;
51 import com.sun.star.lang.XMultiComponentFactory;
52 
53 import com.sun.star.sheet.XSpreadsheets;
54 import com.sun.star.sheet.XSpreadsheet;
55 import com.sun.star.sheet.XSpreadsheetDocument;
56 import com.sun.star.sheet.XCellRangeAddressable;
57 
58 import com.sun.star.table.XTableChart;
59 import com.sun.star.table.XTableCharts;
60 import com.sun.star.table.XCell;
61 import com.sun.star.table.XCellRange;
62 import com.sun.star.table.XTableChartsSupplier;
63 import com.sun.star.table.CellRangeAddress;
64 
65 import com.sun.star.uno.UnoRuntime;
66 import com.sun.star.uno.XInterface;
67 import com.sun.star.uno.XComponentContext;
68 
69 
70 
71 /** This class loads an OpenOffice.org Calc document and changes the type of the
72  * embedded chart.
73  * @author Bertram Nolte
74  */
75 public class ChartTypeChange {
76 
77     /** Table chart, which type will be changed.
78      */
79     private XTableChart xtablechart = null;
80 
81     /** Service factory
82      */
83     private XMultiComponentFactory xMCF = null;
84 
85     /** Component context
86      */
87     private XComponentContext xCompContext = null;
88 
89     /** Beginning of the program.
90      * @param args No arguments will be passed to the class.
91      */
92     public static void main(String args[]) {
93         try {
94             ChartTypeChange charttypechange = new ChartTypeChange();
95 
96             // Double array holding all values the chart should be based on.
97             String[][] stringValues = {
98                 { "", "Jan", "Feb", "Mar", "Apr", "Mai" },
99                 { "Profit", "12.3", "43.2", "5.1", "76", "56.8" },
100                 { "Rival in business", "12.2", "12.6", "17.7", "20.4", "100" },
101             };
102 
103             // Create the chart with
104             charttypechange.getChart( stringValues );
105 
106             String[] stringChartType = {
107                 "com.sun.star.chart.LineDiagram",
108                 "com.sun.star.chart.BarDiagram",
109                 "com.sun.star.chart.PieDiagram",
110                 "com.sun.star.chart.NetDiagram",
111                 "com.sun.star.chart.XYDiagram",
112                 "com.sun.star.chart.StockDiagram",
113                 "com.sun.star.chart.AreaDiagram"
114             };
115 
116             for ( int intCounter = 0; intCounter < stringChartType.length;
117                   intCounter++ ) {
118                 charttypechange.changeChartType( stringChartType[ intCounter ],
119                                                  false );
120                 Thread.sleep( 3000 );
121             }
122 
123             System.exit(0);
124         }
125         catch( Exception exception ) {
126             System.err.println( exception );
127         }
128     }
129 
130     /** The constructor connects to the OpenOffice.org.
131      * @param args Parameters for this constructor (connection string).
132      * @throws Exception All exceptions are thrown from this method.
133      */
134     public ChartTypeChange()
135         throws Exception {
136 
137         /* Bootstraps a component context. Component context to be granted
138            to a component for running. Arbitrary values can be retrieved
139            from the context. */
140         xCompContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
141 
142         /* Gets the service manager instance to be used (or null). This method has
143            been added for convenience, because the service manager is a often used
144            object. */
145         xMCF = xCompContext.getServiceManager();
146     }
147 
148     /** This method will change the type of a specified chart.
149      * @param stringType The chart will be converted to this type.
150      * @param booleanIs3D If the chart should be displayed in 3D this parameter should be set to true.
151      * @throws Exception All exceptions are thrown from this method.
152      */
153     public void changeChartType( String stringType, boolean booleanIs3D )
154     throws Exception {
155         XEmbeddedObjectSupplier xEmbeddedObjSupplier = (XEmbeddedObjectSupplier)
156             UnoRuntime.queryInterface(XEmbeddedObjectSupplier.class, xtablechart);
157         XInterface xInterface = xEmbeddedObjSupplier.getEmbeddedObject();
158 
159         XChartDocument xChartDoc = (XChartDocument)UnoRuntime.queryInterface(
160             XChartDocument.class, xInterface);
161         XDiagram xDiagram = (XDiagram) xChartDoc.getDiagram();
162         XMultiServiceFactory xMSF = (XMultiServiceFactory)
163             UnoRuntime.queryInterface( XMultiServiceFactory.class, xChartDoc );
164         Object object = xMSF.createInstance( stringType );
165         xDiagram = (XDiagram) UnoRuntime.queryInterface(XDiagram.class, object);
166 
167         XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(
168             XPropertySet.class, xDiagram );
169         xPropSet.setPropertyValue( "Dim3D", new Boolean( booleanIs3D ) );
170 
171         xChartDoc.setDiagram(xDiagram);
172     }
173 
174     /** Loading an OpenOffice.org Calc document and getting a chart by name.
175      * @param stringFileName Name of the OpenOffice.org Calc document which should
176      *                       be loaded.
177      * @param stringChartName Name of the chart which should get a new chart type.
178      */
179     public void getChart( String stringFileName, String stringChartName ) {
180         try {
181             /* A desktop environment contains tasks with one or more
182                frames in which components can be loaded. Desktop is the
183                environment for components which can instanciate within
184                frames. */
185             XComponentLoader xComponentloader = (XComponentLoader)
186                 UnoRuntime.queryInterface( XComponentLoader.class,
187                     xMCF.createInstanceWithContext("com.sun.star.frame.Desktop",
188                                                    xCompContext ) );
189 
190             // Load a Writer document, which will be automaticly displayed
191             XComponent xComponent = xComponentloader.loadComponentFromURL(
192             "file:///" + stringFileName, "_blank", 0,
193             new PropertyValue[0] );
194 
195             // Query for the interface XSpreadsheetDocument
196             XSpreadsheetDocument xSpreadSheetDocument = ( XSpreadsheetDocument )
197                 UnoRuntime.queryInterface( XSpreadsheetDocument.class, xComponent );
198 
199             XSpreadsheets xSpreadsheets = xSpreadSheetDocument.getSheets() ;
200 
201             XIndexAccess xIndexAccess = (XIndexAccess)
202                 UnoRuntime.queryInterface(XIndexAccess.class, xSpreadsheets );
203 
204             XSpreadsheet xSpreadsheet = (XSpreadsheet) UnoRuntime.queryInterface(
205                 XSpreadsheet.class, xIndexAccess.getByIndex(0));
206 
207             XTableChartsSupplier xTableChartsSupplier = ( XTableChartsSupplier )
208                 UnoRuntime.queryInterface( XTableChartsSupplier.class, xSpreadsheet );
209 
210             xIndexAccess = (XIndexAccess) UnoRuntime.queryInterface(
211                 XIndexAccess.class, xTableChartsSupplier.getCharts() );
212 
213             this.xtablechart = (XTableChart) UnoRuntime.queryInterface(
214                 XTableChart.class,  xIndexAccess.getByIndex( 0 ) );
215         }
216         catch( Exception exception ) {
217             System.err.println( exception );
218         }
219     }
220 
221     /** Creating an empty OpenOffice.org Calc document, inserting data, and getting a
222      * chart by name.
223      * @param stringValues Double array with the values for the chart.
224      */
225     public void getChart( String[][] stringValues ) {
226         try {
227             /* A desktop environment contains tasks with one or more
228                frames in which components can be loaded. Desktop is the
229                environment for components which can instanciate within
230                frames. */
231             XComponentLoader xcomponentloader = ( XComponentLoader )
232                 UnoRuntime.queryInterface( XComponentLoader.class,
233                                            xMCF.createInstanceWithContext(
234                                                "com.sun.star.frame.Desktop",
235                                                xCompContext ) );
236 
237             // Create an empty calc document, which will be automaticly displayed
238             XComponent xComponent = xcomponentloader.loadComponentFromURL(
239             "private:factory/scalc", "_blank", 0,
240             new PropertyValue[0] );
241 
242             // Query for the interface XSpreadsheetDocument
243             XSpreadsheetDocument xspreadsheetdocument = ( XSpreadsheetDocument )
244                 UnoRuntime.queryInterface( XSpreadsheetDocument.class, xComponent );
245 
246             // Get all sheets of the spreadsheet document.
247             XSpreadsheets xspreadsheets = xspreadsheetdocument.getSheets() ;
248 
249             // Get the index of the spreadsheet document.
250             XIndexAccess xindexaccess = (XIndexAccess) UnoRuntime.queryInterface(
251                 XIndexAccess.class, xspreadsheets );
252 
253             // Get the first spreadsheet.
254             XSpreadsheet xspreadsheet = (XSpreadsheet) UnoRuntime.queryInterface(
255                 XSpreadsheet.class, xindexaccess.getByIndex(0));
256 
257             // The double array will written to the spreadsheet
258             for ( int intY = 0; intY < stringValues.length; intY++ ) {
259                 for ( int intX = 0; intX < stringValues[ intY ].length;
260                 intX++ ) {
261                     // Insert the value to the cell, specified by intY and intX.
262                     this.insertIntoCell( intY, intX,
263                     stringValues[ intY ][ intX ], xspreadsheet, "" );
264                 }
265             }
266 
267             // Create a rectangle, which holds the size of the chart.
268             Rectangle rectangle = new Rectangle();
269             rectangle.X = 500;
270             rectangle.Y = 3000;
271             rectangle.Width = 25000;
272             rectangle.Height = 11000;
273 
274             // Get the cell range of the spreadsheet.
275             XCellRange xcellrange = ( XCellRange ) UnoRuntime.queryInterface(
276                 XCellRange.class, xspreadsheet );
277 
278             // Create the Unicode of the character for the column name.
279             char charRectangle = ( char ) ( 65 + stringValues.length - 1 );
280 
281             // Get maximum length all rows in the double array.
282             int intMaximumWidthRow = 0;
283             for ( int intRow = 0; intRow < stringValues.length; intRow++ ) {
284                 if ( stringValues[ intRow ].length > intMaximumWidthRow ) {
285                     intMaximumWidthRow = stringValues[ intRow ].length;
286                 }
287             }
288 
289             // Get the cell range of the written values.
290             XCellRange xcellrangeChart = xcellrange.getCellRangeByName( "A1:" +
291             charRectangle + intMaximumWidthRow );
292 
293             // Get the addressable cell range.
294             XCellRangeAddressable xcellrangeaddressable =
295             ( XCellRangeAddressable ) UnoRuntime.queryInterface(
296                 XCellRangeAddressable.class, xcellrangeChart );
297 
298             // Get the cell range address.
299             CellRangeAddress cellrangeaddress = xcellrangeaddressable.getRangeAddress();
300 
301             // Create the cell range address for the chart.
302             CellRangeAddress[] cellrangeaddressChart =
303             new CellRangeAddress[ 1 ];
304             cellrangeaddressChart[ 0 ] = cellrangeaddress;
305 
306             // Get the table charts supplier of the spreadsheet.
307             XTableChartsSupplier xtablechartssupplier = ( XTableChartsSupplier )
308                 UnoRuntime.queryInterface( XTableChartsSupplier.class, xspreadsheet );
309 
310             // Get all table charts of the spreadsheet.
311             XTableCharts xtablecharts = xtablechartssupplier.getCharts();
312 
313             // Create a table chart with all written values.
314             xtablecharts.addNewByName( "Example", rectangle,
315             cellrangeaddressChart, true, true );
316 
317             // Get the created table chart.
318             this.xtablechart = ( XTableChart ) UnoRuntime.queryInterface(
319                 XTableChart.class, (( XNameAccess ) UnoRuntime.queryInterface(
320                     XNameAccess.class, xtablecharts ) ).getByName( "Example" ));
321         }
322         catch( Exception exception ) {
323             System.err.println( exception );
324         }
325     }
326 
327     /** Inserting a given value to a cell, that is specified by the parameters intX
328      * and intY.
329      * @param intX Column on the spreadsheet.
330      * @param intY Row on the spreadsheet.
331      * @param stringValue Value to be inserted to a cell.
332      * @param xspreadsheet Spreadsheet of the cell, which will be changed.
333      * @param stringFlag If the value of stringFlag is "V", the stringValue
334      *                   will be converted to the
335      * float type. Otherwise the stringValue will be written as a formula.
336      */
337     public static void insertIntoCell( int intX, int intY, String stringValue,
338                                        XSpreadsheet xspreadsheet, String stringFlag )
339     {
340         XCell xcell = null;
341 
342         try {
343             xcell = xspreadsheet.getCellByPosition( intX, intY );
344         }
345         catch ( com.sun.star.lang.IndexOutOfBoundsException exception ) {
346             System.out.println( "Could not get cell." );
347         }
348         if ( stringFlag.equals( "V" ) ) {
349             xcell.setValue( ( new Float( stringValue ) ).floatValue() );
350         }
351         else {
352             xcell.setFormula( stringValue );
353         }
354     }
355 }
356