1*34dd1e25SAndrew Rist /************************************************************** 2*34dd1e25SAndrew Rist * 3*34dd1e25SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*34dd1e25SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*34dd1e25SAndrew Rist * distributed with this work for additional information 6*34dd1e25SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*34dd1e25SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*34dd1e25SAndrew Rist * "License"); you may not use this file except in compliance 9*34dd1e25SAndrew Rist * with the License. You may obtain a copy of the License at 10*34dd1e25SAndrew Rist * 11*34dd1e25SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*34dd1e25SAndrew Rist * 13*34dd1e25SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*34dd1e25SAndrew Rist * software distributed under the License is distributed on an 15*34dd1e25SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*34dd1e25SAndrew Rist * KIND, either express or implied. See the License for the 17*34dd1e25SAndrew Rist * specific language governing permissions and limitations 18*34dd1e25SAndrew Rist * under the License. 19*34dd1e25SAndrew Rist * 20*34dd1e25SAndrew Rist *************************************************************/ 21*34dd1e25SAndrew Rist 22*34dd1e25SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // __________ Imports __________ 25cdf0e10cSrcweir 26cdf0e10cSrcweir import java.util.Random; 27cdf0e10cSrcweir 28cdf0e10cSrcweir // base classes 29cdf0e10cSrcweir import com.sun.star.uno.XInterface; 30cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 31cdf0e10cSrcweir import com.sun.star.lang.*; 32cdf0e10cSrcweir 33cdf0e10cSrcweir // factory for creating components 34cdf0e10cSrcweir import com.sun.star.comp.servicemanager.ServiceManager; 35cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory; 36cdf0e10cSrcweir import com.sun.star.bridge.XUnoUrlResolver; 37cdf0e10cSrcweir import com.sun.star.uno.XNamingService; 38cdf0e10cSrcweir import com.sun.star.frame.XDesktop; 39cdf0e10cSrcweir import com.sun.star.frame.XComponentLoader; 40cdf0e10cSrcweir 41cdf0e10cSrcweir // property access 42cdf0e10cSrcweir import com.sun.star.beans.*; 43cdf0e10cSrcweir 44cdf0e10cSrcweir // container access 45cdf0e10cSrcweir import com.sun.star.container.*; 46cdf0e10cSrcweir 47cdf0e10cSrcweir // application specific classes 48cdf0e10cSrcweir import com.sun.star.sheet.*; 49cdf0e10cSrcweir import com.sun.star.table.*; 50cdf0e10cSrcweir import com.sun.star.chart.*; 51cdf0e10cSrcweir import com.sun.star.text.XText; 52cdf0e10cSrcweir 53cdf0e10cSrcweir import com.sun.star.document.XEmbeddedObjectSupplier; 54cdf0e10cSrcweir import com.sun.star.frame.XModel; 55cdf0e10cSrcweir import com.sun.star.frame.XController; 56cdf0e10cSrcweir 57cdf0e10cSrcweir // base graphics things 58cdf0e10cSrcweir import com.sun.star.awt.Point; 59cdf0e10cSrcweir import com.sun.star.awt.Size; 60cdf0e10cSrcweir import com.sun.star.awt.Rectangle; 61cdf0e10cSrcweir 62cdf0e10cSrcweir // Exceptions 63cdf0e10cSrcweir import com.sun.star.uno.RuntimeException; 64cdf0e10cSrcweir import com.sun.star.container.NoSuchElementException; 65cdf0e10cSrcweir import com.sun.star.beans.UnknownPropertyException; 66cdf0e10cSrcweir import com.sun.star.lang.IndexOutOfBoundsException; 67cdf0e10cSrcweir 68cdf0e10cSrcweir // __________ Implementation __________ 69cdf0e10cSrcweir 70cdf0e10cSrcweir /** Helper for accessing a calc document 71cdf0e10cSrcweir @author Björn Milcke 72cdf0e10cSrcweir */ 73cdf0e10cSrcweir public class CalcHelper 74cdf0e10cSrcweir { CalcHelper( XSpreadsheetDocument aDoc )75cdf0e10cSrcweir public CalcHelper( XSpreadsheetDocument aDoc ) 76cdf0e10cSrcweir { 77cdf0e10cSrcweir maSpreadSheetDoc = aDoc; 78cdf0e10cSrcweir initSpreadSheet(); 79cdf0e10cSrcweir } 80cdf0e10cSrcweir 81cdf0e10cSrcweir // ____________________ 82cdf0e10cSrcweir getChartSheet()83cdf0e10cSrcweir public XSpreadsheet getChartSheet() throws RuntimeException 84cdf0e10cSrcweir { 85cdf0e10cSrcweir XNameAccess aSheetsNA = (XNameAccess) UnoRuntime.queryInterface( 86cdf0e10cSrcweir XNameAccess.class, maSpreadSheetDoc.getSheets() ); 87cdf0e10cSrcweir 88cdf0e10cSrcweir XSpreadsheet aSheet = null; 89cdf0e10cSrcweir try 90cdf0e10cSrcweir { 91cdf0e10cSrcweir aSheet = (XSpreadsheet) UnoRuntime.queryInterface( 92cdf0e10cSrcweir XSpreadsheet.class, aSheetsNA.getByName( msChartSheetName ) ); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir catch( NoSuchElementException ex ) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir System.out.println( "Couldn't find sheet with name " + msChartSheetName + ": " + ex ); 97cdf0e10cSrcweir } 98cdf0e10cSrcweir catch( Exception ex ) 99cdf0e10cSrcweir {} 100cdf0e10cSrcweir 101cdf0e10cSrcweir return aSheet; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir // ____________________ 105cdf0e10cSrcweir getDataSheet()106cdf0e10cSrcweir public XSpreadsheet getDataSheet() throws RuntimeException 107cdf0e10cSrcweir { 108cdf0e10cSrcweir XNameAccess aSheetsNA = (XNameAccess) UnoRuntime.queryInterface( 109cdf0e10cSrcweir XNameAccess.class, maSpreadSheetDoc.getSheets() ); 110cdf0e10cSrcweir 111cdf0e10cSrcweir XSpreadsheet aSheet = null; 112cdf0e10cSrcweir if( aSheetsNA != null ) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir try 115cdf0e10cSrcweir { 116cdf0e10cSrcweir aSheet = (XSpreadsheet) UnoRuntime.queryInterface( 117cdf0e10cSrcweir XSpreadsheet.class, aSheetsNA.getByName( msDataSheetName ) ); 118cdf0e10cSrcweir } 119cdf0e10cSrcweir catch( NoSuchElementException ex ) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir System.out.println( "Couldn't find sheet with name " + msDataSheetName + ": " + ex ); 122cdf0e10cSrcweir } 123cdf0e10cSrcweir catch( Exception ex ) 124cdf0e10cSrcweir {} 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir return aSheet; 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir // ____________________ 131cdf0e10cSrcweir 132cdf0e10cSrcweir /** Insert a chart using the given name as name of the OLE object and the range as correspoding 133cdf0e10cSrcweir range of data to be used for rendering. The chart is placed in the sheet for charts at 134cdf0e10cSrcweir position aUpperLeft extending as large as given in aExtent. 135cdf0e10cSrcweir 136cdf0e10cSrcweir The service name must be the name of a diagram service that can be instantiated via the 137cdf0e10cSrcweir factory of the chart document 138cdf0e10cSrcweir */ insertChart( String sChartName, CellRangeAddress aRange, Point aUpperLeft, Size aExtent, String sChartServiceName )139cdf0e10cSrcweir public XChartDocument insertChart( 140cdf0e10cSrcweir String sChartName, 141cdf0e10cSrcweir CellRangeAddress aRange, 142cdf0e10cSrcweir Point aUpperLeft, 143cdf0e10cSrcweir Size aExtent, 144cdf0e10cSrcweir String sChartServiceName ) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir XChartDocument aResult = null; 147cdf0e10cSrcweir XTableChartsSupplier aSheet; 148cdf0e10cSrcweir 149cdf0e10cSrcweir // get the sheet to insert the chart 150cdf0e10cSrcweir try 151cdf0e10cSrcweir { 152cdf0e10cSrcweir aSheet = (XTableChartsSupplier) UnoRuntime.queryInterface( 153cdf0e10cSrcweir XTableChartsSupplier.class, getChartSheet() ); 154cdf0e10cSrcweir } 155cdf0e10cSrcweir catch( Exception ex ) 156cdf0e10cSrcweir { 157cdf0e10cSrcweir System.out.println( "Sheet not found" + ex ); 158cdf0e10cSrcweir return aResult; 159cdf0e10cSrcweir } 160cdf0e10cSrcweir 161cdf0e10cSrcweir XTableCharts aChartCollection = aSheet.getCharts(); 162cdf0e10cSrcweir XNameAccess aChartCollectionNA = (XNameAccess) UnoRuntime.queryInterface( 163cdf0e10cSrcweir XNameAccess.class, aChartCollection ); 164cdf0e10cSrcweir 165cdf0e10cSrcweir if( aChartCollectionNA != null && 166cdf0e10cSrcweir ! aChartCollectionNA.hasByName( sChartName ) ) 167cdf0e10cSrcweir { 168cdf0e10cSrcweir Rectangle aRect = new Rectangle( aUpperLeft.X, aUpperLeft.Y, aExtent.Width, aExtent.Height ); 169cdf0e10cSrcweir 170cdf0e10cSrcweir CellRangeAddress[] aAddresses = new CellRangeAddress[ 1 ]; 171cdf0e10cSrcweir aAddresses[ 0 ] = aRange; 172cdf0e10cSrcweir 173cdf0e10cSrcweir // first bool: ColumnHeaders 174cdf0e10cSrcweir // second bool: RowHeaders 175cdf0e10cSrcweir aChartCollection.addNewByName( sChartName, aRect, aAddresses, true, false ); 176cdf0e10cSrcweir 177cdf0e10cSrcweir try 178cdf0e10cSrcweir { 179cdf0e10cSrcweir XTableChart aTableChart = (XTableChart) UnoRuntime.queryInterface( 180cdf0e10cSrcweir XTableChart.class, aChartCollectionNA.getByName( sChartName )); 181cdf0e10cSrcweir 182cdf0e10cSrcweir // the table chart is an embedded object which contains the chart document 183cdf0e10cSrcweir aResult = (XChartDocument) UnoRuntime.queryInterface( 184cdf0e10cSrcweir XChartDocument.class, 185cdf0e10cSrcweir ((XEmbeddedObjectSupplier) UnoRuntime.queryInterface( 186cdf0e10cSrcweir XEmbeddedObjectSupplier.class, 187cdf0e10cSrcweir aTableChart )).getEmbeddedObject()); 188cdf0e10cSrcweir 189cdf0e10cSrcweir // create a diagram via the factory and set this as new diagram 190cdf0e10cSrcweir aResult.setDiagram( 191cdf0e10cSrcweir (XDiagram) UnoRuntime.queryInterface( 192cdf0e10cSrcweir XDiagram.class, 193cdf0e10cSrcweir ((XMultiServiceFactory) UnoRuntime.queryInterface( 194cdf0e10cSrcweir XMultiServiceFactory.class, 195cdf0e10cSrcweir aResult )).createInstance( sChartServiceName ))); 196cdf0e10cSrcweir } 197cdf0e10cSrcweir catch( NoSuchElementException ex ) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir System.out.println( "Couldn't find chart with name " + sChartName + ": " + ex ); 200cdf0e10cSrcweir } 201cdf0e10cSrcweir catch( Exception ex ) 202cdf0e10cSrcweir {} 203cdf0e10cSrcweir } 204cdf0e10cSrcweir 205cdf0e10cSrcweir return aResult; 206cdf0e10cSrcweir } 207cdf0e10cSrcweir 208cdf0e10cSrcweir // ____________________ 209cdf0e10cSrcweir 210cdf0e10cSrcweir /** Fill a rectangular range with random numbers. 211cdf0e10cSrcweir The first column has increasing values 212cdf0e10cSrcweir */ insertRandomRange( int nColumnCount, int nRowCount )213cdf0e10cSrcweir public XCellRange insertRandomRange( int nColumnCount, int nRowCount ) 214cdf0e10cSrcweir { 215cdf0e10cSrcweir XCellRange aRange = null; 216cdf0e10cSrcweir 217cdf0e10cSrcweir // get the sheet to insert the chart 218cdf0e10cSrcweir try 219cdf0e10cSrcweir { 220cdf0e10cSrcweir XSpreadsheet aSheet = getDataSheet(); 221cdf0e10cSrcweir XCellRange aSheetRange = (XCellRange) UnoRuntime.queryInterface( XCellRange.class, aSheet ); 222cdf0e10cSrcweir 223cdf0e10cSrcweir aRange = aSheetRange.getCellRangeByPosition( 224cdf0e10cSrcweir 0, 0, 225cdf0e10cSrcweir nColumnCount - 1, nRowCount - 1 ); 226cdf0e10cSrcweir 227cdf0e10cSrcweir int nCol, nRow; 228cdf0e10cSrcweir double fBase = 0.0; 229cdf0e10cSrcweir double fRange = 10.0; 230cdf0e10cSrcweir double fValue; 231cdf0e10cSrcweir Random aGenerator = new Random(); 232cdf0e10cSrcweir 233cdf0e10cSrcweir 234cdf0e10cSrcweir for( nCol = 0; nCol < nColumnCount; nCol++ ) 235cdf0e10cSrcweir { 236cdf0e10cSrcweir if( 0 == nCol ) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir (aSheet.getCellByPosition( nCol, 0 )).setFormula( "X" ); 239cdf0e10cSrcweir } 240cdf0e10cSrcweir else 241cdf0e10cSrcweir { 242cdf0e10cSrcweir (aSheet.getCellByPosition( nCol, 0 )).setFormula( "Random " + nCol ); 243cdf0e10cSrcweir } 244cdf0e10cSrcweir 245cdf0e10cSrcweir for( nRow = 1; nRow < nRowCount; nRow++ ) 246cdf0e10cSrcweir { 247cdf0e10cSrcweir if( 0 == nCol ) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir // x values: ascending numbers 250cdf0e10cSrcweir fValue = (double)nRow + aGenerator.nextDouble(); 251cdf0e10cSrcweir } 252cdf0e10cSrcweir else 253cdf0e10cSrcweir { 254cdf0e10cSrcweir fValue = fBase + ( aGenerator.nextGaussian() * fRange ); 255cdf0e10cSrcweir } 256cdf0e10cSrcweir 257cdf0e10cSrcweir // put value into cell 258cdf0e10cSrcweir 259cdf0e10cSrcweir // note: getCellByPosition is a method at ...table.XCellRange which 260cdf0e10cSrcweir // the XSpreadsheet inherits via ...sheet.XSheetCellRange 261cdf0e10cSrcweir (aSheet.getCellByPosition( nCol, nRow )).setValue( fValue ); 262cdf0e10cSrcweir } 263cdf0e10cSrcweir } 264cdf0e10cSrcweir 265cdf0e10cSrcweir } 266cdf0e10cSrcweir catch( Exception ex ) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir System.out.println( "Sheet not found" + ex ); 269cdf0e10cSrcweir } 270cdf0e10cSrcweir 271cdf0e10cSrcweir return aRange; 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir // ____________________ 275cdf0e10cSrcweir insertFormulaRange( int nColumnCount, int nRowCount )276cdf0e10cSrcweir public XCellRange insertFormulaRange( int nColumnCount, int nRowCount ) 277cdf0e10cSrcweir { 278cdf0e10cSrcweir XCellRange aRange = null; 279cdf0e10cSrcweir 280cdf0e10cSrcweir // get the sheet to insert the chart 281cdf0e10cSrcweir try 282cdf0e10cSrcweir { 283cdf0e10cSrcweir XSpreadsheet aSheet = getDataSheet(); 284cdf0e10cSrcweir XCellRange aSheetRange = (XCellRange) UnoRuntime.queryInterface( XCellRange.class, aSheet ); 285cdf0e10cSrcweir 286cdf0e10cSrcweir aRange = aSheetRange.getCellRangeByPosition( 287cdf0e10cSrcweir 0, 0, 288cdf0e10cSrcweir nColumnCount - 1, nRowCount - 1 ); 289cdf0e10cSrcweir 290cdf0e10cSrcweir int nCol, nRow; 291cdf0e10cSrcweir double fValue; 292cdf0e10cSrcweir double fFactor = 2.0 * java.lang.Math.PI / (double)(nRowCount - 1); 293cdf0e10cSrcweir String aFormula; 294cdf0e10cSrcweir 295cdf0e10cSrcweir // set variable factor for cos formula 296cdf0e10cSrcweir int nFactorCol = nColumnCount + 2; 297cdf0e10cSrcweir (aSheet.getCellByPosition( nFactorCol - 1, 0 )).setValue( 0.2 ); 298cdf0e10cSrcweir 299cdf0e10cSrcweir XText xCellText = (XText) UnoRuntime.queryInterface( XText.class, aSheet.getCellByPosition( nFactorCol - 1, 1 ) ); 300cdf0e10cSrcweir xCellText.setString( "Change the factor above and\nwatch the changes in the chart" ); 301cdf0e10cSrcweir 302cdf0e10cSrcweir for( nCol = 0; nCol < nColumnCount; nCol++ ) 303cdf0e10cSrcweir { 304cdf0e10cSrcweir for( nRow = 0; nRow < nRowCount; nRow++ ) 305cdf0e10cSrcweir { 306cdf0e10cSrcweir if( 0 == nCol ) 307cdf0e10cSrcweir { 308cdf0e10cSrcweir // x values: ascending numbers 309cdf0e10cSrcweir fValue = (double)nRow * fFactor; 310cdf0e10cSrcweir (aSheet.getCellByPosition( nCol, nRow )).setValue( fValue ); 311cdf0e10cSrcweir } 312cdf0e10cSrcweir else 313cdf0e10cSrcweir { 314cdf0e10cSrcweir aFormula = new String( "=" ); 315cdf0e10cSrcweir if( nCol % 2 == 0 ) 316cdf0e10cSrcweir aFormula += "SIN"; 317cdf0e10cSrcweir else 318cdf0e10cSrcweir aFormula += "COS"; 319cdf0e10cSrcweir aFormula += "(INDIRECT(ADDRESS(" + (nRow + 1) + ";1)))+RAND()*INDIRECT(ADDRESS(1;" + nFactorCol + "))"; 320cdf0e10cSrcweir (aSheet.getCellByPosition( nCol, nRow )).setFormula( aFormula ); 321cdf0e10cSrcweir } 322cdf0e10cSrcweir } 323cdf0e10cSrcweir } 324cdf0e10cSrcweir 325cdf0e10cSrcweir } 326cdf0e10cSrcweir catch( Exception ex ) 327cdf0e10cSrcweir { 328cdf0e10cSrcweir System.out.println( "Sheet not found" + ex ); 329cdf0e10cSrcweir } 330cdf0e10cSrcweir 331cdf0e10cSrcweir return aRange; 332cdf0e10cSrcweir } 333cdf0e10cSrcweir 334cdf0e10cSrcweir // ____________________ 335cdf0e10cSrcweir 336cdf0e10cSrcweir /** Bring the sheet containing charts visually to the foreground 337cdf0e10cSrcweir */ raiseChartSheet()338cdf0e10cSrcweir public void raiseChartSheet() 339cdf0e10cSrcweir { 340cdf0e10cSrcweir ((XSpreadsheetView) UnoRuntime.queryInterface( 341cdf0e10cSrcweir XSpreadsheetView.class, 342cdf0e10cSrcweir ((XModel) UnoRuntime.queryInterface( 343cdf0e10cSrcweir XModel.class, 344cdf0e10cSrcweir maSpreadSheetDoc )).getCurrentController()) ).setActiveSheet( getChartSheet() ); 345cdf0e10cSrcweir } 346cdf0e10cSrcweir 347cdf0e10cSrcweir 348cdf0e10cSrcweir // __________ private members and methods __________ 349cdf0e10cSrcweir 350cdf0e10cSrcweir private final String msDataSheetName = "Data"; 351cdf0e10cSrcweir private final String msChartSheetName = "Chart"; 352cdf0e10cSrcweir 353cdf0e10cSrcweir private XSpreadsheetDocument maSpreadSheetDoc; 354cdf0e10cSrcweir 355cdf0e10cSrcweir 356cdf0e10cSrcweir // ____________________ 357cdf0e10cSrcweir 358cdf0e10cSrcweir /** create two sheets, one for data and one for charts in the document 359cdf0e10cSrcweir */ initSpreadSheet()360cdf0e10cSrcweir private void initSpreadSheet() 361cdf0e10cSrcweir { 362cdf0e10cSrcweir if( maSpreadSheetDoc != null ) 363cdf0e10cSrcweir { 364cdf0e10cSrcweir XSpreadsheets aSheets = maSpreadSheetDoc.getSheets(); 365cdf0e10cSrcweir XNameContainer aSheetsNC = (XNameContainer) UnoRuntime.queryInterface( 366cdf0e10cSrcweir XNameContainer.class, aSheets ); 367cdf0e10cSrcweir XIndexAccess aSheetsIA = (XIndexAccess) UnoRuntime.queryInterface( 368cdf0e10cSrcweir XIndexAccess.class, aSheets ); 369cdf0e10cSrcweir 370cdf0e10cSrcweir if( aSheets != null && 371cdf0e10cSrcweir aSheetsNC != null && 372cdf0e10cSrcweir aSheetsIA != null ) 373cdf0e10cSrcweir { 374cdf0e10cSrcweir try 375cdf0e10cSrcweir { 376cdf0e10cSrcweir // remove all sheets except one 377cdf0e10cSrcweir for( int i = aSheetsIA.getCount() - 1; i > 0; i-- ) 378cdf0e10cSrcweir { 379cdf0e10cSrcweir aSheetsNC.removeByName( 380cdf0e10cSrcweir ( (XNamed) UnoRuntime.queryInterface( 381cdf0e10cSrcweir XNamed.class, aSheetsIA.getByIndex( i ) )).getName() ); 382cdf0e10cSrcweir } 383cdf0e10cSrcweir 384cdf0e10cSrcweir XNamed aFirstSheet = (XNamed) UnoRuntime.queryInterface( 385cdf0e10cSrcweir XNamed.class, 386cdf0e10cSrcweir aSheetsIA.getByIndex( 0 )); 387cdf0e10cSrcweir 388cdf0e10cSrcweir // first sheet becomes data sheet 389cdf0e10cSrcweir aFirstSheet.setName( msDataSheetName ); 390cdf0e10cSrcweir 391cdf0e10cSrcweir // second sheet becomes chart sheet 392cdf0e10cSrcweir aSheets.insertNewByName( msChartSheetName, (short)1 ); 393cdf0e10cSrcweir } 394cdf0e10cSrcweir catch( Exception ex ) 395cdf0e10cSrcweir { 396cdf0e10cSrcweir System.out.println( "Couldn't initialize Spreadsheet Document: " + ex ); 397cdf0e10cSrcweir } 398cdf0e10cSrcweir } 399cdf0e10cSrcweir } 400cdf0e10cSrcweir } 401cdf0e10cSrcweir } 402