LibreOffice Module chart2 (master) 1
LegendWrapper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "LegendWrapper.hxx"
24#include <com/sun/star/beans/PropertyAttribute.hpp>
25#include <com/sun/star/chart/ChartLegendPosition.hpp>
26#include <com/sun/star/chart2/LegendPosition.hpp>
27#include <com/sun/star/chart/ChartLegendExpansion.hpp>
28#include <com/sun/star/chart2/RelativePosition.hpp>
29
32#include <FillProperties.hxx>
39
40#include <algorithm>
41#include <utility>
42
43using namespace ::com::sun::star;
44using ::com::sun::star::beans::Property;
45using ::com::sun::star::uno::Any;
46using ::com::sun::star::uno::Reference;
47using ::com::sun::star::uno::Sequence;
48
49namespace chart
50{
51namespace {
52
53class WrappedLegendAlignmentProperty : public WrappedProperty
54{
55public:
56 WrappedLegendAlignmentProperty();
57
58 virtual void setPropertyValue( const Any& rOuterValue, const Reference< beans::XPropertySet >& xInnerPropertySet ) const override;
59 virtual Any getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const override;
60
61protected:
62 virtual Any convertInnerToOuterValue( const Any& rInnerValue ) const override;
63 virtual Any convertOuterToInnerValue( const Any& rOuterValue ) const override;
64};
65
66}
67
68WrappedLegendAlignmentProperty::WrappedLegendAlignmentProperty()
69 : ::chart::WrappedProperty( "Alignment", "AnchorPosition" )
70{
71}
72
73Any WrappedLegendAlignmentProperty::getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const
74{
75 Any aRet;
76 if( xInnerPropertySet.is() )
77 {
78 bool bShowLegend = true;
79 xInnerPropertySet->getPropertyValue( "Show" ) >>= bShowLegend;
80 if(!bShowLegend)
81 {
82 aRet <<= css::chart::ChartLegendPosition_NONE;
83 }
84 else
85 {
86 aRet = xInnerPropertySet->getPropertyValue( m_aInnerName );
87 aRet = convertInnerToOuterValue( aRet );
88 }
89 }
90 return aRet;
91}
92
93void WrappedLegendAlignmentProperty::setPropertyValue( const Any& rOuterValue, const Reference< beans::XPropertySet >& xInnerPropertySet ) const
94{
95 if(!xInnerPropertySet.is())
96 return;
97
98 bool bNewShowLegend = true;
99 bool bOldShowLegend = true;
100 {
101 css::chart::ChartLegendPosition eOuterPos(css::chart::ChartLegendPosition_NONE);
102 if( (rOuterValue >>= eOuterPos) && eOuterPos == css::chart::ChartLegendPosition_NONE )
103 bNewShowLegend = false;
104 xInnerPropertySet->getPropertyValue( "Show" ) >>= bOldShowLegend;
105 }
106 if(bNewShowLegend!=bOldShowLegend)
107 {
108 xInnerPropertySet->setPropertyValue( "Show", uno::Any(bNewShowLegend) );
109 }
110 if(!bNewShowLegend)
111 return;
112
113 //set corresponding LegendPosition
114 Any aInnerValue = convertOuterToInnerValue( rOuterValue );
115 xInnerPropertySet->setPropertyValue( m_aInnerName, aInnerValue );
116
117 //correct LegendExpansion
118 chart2::LegendPosition eNewInnerPos(chart2::LegendPosition_LINE_END);
119 if( aInnerValue >>= eNewInnerPos )
120 {
121 css::chart::ChartLegendExpansion eNewExpansion =
122 ( eNewInnerPos == chart2::LegendPosition_LINE_END ||
123 eNewInnerPos == chart2::LegendPosition_LINE_START )
124 ? css::chart::ChartLegendExpansion_HIGH
125 : css::chart::ChartLegendExpansion_WIDE;
126
127 css::chart::ChartLegendExpansion eOldExpansion( css::chart::ChartLegendExpansion_HIGH );
128 bool bExpansionWasSet(
129 xInnerPropertySet->getPropertyValue( "Expansion" ) >>= eOldExpansion );
130
131 if( !bExpansionWasSet || (eOldExpansion != eNewExpansion))
132 xInnerPropertySet->setPropertyValue( "Expansion", uno::Any( eNewExpansion ));
133 }
134
135 //correct RelativePosition
136 Any aRelativePosition( xInnerPropertySet->getPropertyValue("RelativePosition") );
137 if(aRelativePosition.hasValue())
138 {
139 xInnerPropertySet->setPropertyValue( "RelativePosition", Any() );
140 }
141}
142
143Any WrappedLegendAlignmentProperty::convertInnerToOuterValue( const Any& rInnerValue ) const
144{
145 css::chart::ChartLegendPosition ePos = css::chart::ChartLegendPosition_NONE;
146
147 chart2::LegendPosition eNewPos;
148 if( rInnerValue >>= eNewPos )
149 {
150 switch( eNewPos )
151 {
152 case chart2::LegendPosition_LINE_START:
153 ePos = css::chart::ChartLegendPosition_LEFT;
154 break;
155 case chart2::LegendPosition_LINE_END:
156 ePos = css::chart::ChartLegendPosition_RIGHT;
157 break;
158 case chart2::LegendPosition_PAGE_START:
159 ePos = css::chart::ChartLegendPosition_TOP;
160 break;
161 case chart2::LegendPosition_PAGE_END:
162 ePos = css::chart::ChartLegendPosition_BOTTOM;
163 break;
164
165 default:
166 ePos = css::chart::ChartLegendPosition_NONE;
167 break;
168 }
169 }
170 return uno::Any( ePos );
171}
172Any WrappedLegendAlignmentProperty::convertOuterToInnerValue( const Any& rOuterValue ) const
173{
174 chart2::LegendPosition eNewPos = chart2::LegendPosition_LINE_END;
175
176 css::chart::ChartLegendPosition ePos;
177 if( rOuterValue >>= ePos )
178 {
179 switch( ePos )
180 {
181 case css::chart::ChartLegendPosition_LEFT:
182 eNewPos = chart2::LegendPosition_LINE_START;
183 break;
184 case css::chart::ChartLegendPosition_RIGHT:
185 eNewPos = chart2::LegendPosition_LINE_END;
186 break;
187 case css::chart::ChartLegendPosition_TOP:
188 eNewPos = chart2::LegendPosition_PAGE_START;
189 break;
190 case css::chart::ChartLegendPosition_BOTTOM:
191 eNewPos = chart2::LegendPosition_PAGE_END;
192 break;
193 default: // NONE
194 break;
195 }
196 }
197
198 return uno::Any( eNewPos );
199}
200}
201
202namespace
203{
204
205enum
206{
207 PROP_LEGEND_ALIGNMENT,
208 PROP_LEGEND_EXPANSION
209};
210
211void lcl_AddPropertiesToVector(
212 std::vector< Property > & rOutProperties )
213{
214 rOutProperties.emplace_back( "Alignment",
215 PROP_LEGEND_ALIGNMENT,
217 //#i111967# no PropertyChangeEvent is fired on change so far
218 beans::PropertyAttribute::MAYBEDEFAULT );
219
220 rOutProperties.emplace_back( "Expansion",
221 PROP_LEGEND_EXPANSION,
223 //#i111967# no PropertyChangeEvent is fired on change so far
224 beans::PropertyAttribute::MAYBEDEFAULT );
225}
226
227const Sequence< Property >& StaticLegendWrapperPropertyArray()
228{
229 static Sequence< Property > aPropSeq = []()
230 {
231 std::vector< css::beans::Property > aProperties;
232 lcl_AddPropertiesToVector( aProperties );
239
240 std::sort( aProperties.begin(), aProperties.end(),
242
243 return comphelper::containerToSequence( aProperties );
244 }();
245 return aPropSeq;
246};
247
248} // anonymous namespace
249
250namespace chart::wrapper
251{
252
253LegendWrapper::LegendWrapper(std::shared_ptr<Chart2ModelContact> spChart2ModelContact)
254 : m_spChart2ModelContact(std::move(spChart2ModelContact))
255{
256}
257
259{
260}
261
262// ____ XShape ____
263awt::Point SAL_CALL LegendWrapper::getPosition()
264{
265 return m_spChart2ModelContact->GetLegendPosition();
266}
267
268void SAL_CALL LegendWrapper::setPosition( const awt::Point& aPosition )
269{
271 if( xProp.is() )
272 {
273 awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() );
274
275 chart2::RelativePosition aRelativePosition;
276 aRelativePosition.Anchor = drawing::Alignment_TOP_LEFT;
277 aRelativePosition.Primary = aPageSize.Width == 0 ? 0 : double(aPosition.X)/double(aPageSize.Width);
278 aRelativePosition.Secondary = aPageSize.Height == 0 ? 0 : double(aPosition.Y)/double(aPageSize.Height);
279 xProp->setPropertyValue( "RelativePosition", uno::Any(aRelativePosition) );
280 }
281}
282
283awt::Size SAL_CALL LegendWrapper::getSize()
284{
285 return m_spChart2ModelContact->GetLegendSize();
286}
287
288void SAL_CALL LegendWrapper::setSize( const awt::Size& aSize )
289{
291 if( xProp.is() )
292 {
293 awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() );
294 awt::Rectangle aPageRectangle( 0,0,aPageSize.Width,aPageSize.Height);
295
296 awt::Point aPos( getPosition() );
297 awt::Rectangle aNewPositionAndSize(aPos.X,aPos.Y,aSize.Width,aSize.Height);
298
300 , xProp, aNewPositionAndSize, awt::Rectangle(), aPageRectangle );
301 }
302}
303
304// ____ XShapeDescriptor (base of XShape) ____
306{
307 return "com.sun.star.chart.ChartLegend";
308}
309
310// ____ XComponent ____
312{
313 std::unique_lock g(m_aMutex);
314 Reference< uno::XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
315 m_aEventListenerContainer.disposeAndClear( g, lang::EventObject( xSource ) );
316
317 clearWrappedPropertySet();
318}
319
321 const Reference< lang::XEventListener >& xListener )
322{
323 std::unique_lock g(m_aMutex);
325}
326
328 const Reference< lang::XEventListener >& aListener )
329{
330 std::unique_lock g(m_aMutex);
332}
333
334//ReferenceSizePropertyProvider
336{
338 if( xProp.is() )
339 {
340 if( xProp->getPropertyValue( "ReferencePageSize" ).hasValue() )
341 xProp->setPropertyValue( "ReferencePageSize", uno::Any(
342 m_spChart2ModelContact->GetPageSize() ));
343 }
344}
346{
347 Any aRet;
349 if( xProp.is() )
350 aRet = xProp->getPropertyValue( "ReferencePageSize" );
351
352 return aRet;
353}
355{
356 return m_spChart2ModelContact->GetPageSize();
357}
358
359// WrappedPropertySet
361{
364 if( xDiagram.is() )
365 xRet.set( xDiagram->getLegend(), uno::UNO_QUERY );
366 OSL_ENSURE(xRet.is(),"LegendWrapper::getInnerPropertySet() is NULL");
367 return xRet;
368}
369
371{
372 return StaticLegendWrapperPropertyArray();
373}
374
375std::vector< std::unique_ptr<WrappedProperty> > LegendWrapper::createWrappedProperties()
376{
377 std::vector< std::unique_ptr<WrappedProperty> > aWrappedProperties;
378
379 aWrappedProperties.emplace_back( new WrappedLegendAlignmentProperty() );
380 aWrappedProperties.emplace_back( new WrappedProperty( "Expansion", "Expansion"));
382 //same problem as for wall: the defaults in the old chart are different for different charttypes, so we need to export explicitly
383 aWrappedProperties.emplace_back( new WrappedDirectStateProperty("FillStyle", "FillStyle"));
384 aWrappedProperties.emplace_back( new WrappedDirectStateProperty("FillColor", "FillColor"));
387
388 return aWrappedProperties;
389}
390
392{
393 return "com.sun.star.comp.chart.Legend";
394}
395
396sal_Bool SAL_CALL LegendWrapper::supportsService( const OUString& rServiceName )
397{
398 return cppu::supportsService(this, rServiceName);
399}
400
401css::uno::Sequence< OUString > SAL_CALL LegendWrapper::getSupportedServiceNames()
402{
403 return {
404 "com.sun.star.chart.ChartLegend",
405 "com.sun.star.drawing.Shape",
406 "com.sun.star.xml.UserDefinedAttributesSupplier",
407 "com.sun.star.style.CharacterProperties"
408 };
409}
410
411} // namespace chart::wrapper
412
413/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::chart::ChartAxisLabelPosition ePos
std::shared_ptr< Chart2ModelContact > m_spChart2ModelContact
PropertiesInfo aProperties
static bool moveObject(ObjectType eObjectType, const css::uno::Reference< css::beans::XPropertySet > &xObjectProp, const css::awt::Rectangle &rNewPositionAndSize, const css::awt::Rectangle &rOldPositionAndSize, const css::awt::Rectangle &rPageRectangle)
virtual void updateReferenceSize() override
virtual css::awt::Point SAL_CALL getPosition() override
virtual OUString SAL_CALL getImplementationName() override
XServiceInfo declarations.
virtual const css::uno::Sequence< css::beans::Property > & getPropertySequence() override
virtual void SAL_CALL setSize(const css::awt::Size &aSize) override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
virtual ~LegendWrapper() override
virtual void SAL_CALL dispose() override
virtual std::vector< std::unique_ptr< WrappedProperty > > createWrappedProperties() override
virtual OUString SAL_CALL getShapeType() override
virtual void SAL_CALL setPosition(const css::awt::Point &aPosition) override
virtual css::uno::Any getReferenceSize() override
std::shared_ptr< Chart2ModelContact > m_spChart2ModelContact
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
virtual css::uno::Reference< css::beans::XPropertySet > getInnerPropertySet() override
LegendWrapper(std::shared_ptr< Chart2ModelContact > spChart2ModelContact)
virtual css::awt::Size SAL_CALL getSize() override
::comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_aEventListenerContainer
virtual css::awt::Size getCurrentSizeForReference() override
static void addWrappedProperties(std::vector< std::unique_ptr< WrappedProperty > > &rList)
static void addProperties(std::vector< css::beans::Property > &rOutProperties)
static void addWrappedProperties(std::vector< std::unique_ptr< WrappedProperty > > &rList, ReferenceSizePropertyProvider *pRefSizePropProvider)
static void addProperties(std::vector< css::beans::Property > &rOutProperties)
static void addWrappedProperties(std::vector< std::unique_ptr< WrappedProperty > > &rList, const std::shared_ptr< Chart2ModelContact > &spChart2ModelContact)
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(::std::unique_lock<::std::mutex > &rGuard, const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
std::mutex m_aMutex
OOO_DLLPUBLIC_CHARTTOOLS void AddPropertiesToVector(std::vector< css::beans::Property > &rOutProperties)
void setPropertyValue(tPropertyValueMap &rOutMap, tPropertyValueMapKey key, const Value &value)
Set a property to a certain value in the given map.
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
unsigned char sal_Bool