1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  *  The Contents of this file are made available subject to the terms of
5  *  the BSD license.
6  *
7  *  Copyright 2000, 2010 Oracle and/or its affiliates.
8  *  All rights reserved.
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *  1. Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  *  2. Redistributions in binary form must reproduce the above copyright
16  *     notice, this list of conditions and the following disclaimer in the
17  *     documentation and/or other materials provided with the distribution.
18  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
19  *     contributors may be used to endorse or promote products derived
20  *     from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
31  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
32  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *************************************************************************/
35 
36 import com.sun.star.uno.UnoRuntime;
37 import com.sun.star.container.XIndexAccess;
38 import com.sun.star.lib.uno.helper.WeakBase;
39 
40 // factories
41 import com.sun.star.lang.XMultiServiceFactory;
42 import com.sun.star.lang.XSingleServiceFactory;
43 
44 // graphics stuff
45 import com.sun.star.drawing.*;
46 import com.sun.star.awt.Point;
47 import com.sun.star.awt.Size;
48 
49 // chart stuff
50 import com.sun.star.chart.*;
51 
52 // property access
53 import com.sun.star.beans.*;
54 
55 // Add-In stuff
56 import com.sun.star.lang.XInitialization;
57 import com.sun.star.util.XRefreshable;
58 import com.sun.star.lang.XServiceName;
59 import com.sun.star.lang.XServiceInfo;
60 // Exceptions
61 import com.sun.star.uno.Exception;
62 import com.sun.star.uno.RuntimeException;
63 
64 import javax.swing.JOptionPane;
65 
66 public class JavaSampleChartAddIn extends WeakBase implements
67     XInitialization,
68     XRefreshable,
69     XDiagram,
70     XServiceName,
71     XServiceInfo
72 {
73 
74     // __________ interface methods __________
75 
76     // XInitialization
initialize( Object[] aArguments )77     public void initialize( Object[] aArguments )
78         throws Exception, RuntimeException
79     {
80         if( aArguments.length > 0 )
81         {
82             maChartDocument = UnoRuntime.queryInterface(
83                 XChartDocument.class, aArguments[ 0 ]);
84 
85             XPropertySet aDocProp = UnoRuntime.queryInterface(
86                 XPropertySet.class, maChartDocument );
87             if( aDocProp != null )
88             {
89                 // set base diagram which will be extended in refresh()
90                 aDocProp.setPropertyValue( "BaseDiagram", "com.sun.star.chart.XYDiagram" );
91             }
92 
93             // get the draw page
94             XDrawPageSupplier aPageSupp = UnoRuntime.queryInterface(
95                 XDrawPageSupplier.class, maChartDocument );
96             if( aPageSupp != null )
97                 maDrawPage = UnoRuntime.queryInterface(
98                     XDrawPage.class, aPageSupp.getDrawPage() );
99 
100             // get a factory for creating shapes
101             maShapeFactory = UnoRuntime.queryInterface(
102                 XMultiServiceFactory.class, maChartDocument );
103         }
104     }
105 
106     // XRefreshable
refresh()107     public void refresh() throws RuntimeException
108     {
109         // recycle shapes in first call, if document was loaded
110         if( maBottomLine == null ||
111             maTopLine == null )
112         {
113             // try to recycle loaded shapes
114             XPropertySet aDocProp = UnoRuntime.queryInterface(
115                 XPropertySet.class, maChartDocument );
116             if( aDocProp != null )
117             {
118                 try
119                 {
120                     XIndexAccess aShapesIA = UnoRuntime.queryInterface(
121                         XIndexAccess.class, aDocProp.getPropertyValue( "AdditionalShapes" ));
122                     if( aShapesIA != null &&
123                         aShapesIA.getCount() > 0 )
124                     {
125                         XShape aShape;
126                         String aName;
127                         for( int i = aShapesIA.getCount() - 1; i >= 0; --i )
128                         {
129                             aShape = UnoRuntime.queryInterface(
130                                 XShape.class, aShapesIA.getByIndex( i ));
131                             if( aShape != null )
132                             {
133                                 XPropertySet aProp = UnoRuntime.queryInterface(
134                                     XPropertySet.class, aShape );
135                                 aName = (String) aProp.getPropertyValue( "Name" );
136 
137                                 if( aName.equals( "top" ))
138                                 {
139                                     maTopLine = aShape;
140                                 }
141                                 else if( aName.equals( "bottom" ))
142                                 {
143                                     maBottomLine = aShape;
144                                 }
145                             }
146                         }
147                     }
148                 }
149                 catch( Exception ex )
150                 {
151                     JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE );
152                 }
153             }
154         }
155 
156         // create top line if it does not yet exist
157         try
158         {
159             if( maTopLine == null )
160             {
161                 maTopLine = UnoRuntime.queryInterface(
162                     XShape.class, maShapeFactory.createInstance( "com.sun.star.drawing.LineShape" ));
163                 maDrawPage.add( maTopLine );
164 
165                 // make line red and thicker
166                 XPropertySet aShapeProp = UnoRuntime.queryInterface(
167                     XPropertySet.class, maTopLine );
168 
169                 aShapeProp.setPropertyValue( "LineColor", Integer.valueOf( 0xe01010 ));
170                 aShapeProp.setPropertyValue( "LineWidth", Integer.valueOf( 50 ));
171                 aShapeProp.setPropertyValue( "Name", "top" );
172             }
173         }
174         catch( Exception ex )
175         {
176             JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE );
177         }
178 
179         // create bottom line if it does not yet exist
180         try
181         {
182             if( maBottomLine == null )
183             {
184                 maBottomLine = UnoRuntime.queryInterface(
185                     XShape.class, maShapeFactory.createInstance( "com.sun.star.drawing.LineShape" ));
186                 maDrawPage.add( maBottomLine );
187 
188                 // make line green and thicker
189                 XPropertySet aShapeProp = UnoRuntime.queryInterface(
190                     XPropertySet.class, maBottomLine );
191 
192                 aShapeProp.setPropertyValue( "LineColor", Integer.valueOf( 0x10e010 ));
193                 aShapeProp.setPropertyValue( "LineWidth", Integer.valueOf( 50 ));
194                 aShapeProp.setPropertyValue( "Name", "bottom" );
195             }
196         }
197         catch( Exception ex )
198         {
199             JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE );
200         }
201 
202         if( maTopLine == null ||
203             maBottomLine == null )
204         {
205             JOptionPane.showMessageDialog( null, "One of the lines is still null", "Assertion", JOptionPane.WARNING_MESSAGE );
206             return;
207         }
208 
209         // position lines
210 
211 
212         // get data
213         XChartDataArray aDataArray = UnoRuntime.queryInterface(
214             XChartDataArray.class, maChartDocument.getData());
215         double aData[][] = aDataArray.getData();
216 
217         // get axes
218         XDiagram aDiagram = maChartDocument.getDiagram();
219         XShape aXAxis = UnoRuntime.queryInterface(
220             XShape.class, UnoRuntime.queryInterface(
221                                XAxisXSupplier.class, aDiagram ).getXAxis() );
222         XShape aYAxis = UnoRuntime.queryInterface(
223             XShape.class, UnoRuntime.queryInterface(
224                                XAxisYSupplier.class, aDiagram ).getYAxis() );
225 
226         // calculate points for hull
227         final int nLength = aData.length;
228         int i, j;
229         double fMax, fMin;
230 
231         Point aMaxPtSeq[][] = new Point[ 1 ][];
232         aMaxPtSeq[ 0 ] = new Point[ nLength ];
233         Point aMinPtSeq[][] = new Point[ 1 ][];
234         aMinPtSeq[ 0 ] = new Point[ nLength ];
235 
236         for( i = 0; i < nLength; i++ )
237         {
238             fMin = fMax = aData[ i ][ 1 ];
239             for( j = 1; j < aData[ i ].length; j++ )
240             {
241                 if( aData[ i ][ j ] > fMax )
242                     fMax = aData[ i ][ j ];
243                 else if( aData[ i ][ j ] < fMin )
244                     fMin = aData[ i ][ j ];
245             }
246             aMaxPtSeq[ 0 ][ i ] = new Point( getAxisPosition( aXAxis, aData[ i ][ 0 ], false ),
247                                              getAxisPosition( aYAxis, fMax, true ));
248             aMinPtSeq[ 0 ][ i ] = new Point( getAxisPosition( aXAxis, aData[ i ][ 0 ], false ),
249                                              getAxisPosition( aYAxis, fMin, true ));
250         }
251 
252         // apply point sequences to lines
253         try
254         {
255             XPropertySet aShapeProp = UnoRuntime.queryInterface(
256                 XPropertySet.class, maTopLine );
257             aShapeProp.setPropertyValue( "PolyPolygon", aMaxPtSeq );
258 
259             aShapeProp = UnoRuntime.queryInterface(
260                 XPropertySet.class, maBottomLine );
261             aShapeProp.setPropertyValue( "PolyPolygon", aMinPtSeq );
262         }
263         catch( Exception ex )
264         {
265             JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE );
266         }
267     }
268 
addRefreshListener( com.sun.star.util.XRefreshListener aListener )269     public void addRefreshListener( com.sun.star.util.XRefreshListener aListener )
270         throws RuntimeException
271     {
272         // we don't want this but we have to implement the interface
273     }
274 
removeRefreshListener( com.sun.star.util.XRefreshListener aListener )275     public void removeRefreshListener( com.sun.star.util.XRefreshListener aListener )
276         throws RuntimeException
277     {
278         // we don't want this but we have to implement the interface
279     }
280 
281 
282     // XServiceName
getServiceName()283     public String getServiceName() throws RuntimeException
284     {
285         return smServiceName;
286     }
287 
288     // XServiceInfo
supportsService( String aServiceName )289     public boolean supportsService( String aServiceName )
290     {
291         String[] aServices = getSupportedServiceNames_Static();
292         int i, nLength = aServices.length;
293         boolean bResult = false;
294 
295         for( i = 0; !bResult && i < nLength; ++i )
296             bResult = aServiceName.equals( aServices[ i ] );
297 
298         return bResult;
299     }
300 
getImplementationName()301     public String getImplementationName()
302     {
303         return( JavaSampleChartAddIn.class.getName() );
304     }
305 
getSupportedServiceNames()306     public String[] getSupportedServiceNames()
307     {
308         return getSupportedServiceNames_Static();
309     }
310 
311     // XDiagram
getDiagramType()312     public String getDiagramType() throws RuntimeException
313     {
314         return smServiceName;
315     }
316 
getDataRowProperties( int nRow )317     public XPropertySet getDataRowProperties( int nRow )
318         throws com.sun.star.lang.IndexOutOfBoundsException, RuntimeException
319     {
320         return maChartDocument.getDiagram().getDataRowProperties( nRow );
321     }
322 
getDataPointProperties( int nCol, int nRow )323     public XPropertySet getDataPointProperties( int nCol, int nRow )
324         throws com.sun.star.lang.IndexOutOfBoundsException, RuntimeException
325     {
326         return maChartDocument.getDiagram().getDataPointProperties( nCol, nRow );
327     }
328 
329     // XShape : XDiagram
getSize()330     public Size getSize() throws RuntimeException
331     {
332         return UnoRuntime.queryInterface( XShape.class, maChartDocument.getDiagram()).getSize();
333     }
setSize( Size aSize )334     public void setSize( Size aSize ) throws RuntimeException, PropertyVetoException
335     {
336         UnoRuntime.queryInterface( XShape.class, maChartDocument.getDiagram()).setSize( aSize );
337     }
338 
getPosition()339     public Point getPosition() throws RuntimeException
340     {
341         return UnoRuntime.queryInterface( XShape.class, maChartDocument.getDiagram()).getPosition();
342     }
setPosition( Point aPos )343     public void setPosition( Point aPos ) throws RuntimeException
344     {
345         UnoRuntime.queryInterface( XShape.class, maChartDocument.getDiagram()).setPosition( aPos );
346     }
347 
348     // XShapeDescriptor : XShape : XDiagram
getShapeType()349     public String getShapeType() throws RuntimeException
350     {
351         return "com.sun.star.comp.Chart.JavaSampleDiagramShape";
352     }
353 
354 
355     // __________ private members __________
356     private com.sun.star.chart.XChartDocument       maChartDocument;
357     private com.sun.star.drawing.XDrawPage          maDrawPage;
358     private com.sun.star.lang.XMultiServiceFactory  maShapeFactory;
359 
360     // shapes added by add-in
361     private com.sun.star.drawing.XShape             maTopLine;
362     private com.sun.star.drawing.XShape             maBottomLine;
363 
364     // __________ private methods __________
365 
getAxisPosition( XShape aAxis, double fValue, boolean bVertical )366     private int getAxisPosition( XShape aAxis, double fValue, boolean bVertical )
367     {
368         int nResult = 0;
369 
370         if( aAxis != null )
371         {
372             XPropertySet aAxisProp = UnoRuntime.queryInterface(
373                 XPropertySet.class, aAxis );
374 
375             try
376             {
377                 double fMin, fMax;
378                 fMin = ((Double) aAxisProp.getPropertyValue( "Min" )).doubleValue();
379                 fMax = ((Double) aAxisProp.getPropertyValue( "Max" )).doubleValue();
380                 double fRange = fMax - fMin;
381 
382                 if( fMin <= fValue && fValue <= fMax &&
383                     fRange != 0 )
384                 {
385                     if( bVertical )
386                     {
387                         nResult = aAxis.getPosition().Y +
388                             (int)((aAxis.getSize().Height) *
389                                   (1.0 - (( fValue - fMin ) / fRange )));
390                     }
391                     else
392                     {
393                         nResult = aAxis.getPosition().X +
394                             (int)((aAxis.getSize().Width) *
395                                   (( fValue - fMin ) / fRange ));
396                     }
397                 }
398             }
399             catch( Exception ex )
400             {
401                 JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE );
402             }
403         }
404         return nResult;
405     }
406 
407     // __________ static things __________
408 
409     private static final String smServiceName  = "com.sun.star.comp.Chart.JavaSampleChartAddIn";
410 
getSupportedServiceNames_Static()411     public static String[] getSupportedServiceNames_Static()
412     {
413         String[] aResult = { smServiceName,
414                              "com.sun.star.chart.Diagram",
415                              "com.sun.star.chart.ChartAxisYSupplier" };
416         return aResult;
417     }
418 
419 
420     /**
421      * Returns a factory for creating the service.
422      * This method is called by the <code>JavaLoader</code>
423      * <p>
424      * @return  returns a <code>XSingleServiceFactory</code> for creating the component
425      * @param   implName     the name of the implementation for which a service is desired
426      * @param   multiFactory the service manager to be used if needed
427      * @param   regKey       the registryKey
428      * @see                  com.sun.star.comp.loader.JavaLoader
429      */
__getServiceFactory( String implName, XMultiServiceFactory multiFactory, com.sun.star.registry.XRegistryKey regKey )430     public static XSingleServiceFactory __getServiceFactory(
431         String implName,
432         XMultiServiceFactory multiFactory,
433         com.sun.star.registry.XRegistryKey regKey )
434     {
435         XSingleServiceFactory xSingleServiceFactory = null;
436 
437         if( implName.equals( JavaSampleChartAddIn.class.getName()) )
438         {
439             xSingleServiceFactory = com.sun.star.comp.loader.FactoryHelper.getServiceFactory(
440                 JavaSampleChartAddIn.class, smServiceName,
441                 multiFactory,  regKey );
442         }
443 
444         return xSingleServiceFactory;
445     }
446 
447 }
448 
449 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
450