1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #include "sampleaddin.hxx"
28 
29 #include <cppuhelper/factory.hxx>
30 #include <osl/diagnose.h>
31 
32 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
33 #include <com/sun/star/drawing/XDrawPage.hpp>
34 #include <com/sun/star/chart/XChartDataArray.hpp>
35 #include <com/sun/star/text/XTextRange.hpp>
36 #include <com/sun/star/chart/X3DDisplay.hpp>
37 
38 using namespace com::sun::star;
39 using namespace rtl;
40 
41 // code for creating instances of SampleAddIn
42 
43 extern "C" {
44 
45 void SAL_CALL component_getImplementationEnvironment(
46 	const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
47 {
48 	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
49 }
50 
51 sal_Bool SAL_CALL component_writeInfo(
52 	void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey )
53 {
54 	if( pRegistryKey )
55 	{
56 		try
57 		{
58 			OUString aImpl = OUString::createFromAscii( "/" );
59 			aImpl += SampleAddIn::getImplementationName_Static();
60 			aImpl += OUString::createFromAscii( "/UNO/SERVICES" );
61 
62 			uno::Reference< registry::XRegistryKey> xNewKey(
63 				reinterpret_cast<registry::XRegistryKey*>( pRegistryKey )->createKey( aImpl ) );
64 
65 			uno::Sequence< OUString > aSequ = SampleAddIn::getSupportedServiceNames_Static();
66 			const OUString * pArray = aSequ.getConstArray();
67 			for( sal_Int32 i = 0; i < aSequ.getLength(); i++ )
68 				xNewKey->createKey( pArray[i] );
69 
70 			return sal_True;
71 		}
72 		catch( registry::InvalidRegistryException& )
73 		{
74 			OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
75 		}
76 	}
77 	return sal_False;
78 }
79 
80 void * SAL_CALL component_getFactory(
81 	const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
82 {
83 	void* pRet = 0;
84 
85 	if ( pServiceManager &&
86 			OUString::createFromAscii( pImplName ) == SampleAddIn::getImplementationName_Static() )
87 	{
88 		uno::Reference< lang::XSingleServiceFactory> xFactory( cppu::createSingleFactory(
89 				reinterpret_cast<lang::XMultiServiceFactory*>( pServiceManager ),
90 				SampleAddIn::getImplementationName_Static(),
91 				SampleAddIn_CreateInstance,
92 				SampleAddIn::getSupportedServiceNames_Static() ) );
93 
94 		if( xFactory.is())
95 		{
96 			xFactory->acquire();
97 			pRet = xFactory.get();
98 		}
99 	}
100 
101 	return pRet;
102 }
103 
104 }	// extern C
105 
106 
107 // --------------------
108 // class SampleAddIn
109 // --------------------
110 
111 SampleAddIn::SampleAddIn()
112 {
113 
114 }
115 
116 SampleAddIn::~SampleAddIn()
117 {}
118 
119 
120 // this functionality should be provided by the chart API some day
121 sal_Bool SampleAddIn::getLogicalPosition( uno::Reference< drawing::XShape >& xAxis,
122 										  double fValue,
123 										  sal_Bool bVertical,
124 										  awt::Point& aOutPosition )
125 {
126 	sal_Bool bRet = sal_False;
127 
128 	if( xAxis.is())
129 	{
130 		awt::Size aSize = xAxis->getSize();
131 		sal_Int32 nLength = bVertical? aSize.Height: aSize.Width;
132 
133 		uno::Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY );
134 		if( xProp.is())
135 		{
136 			try
137 			{
138 				double fMin(0.0), fMax(0.0);
139 				uno::Any aAny = xProp->getPropertyValue( OUString::createFromAscii( "Min" ));
140 				aAny >>= fMin;
141 				aAny = xProp->getPropertyValue( OUString::createFromAscii( "Max" ));
142 				aAny >>= fMax;
143 
144 				double fRange = fMax - fMin;
145 				if( fMin <= fValue && fValue <= fMax &&
146 					fRange != 0.0 )
147 				{
148 					double fPercentage = (fValue - fMin) / fRange;
149 					awt::Point aPos = xAxis->getPosition();
150 
151 					if( bVertical )
152 					{
153 						aOutPosition.X = aPos.X;
154 						aOutPosition.Y = static_cast<sal_Int32>(aPos.Y + nLength * (1.0 - fPercentage));	// y scale goes from top to bottom
155 					}
156 					else
157 					{
158 						aOutPosition.X = static_cast<sal_Int32>(aPos.X + nLength * fPercentage);
159 						aOutPosition.Y = aPos.Y;
160 					}
161 					bRet = sal_True;
162 				}
163 			}
164 			catch( beans::UnknownPropertyException )
165 			{
166 				// the shape xAxis was no chart axis
167 			}
168 		}
169 	}
170 
171 	return bRet;
172 }
173 
174 OUString SampleAddIn::getImplementationName_Static()
175 {
176 	return OUString::createFromAscii( "SampleAddIn" );
177 }
178 
179 uno::Sequence< ::rtl::OUString > SampleAddIn::getSupportedServiceNames_Static()
180 {
181 	uno::Sequence< OUString > aSeq( 4 );
182 
183 	aSeq[ 0 ] = OUString::createFromAscii( "com.sun.star.chart.ChartAxisXSupplier" );
184 	aSeq[ 1 ] = OUString::createFromAscii( "com.sun.star.chart.ChartAxisYSupplier" );
185 	aSeq[ 2 ] = OUString::createFromAscii( "com.sun.star.chart.Diagram" );
186 	aSeq[ 3 ] = OUString::createFromAscii( "com.sun.star.chart.SampleAddIn" );
187 
188 	return aSeq;
189 }
190 
191 uno::Reference< uno::XInterface > SAL_CALL SampleAddIn_CreateInstance(
192 	const uno::Reference< lang::XMultiServiceFactory >& )
193 {
194 	uno::Reference< uno::XInterface > xInst = (cppu::OWeakObject*)new SampleAddIn();
195 
196 	return xInst;
197 }
198 
199 // implementation of interface methods
200 
201 // XInitialization
202 void SAL_CALL SampleAddIn::initialize( const uno::Sequence< uno::Any >& aArguments )
203 	throw( uno::Exception, uno::RuntimeException )
204 {
205 	// first argument should be the XChartDocument
206 	OSL_ENSURE( aArguments.getLength() > 0, "Please initialize Chart AddIn with ChartDocument!" );
207 
208 	if( aArguments.getLength())
209 	{
210 		aArguments[ 0 ] >>= mxChartDoc;
211 		OSL_ENSURE( mxChartDoc.is(), "First argument in initialization is not an XChartDocument!" );
212 
213 		// set XY chart as base type to be drawn
214 		uno::Reference< beans::XPropertySet > xDocProp( mxChartDoc, uno::UNO_QUERY );
215 		if( xDocProp.is())
216 		{
217 			uno::Any aBaseType;
218 			aBaseType <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart.XYDiagram" ));
219 			try
220 			{
221 				xDocProp->setPropertyValue( rtl::OUString::createFromAscii( "BaseDiagram" ), aBaseType );
222 			}
223 			catch( ... )
224 			{}
225 		}
226 
227 		// change background of plot area to light blue
228 		uno::Reference< chart::X3DDisplay > xWallSupplier( mxChartDoc->getDiagram(), uno::UNO_QUERY );
229 		if( xWallSupplier.is())
230 		{
231 			uno::Reference< beans::XPropertySet > xDiaProp( xWallSupplier->getWall(), uno::UNO_QUERY );
232 			uno::Reference< beans::XPropertySet > xLegendProp( mxChartDoc->getLegend(), uno::UNO_QUERY );
233 			if( xDiaProp.is() &&
234 				xLegendProp.is())
235 			{
236 				uno::Any aAny;
237 				aAny <<= (sal_Int32)( 0xe0e0f0 );
238 				xDiaProp->setPropertyValue( OUString::createFromAscii( "FillColor" ), aAny );
239 				xLegendProp->setPropertyValue( OUString::createFromAscii( "FillColor" ), aAny );
240 			}
241 		}
242 	}
243 }
244 
245 // XRefreshable
246 /********************************************************************************
247  *
248  * The method refresh is the most important method - here all objects that
249  * are necessary for the chart are created
250  *
251  * in the first implementation you will have to insert everything in this
252  * routine - all old objects are deleted beforehand
253  *
254  ********************************************************************************/
255 void SAL_CALL SampleAddIn::refresh() throw( uno::RuntimeException )
256 {
257 	if( ! mxChartDoc.is())
258 		return;
259 
260 	// first of all get the draw page
261 	uno::Reference< drawing::XDrawPageSupplier > xPageSupp( mxChartDoc, uno::UNO_QUERY );
262 	uno::Reference< lang::XMultiServiceFactory > xFactory( mxChartDoc, uno::UNO_QUERY );
263 	if( xPageSupp.is() &&
264 		xFactory.is() )
265 	{
266 		uno::Reference< drawing::XDrawPage > xPage = xPageSupp->getDrawPage();
267 		if( xPage.is())
268 		{
269 			// now we have the page to insert objects
270 
271 			// add a horizontal line at the middle value of the first series
272 			// -------------------------------------------------------------
273 
274 
275 			// get the logical position from the coordinate
276 			// get x- and y-axis
277 			uno::Reference< drawing::XShape > xYAxisShape( getYAxis(), uno::UNO_QUERY );
278 			uno::Reference< drawing::XShape > xXAxisShape( getXAxis(), uno::UNO_QUERY );
279 
280 			if( xXAxisShape.is() &&
281 				xYAxisShape.is() )
282 			{
283 				// create line first time
284 				if( ! mxMyRedLine.is())
285 				{
286 					mxMyRedLine = uno::Reference< drawing::XShape >(
287 						xFactory->createInstance( OUString::createFromAscii( "com.sun.star.drawing.LineShape" )),
288 						uno::UNO_QUERY );
289 					xPage->add( mxMyRedLine );
290 
291 					// make line red and thick
292 					uno::Reference< beans::XPropertySet > xShapeProp( mxMyRedLine, uno::UNO_QUERY );
293 					if( xShapeProp.is())
294 					{
295 						uno::Any aColor, aWidth;
296 						aColor <<= (sal_Int32)(0xe01010);
297 						aWidth <<= (sal_Int32)(50);			// 0.5 mm
298 						try
299 						{
300 							xShapeProp->setPropertyValue( OUString::createFromAscii( "LineColor" ), aColor );
301 							xShapeProp->setPropertyValue( OUString::createFromAscii( "LineWidth" ), aWidth );
302 						}
303 						catch( ... )
304 						{}
305 					}
306 				}
307 				// create text object first time
308 				if( ! mxMyText.is())
309 				{
310 					mxMyText = uno::Reference< drawing::XShape >(
311 						xFactory->createInstance( OUString::createFromAscii( "com.sun.star.drawing.TextShape" )),
312 						uno::UNO_QUERY );
313 					xPage->add( mxMyText );
314 
315 					// change text
316 					OUString aText;
317 // 					if( maLocale.Language.equalsIgnoreCase( OUString::createFromAscii("DE")))
318 // 						aText = OUString::createFromAscii( "Kleines Beispiel" );
319 // 					else
320 						aText = OUString::createFromAscii( "Little Example" );
321 
322 					uno::Reference< beans::XPropertySet > xTextProp( mxMyText, uno::UNO_QUERY );
323 					if( xTextProp.is())
324 					{
325 						uno::Any aTrueAny;
326 						aTrueAny <<= (sal_Bool)(sal_True);
327 						try
328 						{
329 							xTextProp->setPropertyValue( rtl::OUString::createFromAscii( "TextAutoGrowWidth" ), aTrueAny );
330 						}
331 						catch( ... )
332 						{}
333 					}
334 
335 					uno::Reference< text::XTextRange > xTextRange( mxMyText, uno::UNO_QUERY );
336 					if( xTextRange.is())
337 					{
338 						xTextRange->setString( aText );
339 					}
340 				}
341 
342 
343 				// position line and text
344 
345 				// get the array. Note: the first dimension is the length
346 				// of each series and the second one is the number of series
347 				// this should be changed in the future
348 				uno::Sequence< uno::Sequence< double > > aData;
349 				uno::Reference< chart::XChartData > xData = mxChartDoc->getData();
350 				uno::Reference< chart::XChartDataArray > xDataArray( xData, uno::UNO_QUERY );
351 				if( xDataArray.is())
352 					aData = xDataArray->getData();
353 
354 				// get row count == length of each series
355 				sal_Int32 nSize = aData.getLength();
356 				sal_Int32 nMiddle = nSize / 2;
357 				// get value for first series
358 				double fMiddleVal = xData->getNotANumber();		// set to NaN
359 				if( aData[ nMiddle ].getLength())				// we have at least one series
360 					fMiddleVal = aData[ nMiddle ][ 0 ];
361 
362 				awt::Point aPos;
363 				getLogicalPosition( xYAxisShape, fMiddleVal, sal_True, aPos );
364 				awt::Size aSize = xXAxisShape->getSize();
365 
366 				if( mxMyRedLine.is())
367 				{
368 					awt::Point aEnd = aPos;
369 					aEnd.X += aSize.Width;
370 
371 					uno::Sequence< uno::Sequence< awt::Point > > aPtSeq( 1 );
372 					aPtSeq[ 0 ].realloc( 2 );
373 					aPtSeq[ 0 ][ 0 ] = aPos;
374 					aPtSeq[ 0 ][ 1 ] = aEnd;
375 
376 					uno::Reference< beans::XPropertySet > xShapeProp( mxMyRedLine, uno::UNO_QUERY );
377 					if( xShapeProp.is())
378 					{
379 						uno::Any aAny;
380 						aAny <<= aPtSeq;
381 						xShapeProp->setPropertyValue( rtl::OUString::createFromAscii( "PolyPolygon" ), aAny );
382 					}
383 				}
384 				if( mxMyText.is())
385 				{
386 					// put the text centered below the red line
387 					aPos.X += ( aSize.Width - mxMyRedLine->getPosition().X ) / 2;
388 					aPos.Y += 1000;
389 					aPos.Y += static_cast<sal_Int32>(0.1 * xYAxisShape->getSize().Height);
390 					mxMyText->setPosition( aPos );
391 				}
392 			}
393 		}
394 	}
395 
396 	// set axis scale to 200
397 //  	uno::Reference< beans::XPropertySet > xXAxis( getXAxis(), uno::UNO_QUERY );
398 //  	if( xXAxis.is())
399 //  	{
400 //  		uno::Any aAny;
401 //  		aAny <<= (sal_Bool)(sal_False);
402 //  		xXAxis->setPropertyValue( rtl::OUString::createFromAscii( "AutoStepMain" ),
403 //  								  aAny );
404 //  		aAny <<= (double)(200.0);
405 //  		xXAxis->setPropertyValue( rtl::OUString::createFromAscii( "StepMain" ),
406 //  								  aAny );
407 //  	}
408 
409 // try setting symbols
410 //  	uno::Reference< beans::XPropertySet > xProp = getDataRowProperties( 0 );
411 //  	if( xProp.is())
412 //  	{
413 //  		uno::Any aAny;
414 //  		aAny <<= (sal_Int32)(-1);
415 //  		xProp->setPropertyValue( OUString::createFromAscii( "SymbolType" ), aAny );
416 //  		aAny <<= rtl::OUString::createFromAscii( "http://mib-1168/www/images/go.gif" );
417 //  		xProp->setPropertyValue( OUString::createFromAscii( "SymbolBitmapURL" ), aAny );
418 //  	}
419 }
420 
421 void SAL_CALL SampleAddIn::addRefreshListener( const uno::Reference< util::XRefreshListener >&  )
422 	throw( uno::RuntimeException )
423 {
424 	// not implemented - this is not necessary
425 	// (this method exists just because the interface requires it)
426 }
427 
428 void SAL_CALL SampleAddIn::removeRefreshListener( const uno::Reference< util::XRefreshListener >&  )
429 	throw( uno::RuntimeException )
430 {
431 	// not implemented - this is not necessary
432 	// (this method exists just because the interface requires it)
433 }
434 
435 // XDiagram
436 OUString SAL_CALL SampleAddIn::getDiagramType() throw( uno::RuntimeException )
437 {
438 	return OUString::createFromAscii( "com.sun.star.chart.SampleDiagram" );
439 }
440 
441 // the following methods just delegate to the "parent diagram" (which in the future might no longer exist)
442 
443 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDataRowProperties( sal_Int32 nRow )
444 	throw( lang::IndexOutOfBoundsException,
445 		   uno::RuntimeException )
446 {
447 	if( mxChartDoc.is())
448 	{
449 		uno::Reference< chart::XDiagram > xDia = mxChartDoc->getDiagram();
450 		if( xDia.is())
451 			return xDia->getDataRowProperties( nRow );
452 	}
453 
454 	return uno::Reference< beans::XPropertySet >();
455 }
456 
457 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDataPointProperties( sal_Int32 nCol, sal_Int32 nRow )
458 	throw( lang::IndexOutOfBoundsException,
459 		   uno::RuntimeException )
460 {
461 	if( mxChartDoc.is())
462 	{
463 		uno::Reference< chart::XDiagram > xDia = mxChartDoc->getDiagram();
464 		if( xDia.is())
465 			return xDia->getDataPointProperties( nCol, nRow );
466 	}
467 
468 	return uno::Reference< beans::XPropertySet >();
469 }
470 
471 // XShape ( ::XDiagram )
472 awt::Size SAL_CALL SampleAddIn::getSize()
473 	throw( uno::RuntimeException )
474 {
475 	if( mxChartDoc.is())
476 	{
477 		uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
478 		if( xShape.is())
479 			return xShape->getSize();
480 	}
481 
482 	return awt::Size();
483 }
484 
485 void SAL_CALL SampleAddIn::setSize( const awt::Size& aSize )
486 	throw( beans::PropertyVetoException, uno::RuntimeException )
487 {
488 	if( mxChartDoc.is())
489 	{
490 		uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
491 		if( xShape.is())
492 			xShape->setSize( aSize );
493 	}
494 }
495 
496 awt::Point SAL_CALL SampleAddIn::getPosition()
497 	throw( uno::RuntimeException )
498 {
499 	if( mxChartDoc.is())
500 	{
501 		uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
502 		if( xShape.is())
503 			return xShape->getPosition();
504 	}
505 
506 	return awt::Point();
507 }
508 
509 void SAL_CALL SampleAddIn::setPosition( const awt::Point& aPos )
510 	throw( uno::RuntimeException )
511 {
512 	if( mxChartDoc.is())
513 	{
514 		uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
515 		if( xShape.is())
516 			xShape->setPosition( aPos );
517 	}
518 }
519 
520 // XShapeDescriptor ( ::XShape ::XDiagram )
521 rtl::OUString SAL_CALL SampleAddIn::getShapeType() throw( com::sun::star::uno::RuntimeException )
522 {
523 	return OUString::createFromAscii( "com.sun.star.chart.SampleAddinShape" );
524 }
525 
526 // XAxisXSupplier
527 uno::Reference< drawing::XShape > SAL_CALL SampleAddIn::getXAxisTitle()
528 	throw( uno::RuntimeException )
529 {
530 	if( mxChartDoc.is())
531 	{
532 		uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
533 		if( xAxisSupp.is())
534 			return xAxisSupp->getXAxisTitle();
535 	}
536 
537 	return uno::Reference< drawing::XShape >();
538 }
539 
540 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXAxis()
541 	throw( uno::RuntimeException )
542 {
543 	if( mxChartDoc.is())
544 	{
545 		uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
546 		if( xAxisSupp.is())
547 			return xAxisSupp->getXAxis();
548 	}
549 
550 	return uno::Reference< beans::XPropertySet >();
551 }
552 
553 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXMainGrid()
554 	throw( uno::RuntimeException )
555 {
556 	if( mxChartDoc.is())
557 	{
558 		uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
559 		if( xAxisSupp.is())
560 			return xAxisSupp->getXMainGrid();
561 	}
562 
563 	return uno::Reference< beans::XPropertySet >();
564 }
565 
566 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXHelpGrid()
567 	throw( uno::RuntimeException )
568 {
569 	if( mxChartDoc.is())
570 	{
571 		uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
572 		if( xAxisSupp.is())
573 			return xAxisSupp->getXHelpGrid();
574 	}
575 
576 	return uno::Reference< beans::XPropertySet >();
577 }
578 
579 // XAxisYSupplier
580 uno::Reference< drawing::XShape > SAL_CALL SampleAddIn::getYAxisTitle()
581 	throw( uno::RuntimeException )
582 {
583 	if( mxChartDoc.is())
584 	{
585 		uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
586 		if( xAxisSupp.is())
587 			return xAxisSupp->getYAxisTitle();
588 	}
589 
590 	return uno::Reference< drawing::XShape >();
591 }
592 
593 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYAxis()
594 	throw( uno::RuntimeException )
595 {
596 	if( mxChartDoc.is())
597 	{
598 		uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
599 		if( xAxisSupp.is())
600 			return xAxisSupp->getYAxis();
601 	}
602 
603 	return uno::Reference< beans::XPropertySet >();
604 }
605 
606 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYMainGrid()
607 	throw( uno::RuntimeException )
608 {
609 	if( mxChartDoc.is())
610 	{
611 		uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
612 		if( xAxisSupp.is())
613 			return xAxisSupp->getYMainGrid();
614 	}
615 
616 	return uno::Reference< beans::XPropertySet >();
617 }
618 
619 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYHelpGrid()
620 	throw( uno::RuntimeException )
621 {
622 	if( mxChartDoc.is())
623 	{
624 		uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
625 		if( xAxisSupp.is())
626 			return xAxisSupp->getYHelpGrid();
627 	}
628 
629 	return uno::Reference< beans::XPropertySet >();
630 }
631 
632 // XStatisticDisplay
633 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getUpBar()
634 	throw( uno::RuntimeException )
635 {
636 	if( mxChartDoc.is())
637 	{
638 		uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
639 		if( xStatDisp.is())
640 			return xStatDisp->getUpBar();
641 	}
642 
643 	return uno::Reference< beans::XPropertySet >();
644 }
645 
646 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDownBar()
647 	throw( uno::RuntimeException )
648 {
649 	if( mxChartDoc.is())
650 	{
651 		uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
652 		if( xStatDisp.is())
653 			return xStatDisp->getDownBar();
654 	}
655 
656 	return uno::Reference< beans::XPropertySet >();
657 }
658 
659 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getMinMaxLine()
660 	throw( uno::RuntimeException )
661 {
662 	if( mxChartDoc.is())
663 	{
664 		uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
665 		if( xStatDisp.is())
666 			return xStatDisp->getMinMaxLine();
667 	}
668 
669 	return uno::Reference< beans::XPropertySet >();
670 }
671 
672 // XServiceName
673 OUString SAL_CALL SampleAddIn::getServiceName() throw( uno::RuntimeException )
674 {
675 	return OUString::createFromAscii( "com.sun.star.chart.SampleAddIn" );
676 }
677 
678 // XServiceInfo
679 OUString SAL_CALL SampleAddIn::getImplementationName() throw( uno::RuntimeException )
680 {
681 	return getImplementationName_Static();
682 }
683 
684 sal_Bool SAL_CALL SampleAddIn::supportsService( const OUString& ServiceName )
685 	throw( uno::RuntimeException )
686 {
687 	uno::Sequence< OUString > aServiceSeq = getSupportedServiceNames_Static();
688 
689 	sal_Int32 nLength = aServiceSeq.getLength();
690 	for( sal_Int32 i=0; i < nLength; i++ )
691 	{
692 		if( ServiceName.equals( aServiceSeq[ i ] ))
693 			return sal_True;
694 	}
695 
696 	return sal_False;
697 }
698 
699 uno::Sequence< OUString > SAL_CALL SampleAddIn::getSupportedServiceNames()
700 	throw( uno::RuntimeException )
701 {
702 	return getSupportedServiceNames_Static();
703 }
704 
705 // XLocalizable
706 void SAL_CALL SampleAddIn::setLocale( const lang::Locale& eLocale )
707 	throw( uno::RuntimeException )
708 {
709 	maLocale = eLocale;
710 }
711 
712 lang::Locale SAL_CALL SampleAddIn::getLocale()
713 	throw( uno::RuntimeException )
714 {
715 	return maLocale;
716 }
717