1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "sampleaddin.hxx"
21 #include <cppuhelper/factory.hxx>
22 #include <osl/diagnose.h>
24 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
25 #include <com/sun/star/drawing/XDrawPage.hpp>
26 #include <com/sun/star/chart/XChartDataArray.hpp>
27 #include <com/sun/star/text/XTextRange.hpp>
28 #include <com/sun/star/chart/X3DDisplay.hpp>
30 using namespace com::sun::star
;
33 // code for creating instances of SampleAddIn
37 sal_Bool SAL_CALL
component_writeInfo(
38 void * /*pServiceManager*/, registry::XRegistryKey
* pRegistryKey
)
44 OUString
aImpl( "/" );
45 aImpl
+= SampleAddIn::getImplementationName_Static();
46 aImpl
+= "/UNO/SERVICES";
48 uno::Reference
< registry::XRegistryKey
> xNewKey(
49 reinterpret_cast<registry::XRegistryKey
*>( pRegistryKey
)->createKey( aImpl
) );
51 uno::Sequence
< OUString
> aSequ
= SampleAddIn::getSupportedServiceNames_Static();
52 const OUString
* pArray
= aSequ
.getConstArray();
53 for( sal_Int32 i
= 0; i
< aSequ
.getLength(); i
++ )
54 xNewKey
->createKey( pArray
[i
] );
58 catch( const registry::InvalidRegistryException
& )
60 OSL_FAIL( "### InvalidRegistryException!" );
66 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
component_getFactory(
67 const sal_Char
* pImplName
, void * pServiceManager
, void * /*pRegistryKey*/ )
71 if ( pServiceManager
&&
72 OUString::createFromAscii( pImplName
) == SampleAddIn::getImplementationName_Static() )
74 uno::Reference
< lang::XSingleServiceFactory
> xFactory( cppu::createSingleFactory(
75 reinterpret_cast<lang::XMultiServiceFactory
*>( pServiceManager
),
76 SampleAddIn::getImplementationName_Static(),
77 SampleAddIn_CreateInstance
,
78 SampleAddIn::getSupportedServiceNames_Static() ) );
83 pRet
= xFactory
.get();
93 // --------------------
95 // --------------------
97 SampleAddIn::SampleAddIn()
102 SampleAddIn::~SampleAddIn()
106 // this functionality should be provided by the chart API some day
107 sal_Bool
SampleAddIn::getLogicalPosition( uno::Reference
< drawing::XShape
>& xAxis
,
110 awt::Point
& aOutPosition
)
112 sal_Bool bRet
= sal_False
;
116 awt::Size aSize
= xAxis
->getSize();
117 sal_Int32 nLength
= bVertical
? aSize
.Height
: aSize
.Width
;
119 uno::Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
124 double fMin(0.0), fMax(0.0);
125 uno::Any aAny
= xProp
->getPropertyValue( "Min" );
127 aAny
= xProp
->getPropertyValue( "Max" );
130 double fRange
= fMax
- fMin
;
131 if( fMin
<= fValue
&& fValue
<= fMax
&&
134 double fPercentage
= (fValue
- fMin
) / fRange
;
135 awt::Point aPos
= xAxis
->getPosition();
139 aOutPosition
.X
= aPos
.X
;
140 aOutPosition
.Y
= static_cast<sal_Int32
>(aPos
.Y
+ nLength
* (1.0 - fPercentage
)); // y scale goes from top to bottom
144 aOutPosition
.X
= static_cast<sal_Int32
>(aPos
.X
+ nLength
* fPercentage
);
145 aOutPosition
.Y
= aPos
.Y
;
150 catch( const beans::UnknownPropertyException
& )
152 // the shape xAxis was no chart axis
160 OUString
SampleAddIn::getImplementationName_Static()
162 return "SampleAddIn";
165 uno::Sequence
< OUString
> SampleAddIn::getSupportedServiceNames_Static()
167 uno::Sequence
< OUString
> aSeq( 4 );
169 aSeq
[ 0 ] = "com.sun.star.chart.ChartAxisXSupplier";
170 aSeq
[ 1 ] = "com.sun.star.chart.ChartAxisYSupplier";
171 aSeq
[ 2 ] = "com.sun.star.chart.Diagram";
172 aSeq
[ 3 ] = "com.sun.star.chart.SampleAddIn";
177 uno::Reference
< uno::XInterface
> SAL_CALL
SampleAddIn_CreateInstance(
178 const uno::Reference
< lang::XMultiServiceFactory
>& )
180 uno::Reference
< uno::XInterface
> xInst
= (cppu::OWeakObject
*)new SampleAddIn();
185 // implementation of interface methods
188 void SAL_CALL
SampleAddIn::initialize( const uno::Sequence
< uno::Any
>& aArguments
)
189 throw( uno::Exception
, uno::RuntimeException
)
191 // first argument should be the XChartDocument
192 OSL_ENSURE( aArguments
.getLength() > 0, "Please initialize Chart AddIn with ChartDocument!" );
194 if( aArguments
.getLength())
196 aArguments
[ 0 ] >>= mxChartDoc
;
197 OSL_ENSURE( mxChartDoc
.is(), "First argument in initialization is not an XChartDocument!" );
199 // set XY chart as base type to be drawn
200 uno::Reference
< beans::XPropertySet
> xDocProp( mxChartDoc
, uno::UNO_QUERY
);
204 aBaseType
<<= "com.sun.star.chart.XYDiagram";
207 xDocProp
->setPropertyValue( "BaseDiagram" , aBaseType
);
213 // change background of plot area to light blue
214 uno::Reference
< chart::X3DDisplay
> xWallSupplier( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
215 if( xWallSupplier
.is())
217 uno::Reference
< beans::XPropertySet
> xDiaProp( xWallSupplier
->getWall(), uno::UNO_QUERY
);
218 uno::Reference
< beans::XPropertySet
> xLegendProp( mxChartDoc
->getLegend(), uno::UNO_QUERY
);
223 aAny
<<= (sal_Int32
)( 0xe0e0f0 );
224 xDiaProp
->setPropertyValue( "FillColor" , aAny
);
225 xLegendProp
->setPropertyValue( "FillColor" , aAny
);
232 /********************************************************************************
234 * The method refresh is the most important method - here all objects that
235 * are necessary for the chart are created
237 * in the first implementation you will have to insert everything in this
238 * routine - all old objects are deleted beforehand
240 ********************************************************************************/
241 void SAL_CALL
SampleAddIn::refresh() throw( uno::RuntimeException
)
243 if( ! mxChartDoc
.is())
246 // first of all get the draw page
247 uno::Reference
< drawing::XDrawPageSupplier
> xPageSupp( mxChartDoc
, uno::UNO_QUERY
);
248 uno::Reference
< lang::XMultiServiceFactory
> xFactory( mxChartDoc
, uno::UNO_QUERY
);
249 if( xPageSupp
.is() &&
252 uno::Reference
< drawing::XDrawPage
> xPage
= xPageSupp
->getDrawPage();
255 // now we have the page to insert objects
257 // add a horizontal line at the middle value of the first series
258 // -------------------------------------------------------------
261 // get the logical position from the coordinate
263 uno::Reference
< drawing::XShape
> xYAxisShape( getYAxis(), uno::UNO_QUERY
);
264 uno::Reference
< drawing::XShape
> xXAxisShape( getXAxis(), uno::UNO_QUERY
);
266 if( xXAxisShape
.is() &&
269 // create line first time
270 if( ! mxMyRedLine
.is())
272 mxMyRedLine
= uno::Reference
< drawing::XShape
>(
273 xFactory
->createInstance( "com.sun.star.drawing.LineShape" ),
275 xPage
->add( mxMyRedLine
);
277 // make line red and thick
278 uno::Reference
< beans::XPropertySet
> xShapeProp( mxMyRedLine
, uno::UNO_QUERY
);
281 uno::Any aColor
, aWidth
;
282 aColor
<<= (sal_Int32
)(0xe01010);
283 aWidth
<<= (sal_Int32
)(50); // 0.5 mm
286 xShapeProp
->setPropertyValue( "LineColor" , aColor
);
287 xShapeProp
->setPropertyValue( "LineWidth" , aWidth
);
293 // create text object first time
296 mxMyText
= uno::Reference
< drawing::XShape
>(
297 xFactory
->createInstance( "com.sun.star.drawing.TextShape" ),
299 xPage
->add( mxMyText
);
302 OUString
aText( "Little Example" );
303 uno::Reference
< beans::XPropertySet
> xTextProp( mxMyText
, uno::UNO_QUERY
);
307 aTrueAny
<<= (sal_Bool
)(sal_True
);
310 xTextProp
->setPropertyValue( "TextAutoGrowWidth" , aTrueAny
);
316 uno::Reference
< text::XTextRange
> xTextRange( mxMyText
, uno::UNO_QUERY
);
319 xTextRange
->setString( aText
);
324 // position line and text
326 // get the array. Note: the first dimension is the length
327 // of each series and the second one is the number of series
328 // this should be changed in the future
329 uno::Sequence
< uno::Sequence
< double > > aData
;
330 uno::Reference
< chart::XChartData
> xData
= mxChartDoc
->getData();
331 uno::Reference
< chart::XChartDataArray
> xDataArray( xData
, uno::UNO_QUERY
);
333 aData
= xDataArray
->getData();
335 // get row count == length of each series
336 sal_Int32 nSize
= aData
.getLength();
337 sal_Int32 nMiddle
= nSize
/ 2;
338 // get value for first series
339 double fMiddleVal
= xData
->getNotANumber(); // set to NaN
340 if( aData
[ nMiddle
].getLength()) // we have at least one series
341 fMiddleVal
= aData
[ nMiddle
][ 0 ];
344 getLogicalPosition( xYAxisShape
, fMiddleVal
, sal_True
, aPos
);
345 awt::Size aSize
= xXAxisShape
->getSize();
347 if( mxMyRedLine
.is())
349 awt::Point aEnd
= aPos
;
350 aEnd
.X
+= aSize
.Width
;
352 uno::Sequence
< uno::Sequence
< awt::Point
> > aPtSeq( 1 );
353 aPtSeq
[ 0 ].realloc( 2 );
354 aPtSeq
[ 0 ][ 0 ] = aPos
;
355 aPtSeq
[ 0 ][ 1 ] = aEnd
;
357 uno::Reference
< beans::XPropertySet
> xShapeProp( mxMyRedLine
, uno::UNO_QUERY
);
362 xShapeProp
->setPropertyValue( "PolyPolygon" , aAny
);
367 // put the text centered below the red line
368 aPos
.X
+= ( aSize
.Width
- mxMyRedLine
->getPosition().X
) / 2;
370 aPos
.Y
+= static_cast<sal_Int32
>(0.1 * xYAxisShape
->getSize().Height
);
371 mxMyText
->setPosition( aPos
);
378 void SAL_CALL
SampleAddIn::addRefreshListener( const uno::Reference
< util::XRefreshListener
>& )
379 throw( uno::RuntimeException
)
381 // not implemented - this is not necessary
382 // (this method exists just because the interface requires it)
385 void SAL_CALL
SampleAddIn::removeRefreshListener( const uno::Reference
< util::XRefreshListener
>& )
386 throw( uno::RuntimeException
)
388 // not implemented - this is not necessary
389 // (this method exists just because the interface requires it)
393 OUString SAL_CALL
SampleAddIn::getDiagramType() throw( uno::RuntimeException
)
395 return "com.sun.star.chart.SampleDiagram";
398 // the following methods just delegate to the "parent diagram" (which in the future might no longer exist)
400 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getDataRowProperties( sal_Int32 nRow
)
401 throw( lang::IndexOutOfBoundsException
,
402 uno::RuntimeException
)
406 uno::Reference
< chart::XDiagram
> xDia
= mxChartDoc
->getDiagram();
408 return xDia
->getDataRowProperties( nRow
);
411 return uno::Reference
< beans::XPropertySet
>();
414 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getDataPointProperties( sal_Int32 nCol
, sal_Int32 nRow
)
415 throw( lang::IndexOutOfBoundsException
,
416 uno::RuntimeException
)
420 uno::Reference
< chart::XDiagram
> xDia
= mxChartDoc
->getDiagram();
422 return xDia
->getDataPointProperties( nCol
, nRow
);
425 return uno::Reference
< beans::XPropertySet
>();
428 // XShape ( ::XDiagram )
429 awt::Size SAL_CALL
SampleAddIn::getSize()
430 throw( uno::RuntimeException
)
434 uno::Reference
< drawing::XShape
> xShape( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
436 return xShape
->getSize();
442 void SAL_CALL
SampleAddIn::setSize( const awt::Size
& aSize
)
443 throw( beans::PropertyVetoException
, uno::RuntimeException
)
447 uno::Reference
< drawing::XShape
> xShape( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
449 xShape
->setSize( aSize
);
453 awt::Point SAL_CALL
SampleAddIn::getPosition()
454 throw( uno::RuntimeException
)
458 uno::Reference
< drawing::XShape
> xShape( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
460 return xShape
->getPosition();
466 void SAL_CALL
SampleAddIn::setPosition( const awt::Point
& aPos
)
467 throw( uno::RuntimeException
)
471 uno::Reference
< drawing::XShape
> xShape( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
473 xShape
->setPosition( aPos
);
477 // XShapeDescriptor ( ::XShape ::XDiagram )
478 OUString SAL_CALL
SampleAddIn::getShapeType() throw( com::sun::star::uno::RuntimeException
)
480 return "com.sun.star.chart.SampleAddinShape";
484 uno::Reference
< drawing::XShape
> SAL_CALL
SampleAddIn::getXAxisTitle()
485 throw( uno::RuntimeException
)
489 uno::Reference
< chart::XAxisXSupplier
> xAxisSupp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
491 return xAxisSupp
->getXAxisTitle();
494 return uno::Reference
< drawing::XShape
>();
497 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getXAxis()
498 throw( uno::RuntimeException
)
502 uno::Reference
< chart::XAxisXSupplier
> xAxisSupp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
504 return xAxisSupp
->getXAxis();
507 return uno::Reference
< beans::XPropertySet
>();
510 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getXMainGrid()
511 throw( uno::RuntimeException
)
515 uno::Reference
< chart::XAxisXSupplier
> xAxisSupp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
517 return xAxisSupp
->getXMainGrid();
520 return uno::Reference
< beans::XPropertySet
>();
523 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getXHelpGrid()
524 throw( uno::RuntimeException
)
528 uno::Reference
< chart::XAxisXSupplier
> xAxisSupp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
530 return xAxisSupp
->getXHelpGrid();
533 return uno::Reference
< beans::XPropertySet
>();
537 uno::Reference
< drawing::XShape
> SAL_CALL
SampleAddIn::getYAxisTitle()
538 throw( uno::RuntimeException
)
542 uno::Reference
< chart::XAxisYSupplier
> xAxisSupp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
544 return xAxisSupp
->getYAxisTitle();
547 return uno::Reference
< drawing::XShape
>();
550 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getYAxis()
551 throw( uno::RuntimeException
)
555 uno::Reference
< chart::XAxisYSupplier
> xAxisSupp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
557 return xAxisSupp
->getYAxis();
560 return uno::Reference
< beans::XPropertySet
>();
563 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getYMainGrid()
564 throw( uno::RuntimeException
)
568 uno::Reference
< chart::XAxisYSupplier
> xAxisSupp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
570 return xAxisSupp
->getYMainGrid();
573 return uno::Reference
< beans::XPropertySet
>();
576 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getYHelpGrid()
577 throw( uno::RuntimeException
)
581 uno::Reference
< chart::XAxisYSupplier
> xAxisSupp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
583 return xAxisSupp
->getYHelpGrid();
586 return uno::Reference
< beans::XPropertySet
>();
590 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getUpBar()
591 throw( uno::RuntimeException
)
595 uno::Reference
< chart::XStatisticDisplay
> xStatDisp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
597 return xStatDisp
->getUpBar();
600 return uno::Reference
< beans::XPropertySet
>();
603 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getDownBar()
604 throw( uno::RuntimeException
)
608 uno::Reference
< chart::XStatisticDisplay
> xStatDisp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
610 return xStatDisp
->getDownBar();
613 return uno::Reference
< beans::XPropertySet
>();
616 uno::Reference
< beans::XPropertySet
> SAL_CALL
SampleAddIn::getMinMaxLine()
617 throw( uno::RuntimeException
)
621 uno::Reference
< chart::XStatisticDisplay
> xStatDisp( mxChartDoc
->getDiagram(), uno::UNO_QUERY
);
623 return xStatDisp
->getMinMaxLine();
626 return uno::Reference
< beans::XPropertySet
>();
630 OUString SAL_CALL
SampleAddIn::getServiceName() throw( uno::RuntimeException
)
632 return "com.sun.star.chart.SampleAddIn";
636 OUString SAL_CALL
SampleAddIn::getImplementationName() throw( uno::RuntimeException
)
638 return getImplementationName_Static();
641 sal_Bool SAL_CALL
SampleAddIn::supportsService( const OUString
& ServiceName
)
642 throw( uno::RuntimeException
)
644 uno::Sequence
< OUString
> aServiceSeq
= getSupportedServiceNames_Static();
646 sal_Int32 nLength
= aServiceSeq
.getLength();
647 for( sal_Int32 i
=0; i
< nLength
; i
++ )
649 if( ServiceName
.equals( aServiceSeq
[ i
] ))
656 uno::Sequence
< OUString
> SAL_CALL
SampleAddIn::getSupportedServiceNames()
657 throw( uno::RuntimeException
)
659 return getSupportedServiceNames_Static();
663 void SAL_CALL
SampleAddIn::setLocale( const lang::Locale
& eLocale
)
664 throw( uno::RuntimeException
)
669 lang::Locale SAL_CALL
SampleAddIn::getLocale()
670 throw( uno::RuntimeException
)
675 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */