tdf#154546 skip dispatch when presenter controller is not set
[LibreOffice.git] / chart2 / workbench / addin / sampleaddin.cxx
blob5e3d23fd5fe6b353c15a260b8b555cc84c54658e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/supportsservice.hxx>
22 #include <cppuhelper/factory.hxx>
23 #include <osl/diagnose.h>
25 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
26 #include <com/sun/star/drawing/XDrawPage.hpp>
27 #include <com/sun/star/chart/XChartDataArray.hpp>
28 #include <com/sun/star/text/XTextRange.hpp>
29 #include <com/sun/star/chart/X3DDisplay.hpp>
31 using namespace com::sun::star;
33 // code for creating instances of SampleAddIn
35 extern "C" {
37 sal_Bool SAL_CALL component_writeInfo(
38 void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey )
40 if( pRegistryKey )
42 try
44 OUString aImpl = "/" + SampleAddIn::getImplementationName_Static() + "/UNO/SERVICES";
46 uno::Reference< registry::XRegistryKey> xNewKey(
47 reinterpret_cast<registry::XRegistryKey*>( pRegistryKey )->createKey( aImpl ) );
49 uno::Sequence< OUString > aSequ = SampleAddIn::getSupportedServiceNames_Static();
50 const OUString * pArray = aSequ.getConstArray();
51 for( sal_Int32 i = 0; i < aSequ.(); i++ )
52 xNewKey->createKey( pArray[i] );
54 return sal_True;
56 catch( const registry::InvalidRegistryException& )
58 TOOLS_WARN_EXCEPTION( "chart2", "" );
61 return sal_False;
64 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
65 const char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
67 void* pRet = 0;
69 if ( pServiceManager &&
70 OUString::createFromAscii( pImplName ) == SampleAddIn::getImplementationName_Static() )
72 uno::Reference< lang::XSingleServiceFactory> xFactory( cppu::createSingleFactory(
73 reinterpret_cast<lang::XMultiServiceFactory*>( pServiceManager ),
74 SampleAddIn::getImplementationName_Static(),
75 SampleAddIn_CreateInstance,
76 SampleAddIn::getSupportedServiceNames_Static() ) );
78 if( xFactory.is())
80 xFactory->acquire();
81 pRet = xFactory.get();
85 return pRet;
88 } // extern C
91 SampleAddIn::SampleAddIn()
96 SampleAddIn::~SampleAddIn()
99 // this functionality should be provided by the chart API some day
100 sal_Bool SampleAddIn::getLogicalPosition( uno::Reference< drawing::XShape >& xAxis,
101 double fValue,
102 sal_Bool bVertical,
103 awt::Point& aOutPosition )
105 sal_Bool bRet = sal_False;
107 if( xAxis.is())
109 awt::Size aSize = xAxis->getSize();
110 sal_Int32 nLength = bVertical? aSize.Height: aSize.Width;
112 uno::Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY );
113 if( xProp.is())
117 double fMin(0.0), fMax(0.0);
118 uno::Any aAny = xProp->getPropertyValue( "Min" );
119 aAny >>= fMin;
120 aAny = xProp->getPropertyValue( "Max" );
121 aAny >>= fMax;
123 double fRange = fMax - fMin;
124 if( fMin <= fValue && fValue <= fMax &&
125 fRange != 0.0 )
127 double fPercentage = (fValue - fMin) / fRange;
128 awt::Point aPos = xAxis->getPosition();
130 if( bVertical )
132 aOutPosition.X = aPos.X;
133 aOutPosition.Y = static_cast<sal_Int32>(aPos.Y + nLength * (1.0 - fPercentage)); // y scale goes from top to bottom
135 else
137 aOutPosition.X = static_cast<sal_Int32>(aPos.X + nLength * fPercentage);
138 aOutPosition.Y = aPos.Y;
140 bRet = sal_True;
143 catch( const beans::UnknownPropertyException& )
145 // the shape xAxis was no chart axis
150 return bRet;
153 OUString SampleAddIn::getImplementationName_Static()
155 return "SampleAddIn";
158 uno::Sequence< OUString > SampleAddIn::getSupportedServiceNames_Static()
160 return {
161 "com.sun.star.chart.ChartAxisXSupplier",
162 "com.sun.star.chart.ChartAxisYSupplier",
163 "com.sun.star.chart.Diagram",
164 "com.sun.star.chart.SampleAddIn"
168 uno::Reference< uno::XInterface > SAL_CALL SampleAddIn_CreateInstance(
169 const uno::Reference< lang::XMultiServiceFactory >& )
171 uno::Reference< uno::XInterface > xInst = (cppu::OWeakObject*)new SampleAddIn();
173 return xInst;
176 // implementation of interface methods
178 // XInitialization
179 void SAL_CALL SampleAddIn::initialize( const uno::Sequence< uno::Any >& aArguments )
180 throw( uno::Exception, uno::RuntimeException )
182 // first argument should be the XChartDocument
183 OSL_ENSURE( aArguments.getLength() > 0, "Please initialize Chart AddIn with ChartDocument!" );
185 if( aArguments.getLength())
187 aArguments[ 0 ] >>= mxChartDoc;
188 OSL_ENSURE( mxChartDoc.is(), "First argument in initialization is not an XChartDocument!" );
190 // set XY chart as base type to be drawn
191 uno::Reference< beans::XPropertySet > xDocProp( mxChartDoc, uno::UNO_QUERY );
192 if( xDocProp.is())
194 uno::Any aBaseType;
195 aBaseType <<= "com.sun.star.chart.XYDiagram";
198 xDocProp->setPropertyValue( "BaseDiagram" , aBaseType );
200 catch( ... )
204 // change background of plot area to light blue
205 uno::Reference< chart::X3DDisplay > xWallSupplier( mxChartDoc->getDiagram(), uno::UNO_QUERY );
206 if( xWallSupplier.is())
208 uno::Reference< beans::XPropertySet > xDiaProp( xWallSupplier->getWall(), uno::UNO_QUERY );
209 uno::Reference< beans::XPropertySet > xLegendProp( mxChartDoc->getLegend(), uno::UNO_QUERY );
210 if( xDiaProp.is() &&
211 xLegendProp.is())
213 uno::Any aAny;
214 aAny <<= (sal_Int32)( 0xe0e0f0 );
215 xDiaProp->setPropertyValue( "FillColor" , aAny );
216 xLegendProp->setPropertyValue( "FillColor" , aAny );
222 // XRefreshable
223 /********************************************************************************
225 * The method refresh is the most important method - here all objects that
226 * are necessary for the chart are created
228 * in the first implementation you will have to insert everything in this
229 * routine - all old objects are deleted beforehand
231 ********************************************************************************/
232 void SAL_CALL SampleAddIn::refresh() throw( uno::RuntimeException )
234 if( ! mxChartDoc.is())
235 return;
237 // first of all get the draw page
238 uno::Reference< drawing::XDrawPageSupplier > xPageSupp( mxChartDoc, uno::UNO_QUERY );
239 uno::Reference< lang::XMultiServiceFactory > xFactory( mxChartDoc, uno::UNO_QUERY );
240 if( xPageSupp.is() &&
241 xFactory.is() )
243 uno::Reference< drawing::XDrawPage > xPage = xPageSupp->getDrawPage();
244 if( xPage.is())
246 // now we have the page to insert objects
248 // add a horizontal line at the middle value of the first series
250 // get the logical position from the coordinate
251 // get x- and y-axis
252 uno::Reference< drawing::XShape > xYAxisShape( getYAxis(), uno::UNO_QUERY );
253 uno::Reference< drawing::XShape > xXAxisShape( getXAxis(), uno::UNO_QUERY );
255 if( xXAxisShape.is() &&
256 xYAxisShape.is() )
258 // create line first time
259 if( ! mxMyRedLine.is())
261 mxMyRedLine.set(
262 xFactory->createInstance( "com.sun.star.drawing.LineShape" ),
263 uno::UNO_QUERY );
264 xPage->add( mxMyRedLine );
266 // make line red and thick
267 uno::Reference< beans::XPropertySet > xShapeProp( mxMyRedLine, uno::UNO_QUERY );
268 if( xShapeProp.is())
270 uno::Any aColor, aWidth;
271 aColor <<= (sal_Int32)(0xe01010);
272 aWidth <<= (sal_Int32)(50); // 0.5 mm
275 xShapeProp->setPropertyValue( "LineColor" , aColor );
276 xShapeProp->setPropertyValue( "LineWidth" , aWidth );
278 catch( ... )
282 // create text object first time
283 if( ! mxMyText.is())
285 mxMyText.set(
286 xFactory->createInstance( "com.sun.star.drawing.TextShape" ),
287 uno::UNO_QUERY );
288 xPage->add( mxMyText );
290 // change text
291 OUString aText( "Little Example" );
292 uno::Reference< beans::XPropertySet > xTextProp( mxMyText, uno::UNO_QUERY );
293 if( xTextProp.is())
295 uno::Any aTrueAny;
296 aTrueAny <<= (sal_Bool)(sal_True);
299 xTextProp->setPropertyValue( "TextAutoGrowWidth" , aTrueAny );
301 catch( ... )
305 uno::Reference< text::XTextRange > xTextRange( mxMyText, uno::UNO_QUERY );
306 if( xTextRange.is())
308 xTextRange->setString( aText );
312 // position line and text
314 // get the array. Note: the first dimension is the length
315 // of each series and the second one is the number of series
316 // this should be changed in the future
317 uno::Sequence< uno::Sequence< double > > aData;
318 uno::Reference< chart::XChartData > xData = mxChartDoc->getData();
319 uno::Reference< chart::XChartDataArray > xDataArray( xData, uno::UNO_QUERY );
320 if( xDataArray.is())
321 aData = xDataArray->getData();
323 // get row count == length of each series
324 sal_Int32 nSize = aData.getLength();
325 sal_Int32 nMiddle = nSize / 2;
326 // get value for first series
327 double fMiddleVal = xData->getNotANumber(); // set to NaN
328 if( aData[ nMiddle ].getLength()) // we have at least one series
329 fMiddleVal = aData[ nMiddle ][ 0 ];
331 awt::Point aPos;
332 getLogicalPosition( xYAxisShape, fMiddleVal, sal_True, aPos );
333 awt::Size aSize = xXAxisShape->getSize();
335 if( mxMyRedLine.is())
337 awt::Point aEnd = aPos;
338 aEnd.X += aSize.Width;
340 uno::Sequence< uno::Sequence< awt::Point > > aPtSeq( 1 );
341 aPtSeq[ 0 ].realloc( 2 );
342 aPtSeq[ 0 ][ 0 ] = aPos;
343 aPtSeq[ 0 ][ 1 ] = aEnd;
345 uno::Reference< beans::XPropertySet > xShapeProp( mxMyRedLine, uno::UNO_QUERY );
346 if( xShapeProp.is())
348 xShapeProp->setPropertyValue( "PolyPolygon" , Any(aPtSeq) );
351 if( mxMyText.is())
353 // put the text centered below the red line
354 aPos.X += ( aSize.Width - mxMyRedLine->getPosition().X ) / 2;
355 aPos.Y += 1000;
356 aPos.Y += static_cast<sal_Int32>(0.1 * xYAxisShape->getSize().Height);
357 mxMyText->setPosition( aPos );
364 void SAL_CALL SampleAddIn::addRefreshListener( const uno::Reference< util::XRefreshListener >& )
365 throw( uno::RuntimeException )
367 // not implemented - this is not necessary
368 // (this method exists just because the interface requires it)
371 void SAL_CALL SampleAddIn::removeRefreshListener( const uno::Reference< util::XRefreshListener >& )
372 throw( uno::RuntimeException )
374 // not implemented - this is not necessary
375 // (this method exists just because the interface requires it)
378 // XDiagram
379 OUString SAL_CALL SampleAddIn::getDiagramType() throw( uno::RuntimeException )
381 return "com.sun.star.chart.SampleDiagram";
384 // the following methods just delegate to the "parent diagram" (which in the future might no longer exist)
386 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDataRowProperties( sal_Int32 nRow )
387 throw( lang::IndexOutOfBoundsException,
388 uno::RuntimeException )
390 if( mxChartDoc.is())
392 uno::Reference< chart::XDiagram > xDia = mxChartDoc->getDiagram();
393 if( xDia.is())
394 return xDia->getDataRowProperties( nRow );
397 return uno::Reference< beans::XPropertySet >();
400 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDataPointProperties( sal_Int32 nCol, sal_Int32 nRow )
401 throw( lang::IndexOutOfBoundsException,
402 uno::RuntimeException )
404 if( mxChartDoc.is())
406 uno::Reference< chart::XDiagram > xDia = mxChartDoc->getDiagram();
407 if( xDia.is())
408 return xDia->getDataPointProperties( nCol, nRow );
411 return uno::Reference< beans::XPropertySet >();
414 // XShape ( ::XDiagram )
415 awt::Size SAL_CALL SampleAddIn::getSize()
416 throw( uno::RuntimeException )
418 if( mxChartDoc.is())
420 uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
421 if( xShape.is())
422 return xShape->getSize();
425 return awt::Size();
428 void SAL_CALL SampleAddIn::setSize( const awt::Size& aSize )
429 throw( beans::PropertyVetoException, uno::RuntimeException )
431 if( mxChartDoc.is())
433 uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
434 if( xShape.is())
435 xShape->setSize( aSize );
439 awt::Point SAL_CALL SampleAddIn::getPosition()
440 throw( uno::RuntimeException )
442 if( mxChartDoc.is())
444 uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
445 if( xShape.is())
446 return xShape->getPosition();
449 return awt::Point();
452 void SAL_CALL SampleAddIn::setPosition( const awt::Point& aPos )
453 throw( uno::RuntimeException )
455 if( mxChartDoc.is())
457 uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
458 if( xShape.is())
459 xShape->setPosition( aPos );
463 // XShapeDescriptor ( ::XShape ::XDiagram )
464 OUString SAL_CALL SampleAddIn::getShapeType() throw( css::uno::RuntimeException )
466 return "com.sun.star.chart.SampleAddinShape";
469 // XAxisXSupplier
470 uno::Reference< drawing::XShape > SAL_CALL SampleAddIn::getXAxisTitle()
471 throw( uno::RuntimeException )
473 if( mxChartDoc.is())
475 uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
476 if( xAxisSupp.is())
477 return xAxisSupp->getXAxisTitle();
480 return uno::Reference< drawing::XShape >();
483 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXAxis()
484 throw( uno::RuntimeException )
486 if( mxChartDoc.is())
488 uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
489 if( xAxisSupp.is())
490 return xAxisSupp->getXAxis();
493 return uno::Reference< beans::XPropertySet >();
496 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXMainGrid()
497 throw( uno::RuntimeException )
499 if( mxChartDoc.is())
501 uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
502 if( xAxisSupp.is())
503 return xAxisSupp->getXMainGrid();
506 return uno::Reference< beans::XPropertySet >();
509 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXHelpGrid()
510 throw( uno::RuntimeException )
512 if( mxChartDoc.is())
514 uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
515 if( xAxisSupp.is())
516 return xAxisSupp->getXHelpGrid();
519 return uno::Reference< beans::XPropertySet >();
522 // XAxisYSupplier
523 uno::Reference< drawing::XShape > SAL_CALL SampleAddIn::getYAxisTitle()
524 throw( uno::RuntimeException )
526 if( mxChartDoc.is())
528 uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
529 if( xAxisSupp.is())
530 return xAxisSupp->getYAxisTitle();
533 return uno::Reference< drawing::XShape >();
536 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYAxis()
537 throw( uno::RuntimeException )
539 if( mxChartDoc.is())
541 uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
542 if( xAxisSupp.is())
543 return xAxisSupp->getYAxis();
546 return uno::Reference< beans::XPropertySet >();
549 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYMainGrid()
550 throw( uno::RuntimeException )
552 if( mxChartDoc.is())
554 uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
555 if( xAxisSupp.is())
556 return xAxisSupp->getYMainGrid();
559 return uno::Reference< beans::XPropertySet >();
562 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYHelpGrid()
563 throw( uno::RuntimeException )
565 if( mxChartDoc.is())
567 uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
568 if( xAxisSupp.is())
569 return xAxisSupp->getYHelpGrid();
572 return uno::Reference< beans::XPropertySet >();
575 // XStatisticDisplay
576 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getUpBar()
577 throw( uno::RuntimeException )
579 if( mxChartDoc.is())
581 uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
582 if( xStatDisp.is())
583 return xStatDisp->getUpBar();
586 return uno::Reference< beans::XPropertySet >();
589 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDownBar()
590 throw( uno::RuntimeException )
592 if( mxChartDoc.is())
594 uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
595 if( xStatDisp.is())
596 return xStatDisp->getDownBar();
599 return uno::Reference< beans::XPropertySet >();
602 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getMinMaxLine()
603 throw( uno::RuntimeException )
605 if( mxChartDoc.is())
607 uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
608 if( xStatDisp.is())
609 return xStatDisp->getMinMaxLine();
612 return uno::Reference< beans::XPropertySet >();
615 // XServiceName
616 OUString SAL_CALL SampleAddIn::getServiceName() throw( uno::RuntimeException )
618 return "com.sun.star.chart.SampleAddIn";
621 // XServiceInfo
622 OUString SAL_CALL SampleAddIn::getImplementationName() throw( uno::RuntimeException )
624 return getImplementationName_Static();
627 sal_Bool SAL_CALL SampleAddIn::supportsService( const OUString& ServiceName )
628 throw( uno::RuntimeException )
630 return cppu::supportsService(this, ServiceName);
633 uno::Sequence< OUString > SAL_CALL SampleAddIn::getSupportedServiceNames()
634 throw( uno::RuntimeException )
636 return getSupportedServiceNames_Static();
639 // XLocalizable
640 void SAL_CALL SampleAddIn::setLocale( const lang::Locale& eLocale )
641 throw( uno::RuntimeException )
643 maLocale = eLocale;
646 lang::Locale SAL_CALL SampleAddIn::getLocale()
647 throw( uno::RuntimeException )
649 return maLocale;
652 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */