Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / chart2 / workbench / addin / sampleaddin.cxx
blob6fc40ebc7d86019f041a33e7abdeec708897e8d4
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.getLength(); i++ )
52 xNewKey->createKey( pArray[i] );
54 return sal_True;
56 catch( const registry::InvalidRegistryException& )
58 OSL_FAIL( "### InvalidRegistryException!" );
61 return sal_False;
64 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
65 const sal_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
90 // class SampleAddIn
92 SampleAddIn::SampleAddIn()
97 SampleAddIn::~SampleAddIn()
100 // this functionality should be provided by the chart API some day
101 sal_Bool SampleAddIn::getLogicalPosition( uno::Reference< drawing::XShape >& xAxis,
102 double fValue,
103 sal_Bool bVertical,
104 awt::Point& aOutPosition )
106 sal_Bool bRet = sal_False;
108 if( xAxis.is())
110 awt::Size aSize = xAxis->getSize();
111 sal_Int32 nLength = bVertical? aSize.Height: aSize.Width;
113 uno::Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY );
114 if( xProp.is())
118 double fMin(0.0), fMax(0.0);
119 uno::Any aAny = xProp->getPropertyValue( "Min" );
120 aAny >>= fMin;
121 aAny = xProp->getPropertyValue( "Max" );
122 aAny >>= fMax;
124 double fRange = fMax - fMin;
125 if( fMin <= fValue && fValue <= fMax &&
126 fRange != 0.0 )
128 double fPercentage = (fValue - fMin) / fRange;
129 awt::Point aPos = xAxis->getPosition();
131 if( bVertical )
133 aOutPosition.X = aPos.X;
134 aOutPosition.Y = static_cast<sal_Int32>(aPos.Y + nLength * (1.0 - fPercentage)); // y scale goes from top to bottom
136 else
138 aOutPosition.X = static_cast<sal_Int32>(aPos.X + nLength * fPercentage);
139 aOutPosition.Y = aPos.Y;
141 bRet = sal_True;
144 catch( const beans::UnknownPropertyException& )
146 // the shape xAxis was no chart axis
151 return bRet;
154 OUString SampleAddIn::getImplementationName_Static()
156 return "SampleAddIn";
159 uno::Sequence< OUString > SampleAddIn::getSupportedServiceNames_Static()
161 return {
162 "com.sun.star.chart.ChartAxisXSupplier",
163 "com.sun.star.chart.ChartAxisYSupplier",
164 "com.sun.star.chart.Diagram",
165 "com.sun.star.chart.SampleAddIn"
169 uno::Reference< uno::XInterface > SAL_CALL SampleAddIn_CreateInstance(
170 const uno::Reference< lang::XMultiServiceFactory >& )
172 uno::Reference< uno::XInterface > xInst = (cppu::OWeakObject*)new SampleAddIn();
174 return xInst;
177 // implementation of interface methods
179 // XInitialization
180 void SAL_CALL SampleAddIn::initialize( const uno::Sequence< uno::Any >& aArguments )
181 throw( uno::Exception, uno::RuntimeException )
183 // first argument should be the XChartDocument
184 OSL_ENSURE( aArguments.getLength() > 0, "Please initialize Chart AddIn with ChartDocument!" );
186 if( aArguments.getLength())
188 aArguments[ 0 ] >>= mxChartDoc;
189 OSL_ENSURE( mxChartDoc.is(), "First argument in initialization is not an XChartDocument!" );
191 // set XY chart as base type to be drawn
192 uno::Reference< beans::XPropertySet > xDocProp( mxChartDoc, uno::UNO_QUERY );
193 if( xDocProp.is())
195 uno::Any aBaseType;
196 aBaseType <<= "com.sun.star.chart.XYDiagram";
199 xDocProp->setPropertyValue( "BaseDiagram" , aBaseType );
201 catch( ... )
205 // change background of plot area to light blue
206 uno::Reference< chart::X3DDisplay > xWallSupplier( mxChartDoc->getDiagram(), uno::UNO_QUERY );
207 if( xWallSupplier.is())
209 uno::Reference< beans::XPropertySet > xDiaProp( xWallSupplier->getWall(), uno::UNO_QUERY );
210 uno::Reference< beans::XPropertySet > xLegendProp( mxChartDoc->getLegend(), uno::UNO_QUERY );
211 if( xDiaProp.is() &&
212 xLegendProp.is())
214 uno::Any aAny;
215 aAny <<= (sal_Int32)( 0xe0e0f0 );
216 xDiaProp->setPropertyValue( "FillColor" , aAny );
217 xLegendProp->setPropertyValue( "FillColor" , aAny );
223 // XRefreshable
224 /********************************************************************************
226 * The method refresh is the most important method - here all objects that
227 * are necessary for the chart are created
229 * in the first implementation you will have to insert everything in this
230 * routine - all old objects are deleted beforehand
232 ********************************************************************************/
233 void SAL_CALL SampleAddIn::refresh() throw( uno::RuntimeException )
235 if( ! mxChartDoc.is())
236 return;
238 // first of all get the draw page
239 uno::Reference< drawing::XDrawPageSupplier > xPageSupp( mxChartDoc, uno::UNO_QUERY );
240 uno::Reference< lang::XMultiServiceFactory > xFactory( mxChartDoc, uno::UNO_QUERY );
241 if( xPageSupp.is() &&
242 xFactory.is() )
244 uno::Reference< drawing::XDrawPage > xPage = xPageSupp->getDrawPage();
245 if( xPage.is())
247 // now we have the page to insert objects
249 // add a horizontal line at the middle value of the first series
251 // get the logical position from the coordinate
252 // get x- and y-axis
253 uno::Reference< drawing::XShape > xYAxisShape( getYAxis(), uno::UNO_QUERY );
254 uno::Reference< drawing::XShape > xXAxisShape( getXAxis(), uno::UNO_QUERY );
256 if( xXAxisShape.is() &&
257 xYAxisShape.is() )
259 // create line first time
260 if( ! mxMyRedLine.is())
262 mxMyRedLine.set(
263 xFactory->createInstance( "com.sun.star.drawing.LineShape" ),
264 uno::UNO_QUERY );
265 xPage->add( mxMyRedLine );
267 // make line red and thick
268 uno::Reference< beans::XPropertySet > xShapeProp( mxMyRedLine, uno::UNO_QUERY );
269 if( xShapeProp.is())
271 uno::Any aColor, aWidth;
272 aColor <<= (sal_Int32)(0xe01010);
273 aWidth <<= (sal_Int32)(50); // 0.5 mm
276 xShapeProp->setPropertyValue( "LineColor" , aColor );
277 xShapeProp->setPropertyValue( "LineWidth" , aWidth );
279 catch( ... )
283 // create text object first time
284 if( ! mxMyText.is())
286 mxMyText.set(
287 xFactory->createInstance( "com.sun.star.drawing.TextShape" ),
288 uno::UNO_QUERY );
289 xPage->add( mxMyText );
291 // change text
292 OUString aText( "Little Example" );
293 uno::Reference< beans::XPropertySet > xTextProp( mxMyText, uno::UNO_QUERY );
294 if( xTextProp.is())
296 uno::Any aTrueAny;
297 aTrueAny <<= (sal_Bool)(sal_True);
300 xTextProp->setPropertyValue( "TextAutoGrowWidth" , aTrueAny );
302 catch( ... )
306 uno::Reference< text::XTextRange > xTextRange( mxMyText, uno::UNO_QUERY );
307 if( xTextRange.is())
309 xTextRange->setString( aText );
313 // position line and text
315 // get the array. Note: the first dimension is the length
316 // of each series and the second one is the number of series
317 // this should be changed in the future
318 uno::Sequence< uno::Sequence< double > > aData;
319 uno::Reference< chart::XChartData > xData = mxChartDoc->getData();
320 uno::Reference< chart::XChartDataArray > xDataArray( xData, uno::UNO_QUERY );
321 if( xDataArray.is())
322 aData = xDataArray->getData();
324 // get row count == length of each series
325 sal_Int32 nSize = aData.getLength();
326 sal_Int32 nMiddle = nSize / 2;
327 // get value for first series
328 double fMiddleVal = xData->getNotANumber(); // set to NaN
329 if( aData[ nMiddle ].getLength()) // we have at least one series
330 fMiddleVal = aData[ nMiddle ][ 0 ];
332 awt::Point aPos;
333 getLogicalPosition( xYAxisShape, fMiddleVal, sal_True, aPos );
334 awt::Size aSize = xXAxisShape->getSize();
336 if( mxMyRedLine.is())
338 awt::Point aEnd = aPos;
339 aEnd.X += aSize.Width;
341 uno::Sequence< uno::Sequence< awt::Point > > aPtSeq( 1 );
342 aPtSeq[ 0 ].realloc( 2 );
343 aPtSeq[ 0 ][ 0 ] = aPos;
344 aPtSeq[ 0 ][ 1 ] = aEnd;
346 uno::Reference< beans::XPropertySet > xShapeProp( mxMyRedLine, uno::UNO_QUERY );
347 if( xShapeProp.is())
349 xShapeProp->setPropertyValue( "PolyPolygon" , Any(aPtSeq) );
352 if( mxMyText.is())
354 // put the text centered below the red line
355 aPos.X += ( aSize.Width - mxMyRedLine->getPosition().X ) / 2;
356 aPos.Y += 1000;
357 aPos.Y += static_cast<sal_Int32>(0.1 * xYAxisShape->getSize().Height);
358 mxMyText->setPosition( aPos );
365 void SAL_CALL SampleAddIn::addRefreshListener( const uno::Reference< util::XRefreshListener >& )
366 throw( uno::RuntimeException )
368 // not implemented - this is not necessary
369 // (this method exists just because the interface requires it)
372 void SAL_CALL SampleAddIn::removeRefreshListener( const uno::Reference< util::XRefreshListener >& )
373 throw( uno::RuntimeException )
375 // not implemented - this is not necessary
376 // (this method exists just because the interface requires it)
379 // XDiagram
380 OUString SAL_CALL SampleAddIn::getDiagramType() throw( uno::RuntimeException )
382 return "com.sun.star.chart.SampleDiagram";
385 // the following methods just delegate to the "parent diagram" (which in the future might no longer exist)
387 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDataRowProperties( sal_Int32 nRow )
388 throw( lang::IndexOutOfBoundsException,
389 uno::RuntimeException )
391 if( mxChartDoc.is())
393 uno::Reference< chart::XDiagram > xDia = mxChartDoc->getDiagram();
394 if( xDia.is())
395 return xDia->getDataRowProperties( nRow );
398 return uno::Reference< beans::XPropertySet >();
401 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDataPointProperties( sal_Int32 nCol, sal_Int32 nRow )
402 throw( lang::IndexOutOfBoundsException,
403 uno::RuntimeException )
405 if( mxChartDoc.is())
407 uno::Reference< chart::XDiagram > xDia = mxChartDoc->getDiagram();
408 if( xDia.is())
409 return xDia->getDataPointProperties( nCol, nRow );
412 return uno::Reference< beans::XPropertySet >();
415 // XShape ( ::XDiagram )
416 awt::Size SAL_CALL SampleAddIn::getSize()
417 throw( uno::RuntimeException )
419 if( mxChartDoc.is())
421 uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
422 if( xShape.is())
423 return xShape->getSize();
426 return awt::Size();
429 void SAL_CALL SampleAddIn::setSize( const awt::Size& aSize )
430 throw( beans::PropertyVetoException, uno::RuntimeException )
432 if( mxChartDoc.is())
434 uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
435 if( xShape.is())
436 xShape->setSize( aSize );
440 awt::Point SAL_CALL SampleAddIn::getPosition()
441 throw( uno::RuntimeException )
443 if( mxChartDoc.is())
445 uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
446 if( xShape.is())
447 return xShape->getPosition();
450 return awt::Point();
453 void SAL_CALL SampleAddIn::setPosition( const awt::Point& aPos )
454 throw( uno::RuntimeException )
456 if( mxChartDoc.is())
458 uno::Reference< drawing::XShape > xShape( mxChartDoc->getDiagram(), uno::UNO_QUERY );
459 if( xShape.is())
460 xShape->setPosition( aPos );
464 // XShapeDescriptor ( ::XShape ::XDiagram )
465 OUString SAL_CALL SampleAddIn::getShapeType() throw( css::uno::RuntimeException )
467 return "com.sun.star.chart.SampleAddinShape";
470 // XAxisXSupplier
471 uno::Reference< drawing::XShape > SAL_CALL SampleAddIn::getXAxisTitle()
472 throw( uno::RuntimeException )
474 if( mxChartDoc.is())
476 uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
477 if( xAxisSupp.is())
478 return xAxisSupp->getXAxisTitle();
481 return uno::Reference< drawing::XShape >();
484 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXAxis()
485 throw( uno::RuntimeException )
487 if( mxChartDoc.is())
489 uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
490 if( xAxisSupp.is())
491 return xAxisSupp->getXAxis();
494 return uno::Reference< beans::XPropertySet >();
497 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXMainGrid()
498 throw( uno::RuntimeException )
500 if( mxChartDoc.is())
502 uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
503 if( xAxisSupp.is())
504 return xAxisSupp->getXMainGrid();
507 return uno::Reference< beans::XPropertySet >();
510 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getXHelpGrid()
511 throw( uno::RuntimeException )
513 if( mxChartDoc.is())
515 uno::Reference< chart::XAxisXSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
516 if( xAxisSupp.is())
517 return xAxisSupp->getXHelpGrid();
520 return uno::Reference< beans::XPropertySet >();
523 // XAxisYSupplier
524 uno::Reference< drawing::XShape > SAL_CALL SampleAddIn::getYAxisTitle()
525 throw( uno::RuntimeException )
527 if( mxChartDoc.is())
529 uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
530 if( xAxisSupp.is())
531 return xAxisSupp->getYAxisTitle();
534 return uno::Reference< drawing::XShape >();
537 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYAxis()
538 throw( uno::RuntimeException )
540 if( mxChartDoc.is())
542 uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
543 if( xAxisSupp.is())
544 return xAxisSupp->getYAxis();
547 return uno::Reference< beans::XPropertySet >();
550 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYMainGrid()
551 throw( uno::RuntimeException )
553 if( mxChartDoc.is())
555 uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
556 if( xAxisSupp.is())
557 return xAxisSupp->getYMainGrid();
560 return uno::Reference< beans::XPropertySet >();
563 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getYHelpGrid()
564 throw( uno::RuntimeException )
566 if( mxChartDoc.is())
568 uno::Reference< chart::XAxisYSupplier > xAxisSupp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
569 if( xAxisSupp.is())
570 return xAxisSupp->getYHelpGrid();
573 return uno::Reference< beans::XPropertySet >();
576 // XStatisticDisplay
577 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getUpBar()
578 throw( uno::RuntimeException )
580 if( mxChartDoc.is())
582 uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
583 if( xStatDisp.is())
584 return xStatDisp->getUpBar();
587 return uno::Reference< beans::XPropertySet >();
590 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getDownBar()
591 throw( uno::RuntimeException )
593 if( mxChartDoc.is())
595 uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
596 if( xStatDisp.is())
597 return xStatDisp->getDownBar();
600 return uno::Reference< beans::XPropertySet >();
603 uno::Reference< beans::XPropertySet > SAL_CALL SampleAddIn::getMinMaxLine()
604 throw( uno::RuntimeException )
606 if( mxChartDoc.is())
608 uno::Reference< chart::XStatisticDisplay > xStatDisp( mxChartDoc->getDiagram(), uno::UNO_QUERY );
609 if( xStatDisp.is())
610 return xStatDisp->getMinMaxLine();
613 return uno::Reference< beans::XPropertySet >();
616 // XServiceName
617 OUString SAL_CALL SampleAddIn::getServiceName() throw( uno::RuntimeException )
619 return "com.sun.star.chart.SampleAddIn";
622 // XServiceInfo
623 OUString SAL_CALL SampleAddIn::getImplementationName() throw( uno::RuntimeException )
625 return getImplementationName_Static();
628 sal_Bool SAL_CALL SampleAddIn::supportsService( const OUString& ServiceName )
629 throw( uno::RuntimeException )
631 return cppu::supportsService(this, ServiceName);
634 uno::Sequence< OUString > SAL_CALL SampleAddIn::getSupportedServiceNames()
635 throw( uno::RuntimeException )
637 return getSupportedServiceNames_Static();
640 // XLocalizable
641 void SAL_CALL SampleAddIn::setLocale( const lang::Locale& eLocale )
642 throw( uno::RuntimeException )
644 maLocale = eLocale;
647 lang::Locale SAL_CALL SampleAddIn::getLocale()
648 throw( uno::RuntimeException )
650 return maLocale;
653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */