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 <VLegendSymbolFactory.hxx>
21 #include <PropertyMapper.hxx>
22 #include <ShapeFactory.hxx>
23 #include <com/sun/star/drawing/Position3D.hpp>
24 #include <com/sun/star/chart2/Symbol.hpp>
25 #include <com/sun/star/drawing/XShapes.hpp>
26 #include <com/sun/star/drawing/Direction3D.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <tools/diagnose_ex.h>
29 #include <sal/log.hxx>
30
31 using namespace ::com::sun::star;
32 using ::com::sun::star::uno::Reference;
33
34 namespace
35 {
36
getPropNamesAndValues(const Reference<beans::XPropertySet> & xProp,::chart::tNameSequence & rNames,::chart::tAnySequence & rValues,::chart::VLegendSymbolFactory::PropertyType ePropertyType,const awt::Size & aMaxSymbolExtent)37 void getPropNamesAndValues( const Reference< beans::XPropertySet >& xProp,
38 ::chart::tNameSequence& rNames,
39 ::chart::tAnySequence& rValues,
40 ::chart::VLegendSymbolFactory::PropertyType ePropertyType,
41 const awt::Size& aMaxSymbolExtent)
42 {
43 const ::chart::tPropertyNameMap & aFilledSeriesNameMap( ::chart::PropertyMapper::getPropertyNameMapForFilledSeriesProperties());
44 const ::chart::tPropertyNameMap & aLineSeriesNameMap( ::chart::PropertyMapper::getPropertyNameMapForLineSeriesProperties());
45 const ::chart::tPropertyNameMap & aLineNameMap( ::chart::PropertyMapper::getPropertyNameMapForLineProperties());
46
47 ::chart::tPropertyNameValueMap aValueMap;
48 switch( ePropertyType )
49 {
50 case ::chart::VLegendSymbolFactory::PropertyType::FilledSeries:
51 ::chart::PropertyMapper::getValueMap( aValueMap, aFilledSeriesNameMap, xProp );
52 break;
53 case ::chart::VLegendSymbolFactory::PropertyType::LineSeries:
54 ::chart::PropertyMapper::getValueMap( aValueMap, aLineSeriesNameMap, xProp );
55 break;
56 case ::chart::VLegendSymbolFactory::PropertyType::Line:
57 ::chart::PropertyMapper::getValueMap( aValueMap, aLineNameMap, xProp );
58 break;
59 }
60
61 ::chart::PropertyMapper::getMultiPropertyListsFromValueMap( rNames, rValues, aValueMap );
62
63 uno::Any* pLineWidthAny = ::chart::PropertyMapper::getValuePointer(rValues,rNames,"LineWidth");
64 sal_Int32 nLineWidth = 0;
65 if( pLineWidthAny && (*pLineWidthAny>>=nLineWidth) )
66 {
67 // use legend entry height as upper limit for line width
68 sal_Int32 nMaxLineWidthForLegend = aMaxSymbolExtent.Height;
69 if( nLineWidth>nMaxLineWidthForLegend )
70 *pLineWidthAny <<= nMaxLineWidthForLegend;
71 }
72 }
73
lcl_setPropertiesToShape(const Reference<beans::XPropertySet> & xProp,const Reference<drawing::XShape> & xShape,::chart::VLegendSymbolFactory::PropertyType ePropertyType,const awt::Size & aMaxSymbolExtent)74 void lcl_setPropertiesToShape(
75 const Reference< beans::XPropertySet > & xProp,
76 const Reference< drawing::XShape > & xShape,
77 ::chart::VLegendSymbolFactory::PropertyType ePropertyType,
78 const awt::Size& aMaxSymbolExtent)
79 {
80 ::chart::tNameSequence aPropNames;
81 ::chart::tAnySequence aPropValues;
82 getPropNamesAndValues( xProp, aPropNames, aPropValues,
83 ePropertyType, aMaxSymbolExtent );
84
85 Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
86 ::chart::PropertyMapper::setMultiProperties( aPropNames, aPropValues, xShapeProp );
87 }
88
89 } // anonymous namespace
90
91 namespace chart
92 {
93
createSymbol(const awt::Size & rEntryKeyAspectRatio,const Reference<drawing::XShapes> & rSymbolContainer,LegendSymbolStyle eStyle,const Reference<lang::XMultiServiceFactory> & xShapeFactory,const Reference<beans::XPropertySet> & xLegendEntryProperties,PropertyType ePropertyType,const uno::Any & rExplicitSymbol)94 Reference< drawing::XShape > VLegendSymbolFactory::createSymbol(
95 const awt::Size& rEntryKeyAspectRatio,
96 const Reference< drawing::XShapes >& rSymbolContainer,
97 LegendSymbolStyle eStyle,
98 const Reference< lang::XMultiServiceFactory > & xShapeFactory,
99 const Reference< beans::XPropertySet > & xLegendEntryProperties,
100 PropertyType ePropertyType, const uno::Any& rExplicitSymbol )
101 {
102 Reference< drawing::XShape > xResult;
103
104 if( ! (rSymbolContainer.is() && xShapeFactory.is()))
105 return xResult;
106
107 ShapeFactory* pShapeFactory = ShapeFactory::getOrCreateShapeFactory(xShapeFactory);
108 xResult.set( pShapeFactory->createGroup2D( rSymbolContainer ), uno::UNO_QUERY );
109
110 Reference< drawing::XShapes > xResultGroup( xResult, uno::UNO_QUERY );
111 if( ! xResultGroup.is())
112 return xResult;
113
114 // add an invisible square box to maintain aspect ratio
115 Reference< drawing::XShape > xBound( pShapeFactory->createInvisibleRectangle(
116 xResultGroup, rEntryKeyAspectRatio ));
117
118 // create symbol
119 try
120 {
121 if( eStyle == LegendSymbolStyle::Line )
122 {
123 Reference< drawing::XShape > xLine =
124 pShapeFactory->createLine( xResultGroup, awt::Size( rEntryKeyAspectRatio.Width, 0 ),
125 awt::Point( 0, rEntryKeyAspectRatio.Height/2 ));
126 if( xLine.is())
127 {
128 lcl_setPropertiesToShape( xLegendEntryProperties, xLine, ePropertyType, rEntryKeyAspectRatio );
129 }
130
131 Reference< drawing::XShape > xSymbol;
132 const sal_Int32 nSize = std::min(rEntryKeyAspectRatio.Width,rEntryKeyAspectRatio.Height);
133 chart2::Symbol aSymbol;
134 if( rExplicitSymbol >>= aSymbol )
135 {
136 drawing::Direction3D aSymbolSize( nSize, nSize, 0 );
137 drawing::Position3D aPos( rEntryKeyAspectRatio.Width/2.0, rEntryKeyAspectRatio.Height/2.0, 0 );
138 ShapeFactory* pFactory = ShapeFactory::getOrCreateShapeFactory( xShapeFactory );
139 if( aSymbol.Style == chart2::SymbolStyle_STANDARD )
140 {
141 // take series color as fill color
142 xLegendEntryProperties->getPropertyValue( "Color") >>= aSymbol.FillColor;
143 // border of symbols always same as fill color
144 aSymbol.BorderColor = aSymbol.FillColor;
145
146 xSymbol.set( pFactory->createSymbol2D(
147 xResultGroup,
148 aPos,
149 aSymbolSize,
150 aSymbol.StandardSymbol,
151 aSymbol.BorderColor,
152 aSymbol.FillColor ));
153 }
154 else if( aSymbol.Style == chart2::SymbolStyle_GRAPHIC )
155 {
156 xSymbol.set( pFactory->createGraphic2D(
157 xResultGroup,
158 aPos,
159 aSymbolSize,
160 aSymbol.Graphic ));
161 }
162 else if( aSymbol.Style == chart2::SymbolStyle_AUTO )
163 {
164 SAL_WARN("chart2", "the given parameter is not allowed to contain an automatic symbol style");
165 }
166 }
167 }
168 else if( eStyle == LegendSymbolStyle::Circle )
169 {
170 sal_Int32 nSize = std::min( rEntryKeyAspectRatio.Width, rEntryKeyAspectRatio.Height );
171 Reference< drawing::XShape > xShape =
172 pShapeFactory->createCircle( xResultGroup, awt::Size( nSize, nSize ),
173 awt::Point( rEntryKeyAspectRatio.Width/2-nSize/2, rEntryKeyAspectRatio.Height/2-nSize/2 ));
174 if( xShape.is() )
175 {
176 lcl_setPropertiesToShape( xLegendEntryProperties, xShape, ePropertyType, awt::Size(0,0) ); // PropertyType::FilledSeries );
177 }
178 }
179 else // eStyle == LegendSymbolStyle::Box
180 {
181 tNameSequence aPropNames;
182 tAnySequence aPropValues;
183
184 getPropNamesAndValues( xLegendEntryProperties, aPropNames, aPropValues,
185 ePropertyType, awt::Size(0,0) );// PropertyType::FilledSeries
186
187 pShapeFactory->createRectangle( xResultGroup,
188 rEntryKeyAspectRatio, awt::Point( 0, 0 ),
189 aPropNames, aPropValues );
190 }
191 }
192 catch( const uno::Exception & )
193 {
194 DBG_UNHANDLED_EXCEPTION("chart2");
195 }
196
197 return xResult;
198 }
199
200 } // namespace chart
201
202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
203