1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 #include "VTitle.hxx"
27 #include "CommonConverters.hxx"
28 #include "macros.hxx"
29 #include "PropertyMapper.hxx"
30 #include "ShapeFactory.hxx"
31 #include "RelativeSizeHelper.hxx"
32 #include <com/sun/star/chart2/XFormattedString.hpp>
33 #include <rtl/math.hxx>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
36 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
37 #include <com/sun/star/text/ControlCharacter.hpp>
38 #include <com/sun/star/text/XText.hpp>
39 #include <com/sun/star/text/XTextCursor.hpp>
40
41 //.............................................................................
42 namespace chart
43 {
44 //.............................................................................
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::chart2;
47
VTitle(const uno::Reference<XTitle> & xTitle)48 VTitle::VTitle( const uno::Reference< XTitle > & xTitle )
49 : m_xTarget(NULL)
50 , m_xShapeFactory(NULL)
51 , m_xTitle(xTitle)
52 , m_xShape(NULL)
53 , m_aCID()
54 , m_fRotationAngleDegree(0.0)
55 , m_nXPos(0)
56 , m_nYPos(0)
57 {
58 }
59
~VTitle()60 VTitle::~VTitle()
61 {
62 }
63
init(const uno::Reference<drawing::XShapes> & xTargetPage,const uno::Reference<lang::XMultiServiceFactory> & xFactory,const rtl::OUString & rCID)64 void VTitle::init(
65 const uno::Reference< drawing::XShapes >& xTargetPage
66 , const uno::Reference< lang::XMultiServiceFactory >& xFactory
67 , const rtl::OUString& rCID )
68 {
69 m_xTarget = xTargetPage;
70 m_xShapeFactory = xFactory;
71 m_aCID = rCID;
72 }
73
getRotationAnglePi() const74 double VTitle::getRotationAnglePi() const
75 {
76 return m_fRotationAngleDegree*F_PI/180.0;
77 }
78
getUnrotatedSize() const79 awt::Size VTitle::getUnrotatedSize() const //size before rotation
80 {
81 awt::Size aRet;
82 if(m_xShape.is())
83 aRet = m_xShape->getSize();
84 return aRet;
85 }
86
getFinalSize() const87 awt::Size VTitle::getFinalSize() const //size after rotation
88 {
89 return ShapeFactory::getSizeAfterRotation(
90 m_xShape, m_fRotationAngleDegree );
91 }
92
changePosition(const awt::Point & rPos)93 void VTitle::changePosition( const awt::Point& rPos )
94 {
95 if(!m_xShape.is())
96 return;
97 uno::Reference< beans::XPropertySet > xShapeProp( m_xShape, uno::UNO_QUERY );
98 if(!xShapeProp.is())
99 return;
100 try
101 {
102 m_nXPos = rPos.X;
103 m_nYPos = rPos.Y;
104
105 //set position matrix
106 //the matrix needs to be set at the end behind autogrow and such position influencing properties
107 ::basegfx::B2DHomMatrix aM;
108 aM.rotate( -m_fRotationAngleDegree*F_PI/180.0 );//#i78696#->#i80521#
109 aM.translate( m_nXPos, m_nYPos);
110 xShapeProp->setPropertyValue( C2U( "Transformation" ), uno::makeAny( B2DHomMatrixToHomogenMatrix3(aM) ) );
111 }
112 catch( uno::Exception& e )
113 {
114 ASSERT_EXCEPTION( e );
115 }
116 }
117
createShapes(const awt::Point & rPos,const awt::Size & rReferenceSize)118 void VTitle::createShapes(
119 const awt::Point& rPos
120 , const awt::Size& rReferenceSize )
121 {
122 try
123 {
124 if(!m_xTitle.is())
125 return;
126
127 uno::Sequence< uno::Reference< XFormattedString > > aStringList = m_xTitle->getText();
128 if(aStringList.getLength()<=0)
129 return;
130
131 //create shape and add to page
132 uno::Reference< drawing::XShape > xShape(
133 m_xShapeFactory->createInstance( C2U(
134 "com.sun.star.drawing.TextShape" ) ), uno::UNO_QUERY );
135 m_xTarget->add(xShape);
136 m_xShape = xShape;
137
138 //set text and text properties
139 uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
140 uno::Reference< text::XTextCursor > xTextCursor( xText->createTextCursor() );
141 uno::Reference< text::XTextRange > xTextRange( xTextCursor, uno::UNO_QUERY );
142 uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
143 uno::Reference< beans::XPropertySet > xTitleProperties( m_xTitle, uno::UNO_QUERY );
144 if( !xText.is() || !xTextRange.is() || !xTextCursor.is() || !xShapeProp.is() || !xTitleProperties.is() )
145 return;
146
147 tPropertyNameValueMap aValueMap;
148 //fill line-, fill- and paragraph-properties into the ValueMap
149 {
150 tMakePropertyNameMap aNameMap = PropertyMapper::getPropertyNameMapForParagraphProperties();
151 aNameMap( PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
152
153 PropertyMapper::getValueMap( aValueMap, aNameMap, xTitleProperties );
154 }
155
156 //fill some more shape properties into the ValueMap
157 {
158 drawing::TextHorizontalAdjust eHorizontalAdjust = drawing::TextHorizontalAdjust_CENTER;
159 drawing::TextVerticalAdjust eVerticalAdjust = drawing::TextVerticalAdjust_CENTER;
160 //text::WritingMode eWritingMode = text::WritingMode_LR_TB;//@todo get correct one
161
162 aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextHorizontalAdjust"), uno::makeAny(eHorizontalAdjust) ) ); // drawing::TextHorizontalAdjust
163 aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextVerticalAdjust"), uno::makeAny(eVerticalAdjust) ) ); //drawing::TextVerticalAdjust
164 //aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextWritingMode"), uno::makeAny(eWritingMode) ) ); //text::WritingMode
165 aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextAutoGrowHeight"), uno::makeAny(sal_True) ) ); // sal_Bool
166 aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextAutoGrowWidth"), uno::makeAny(sal_True) ) ); // sal_Bool
167
168 ////aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextMaximumFrameWidth"), uno::makeAny(rSize.Width) ) ); //sal_Int32
169 ////aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextMaximumFrameHeight"), uno::makeAny(rSize.Height) ) ); //sal_Int32
170
171 //set name/classified ObjectID (CID)
172 if( !m_aCID.isEmpty() )
173 aValueMap.insert( tPropertyNameValueMap::value_type( C2U("Name"), uno::makeAny( m_aCID ) ) ); //CID rtl::OUString
174 }
175
176 //set global title properties
177 {
178 tNameSequence aPropNames;
179 tAnySequence aPropValues;
180 PropertyMapper::getMultiPropertyListsFromValueMap( aPropNames, aPropValues, aValueMap );
181 PropertyMapper::setMultiProperties( aPropNames, aPropValues, xShapeProp );
182 }
183
184 sal_Bool bStackCharacters(sal_False);
185 try
186 {
187 xTitleProperties->getPropertyValue( C2U( "StackCharacters" ) ) >>= bStackCharacters;
188 }
189 catch( uno::Exception& e )
190 {
191 ASSERT_EXCEPTION( e );
192 }
193 if(bStackCharacters)
194 {
195 //if the characters should be stacked we use only the first character properties for code simplicity
196 if( aStringList.getLength()>0 )
197 {
198 rtl::OUString aLabel;
199 for( sal_Int32 nN=0; nN<aStringList.getLength();nN++ )
200 aLabel += aStringList[nN]->getString();
201 aLabel = ShapeFactory::getStackedString( aLabel, bStackCharacters );
202
203 xTextCursor->gotoEnd(false);
204 xText->insertString( xTextRange, aLabel, false );
205 xTextCursor->gotoEnd(true);
206 uno::Reference< beans::XPropertySet > xTargetProps( xShape, uno::UNO_QUERY );
207 uno::Reference< beans::XPropertySet > xSourceProps( aStringList[0], uno::UNO_QUERY );
208
209 PropertyMapper::setMappedProperties( xTargetProps, xSourceProps
210 , PropertyMapper::getPropertyNameMapForCharacterProperties() );
211
212 // adapt font size according to page size
213 awt::Size aOldRefSize;
214 if( xTitleProperties->getPropertyValue( C2U("ReferencePageSize")) >>= aOldRefSize )
215 {
216 RelativeSizeHelper::adaptFontSizes( xTargetProps, aOldRefSize, rReferenceSize );
217 }
218 }
219 }
220 else
221 {
222 uno::Sequence< uno::Reference< text::XTextCursor > > aCursorList( aStringList.getLength() );
223 sal_Int32 nN = 0;
224 for( nN=0; nN<aStringList.getLength();nN++ )
225 {
226 xTextCursor->gotoEnd(false);
227 xText->insertString( xTextRange, aStringList[nN]->getString(), false );
228 xTextCursor->gotoEnd(true);
229 aCursorList[nN] = xText->createTextCursorByRange( uno::Reference< text::XTextRange >(xTextCursor,uno::UNO_QUERY) );
230 }
231 awt::Size aOldRefSize;
232 bool bHasRefPageSize =
233 ( xTitleProperties->getPropertyValue( C2U("ReferencePageSize")) >>= aOldRefSize );
234
235 //for( nN=0; nN<aStringList.getLength();nN++ ) //portion wise fromatting does not work still
236 if( aStringList.getLength()>0 )
237 {
238 //uno::Reference< beans::XPropertySet > xTargetProps( aCursorList[nN], uno::UNO_QUERY );
239 //uno::Reference< beans::XPropertySet > xSourceProps( aStringList[nN], uno::UNO_QUERY );
240 uno::Reference< beans::XPropertySet > xTargetProps( xShape, uno::UNO_QUERY );
241 uno::Reference< beans::XPropertySet > xSourceProps( aStringList[0], uno::UNO_QUERY );
242 PropertyMapper::setMappedProperties( xTargetProps, xSourceProps, PropertyMapper::getPropertyNameMapForCharacterProperties() );
243
244 // adapt font size according to page size
245 if( bHasRefPageSize )
246 {
247 RelativeSizeHelper::adaptFontSizes( xTargetProps, aOldRefSize, rReferenceSize );
248 }
249 }
250 }
251
252 // #i109336# Improve auto positioning in chart
253 float fFontHeight = 0.0;
254 if ( xShapeProp.is() && ( xShapeProp->getPropertyValue( C2U( "CharHeight" ) ) >>= fFontHeight ) )
255 {
256 fFontHeight *= ( 2540. / 72. ); // pt -> 1/100 mm
257 float fXFraction = 0.18;
258 sal_Int32 nXDistance = static_cast< sal_Int32 >( ::rtl::math::round( fFontHeight * fXFraction ) );
259 float fYFraction = 0.30;
260 sal_Int32 nYDistance = static_cast< sal_Int32 >( ::rtl::math::round( fFontHeight * fYFraction ) );
261 xShapeProp->setPropertyValue( C2U( "TextLeftDistance" ), uno::makeAny( nXDistance ) );
262 xShapeProp->setPropertyValue( C2U( "TextRightDistance" ), uno::makeAny( nXDistance ) );
263 xShapeProp->setPropertyValue( C2U( "TextUpperDistance" ), uno::makeAny( nYDistance ) );
264 xShapeProp->setPropertyValue( C2U( "TextLowerDistance" ), uno::makeAny( nYDistance ) );
265 }
266
267 try
268 {
269 double fAngleDegree = 0;
270 xTitleProperties->getPropertyValue( C2U( "TextRotation" ) ) >>= fAngleDegree;
271 m_fRotationAngleDegree += fAngleDegree;
272 }
273 catch( uno::Exception& e )
274 {
275 ASSERT_EXCEPTION( e );
276 }
277 m_nXPos = rPos.X;
278 m_nYPos = rPos.Y;
279
280 //set position matrix
281 //the matrix needs to be set at the end behind autogrow and such position influencing properties
282 ::basegfx::B2DHomMatrix aM;
283 aM.rotate( -m_fRotationAngleDegree*F_PI/180.0 );//#i78696#->#i80521#
284 aM.translate( m_nXPos, m_nYPos );
285 xShapeProp->setPropertyValue( C2U( "Transformation" ), uno::makeAny( B2DHomMatrixToHomogenMatrix3(aM) ) );
286 }
287 catch( uno::Exception& e )
288 {
289 ASSERT_EXCEPTION( e );
290 }
291 }
292
293 //.............................................................................
294 } //namespace chart
295 //.............................................................................
296