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 #include "oox/drawingml/textparagraphproperties.hxx"
25
26 #include <com/sun/star/text/XNumberingRulesSupplier.hpp>
27 #include <com/sun/star/container/XIndexReplace.hpp>
28 #include <com/sun/star/text/HoriOrientation.hpp>
29 #include <com/sun/star/awt/FontDescriptor.hpp>
30 #include <com/sun/star/awt/XBitmap.hpp>
31 #include <com/sun/star/graphic/XGraphic.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33
34 #include "oox/helper/helper.hxx"
35 #include "oox/helper/propertyset.hxx"
36 #include "oox/core/xmlfilterbase.hxx"
37 #include "oox/drawingml/drawingmltypes.hxx"
38
39 using rtl::OUString;
40 using namespace ::oox::core;
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::beans;
43 using namespace ::com::sun::star::style;
44 using namespace ::com::sun::star::text;
45 using namespace ::com::sun::star::container;
46 using ::com::sun::star::awt::FontDescriptor;
47
48 namespace oox { namespace drawingml {
49
BulletList()50 BulletList::BulletList( )
51 : maBulletColorPtr( new Color() )
52 {
53 }
54
is() const55 bool BulletList::is() const
56 {
57 return mnNumberingType.hasValue();
58 }
59
setBulletChar(const::rtl::OUString & sChar)60 void BulletList::setBulletChar( const ::rtl::OUString & sChar )
61 {
62 mnNumberingType <<= NumberingType::CHAR_SPECIAL;
63 msBulletChar <<= sChar;
64 }
65
setGraphic(::com::sun::star::uno::Reference<::com::sun::star::graphic::XGraphic> & rXGraphic)66 void BulletList::setGraphic( ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& rXGraphic )
67 {
68 mnNumberingType <<= NumberingType::BITMAP;
69 maGraphic <<= rXGraphic;
70 }
71
setNone()72 void BulletList::setNone( )
73 {
74 mnNumberingType <<= NumberingType::NUMBER_NONE;
75 }
76
setSuffixParenBoth()77 void BulletList::setSuffixParenBoth()
78 {
79 msNumberingSuffix <<= CREATE_OUSTRING( ")" );
80 msNumberingPrefix <<= CREATE_OUSTRING( "(" );
81 }
82
setSuffixParenRight()83 void BulletList::setSuffixParenRight()
84 {
85 msNumberingSuffix <<= CREATE_OUSTRING( ")" );
86 msNumberingPrefix <<= OUString();
87 }
88
setSuffixPeriod()89 void BulletList::setSuffixPeriod()
90 {
91 msNumberingSuffix <<= CREATE_OUSTRING( "." );
92 msNumberingPrefix <<= OUString();
93 }
94
setSuffixNone()95 void BulletList::setSuffixNone()
96 {
97 msNumberingSuffix <<= OUString();
98 msNumberingPrefix <<= OUString();
99 }
100
setSuffixMinusRight()101 void BulletList::setSuffixMinusRight()
102 {
103 msNumberingSuffix <<= CREATE_OUSTRING( "-" );
104 msNumberingPrefix <<= OUString();
105 }
106
setType(sal_Int32 nType)107 void BulletList::setType( sal_Int32 nType )
108 {
109 // OSL_TRACE( "OOX: set list numbering type %d", nType);
110 switch( nType )
111 {
112 case XML_alphaLcParenBoth:
113 mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
114 setSuffixParenBoth();
115 break;
116 case XML_alphaLcParenR:
117 mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
118 setSuffixParenRight();
119 break;
120 case XML_alphaLcPeriod:
121 mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
122 setSuffixPeriod();
123 break;
124 case XML_alphaUcParenBoth:
125 mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
126 setSuffixParenBoth();
127 break;
128 case XML_alphaUcParenR:
129 mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
130 setSuffixParenRight();
131 break;
132 case XML_alphaUcPeriod:
133 mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
134 setSuffixPeriod();
135 break;
136 case XML_arabic1Minus:
137 case XML_arabic2Minus:
138 case XML_arabicDbPeriod:
139 case XML_arabicDbPlain:
140 // TODO
141 break;
142 case XML_arabicParenBoth:
143 mnNumberingType <<= NumberingType::ARABIC;
144 setSuffixParenBoth();
145 break;
146 case XML_arabicParenR:
147 mnNumberingType <<= NumberingType::ARABIC;
148 setSuffixParenRight();
149 break;
150 case XML_arabicPeriod:
151 mnNumberingType <<= NumberingType::ARABIC;
152 setSuffixPeriod();
153 break;
154 case XML_arabicPlain:
155 mnNumberingType <<= NumberingType::ARABIC;
156 setSuffixNone();
157 break;
158 case XML_circleNumDbPlain:
159 case XML_circleNumWdBlackPlain:
160 case XML_circleNumWdWhitePlain:
161 mnNumberingType <<= NumberingType::CIRCLE_NUMBER;
162 break;
163 case XML_ea1ChsPeriod:
164 mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH;
165 setSuffixPeriod();
166 break;
167 case XML_ea1ChsPlain:
168 mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH;
169 setSuffixNone();
170 break;
171 case XML_ea1ChtPeriod:
172 mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH_TW;
173 setSuffixPeriod();
174 break;
175 case XML_ea1ChtPlain:
176 mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH_TW;
177 setSuffixNone();
178 break;
179 case XML_ea1JpnChsDbPeriod:
180 case XML_ea1JpnKorPeriod:
181 case XML_ea1JpnKorPlain:
182 break;
183 case XML_hebrew2Minus:
184 mnNumberingType <<= NumberingType::CHARS_HEBREW;
185 setSuffixMinusRight();
186 break;
187 case XML_hindiAlpha1Period:
188 case XML_hindiAlphaPeriod:
189 case XML_hindiNumParenR:
190 case XML_hindiNumPeriod:
191 // TODO
192 break;
193 case XML_romanLcParenBoth:
194 mnNumberingType <<= NumberingType::ROMAN_LOWER;
195 setSuffixParenBoth();
196 break;
197 case XML_romanLcParenR:
198 mnNumberingType <<= NumberingType::ROMAN_LOWER;
199 setSuffixParenRight();
200 break;
201 case XML_romanLcPeriod:
202 mnNumberingType <<= NumberingType::ROMAN_LOWER;
203 setSuffixPeriod();
204 break;
205 case XML_romanUcParenBoth:
206 mnNumberingType <<= NumberingType::ROMAN_UPPER;
207 setSuffixParenBoth();
208 break;
209 case XML_romanUcParenR:
210 mnNumberingType <<= NumberingType::ROMAN_UPPER;
211 setSuffixParenRight();
212 break;
213 case XML_romanUcPeriod:
214 mnNumberingType <<= NumberingType::ROMAN_UPPER;
215 setSuffixPeriod();
216 break;
217 case XML_thaiAlphaParenBoth:
218 case XML_thaiNumParenBoth:
219 mnNumberingType <<= NumberingType::CHARS_THAI;
220 setSuffixParenBoth();
221 break;
222 case XML_thaiAlphaParenR:
223 case XML_thaiNumParenR:
224 mnNumberingType <<= NumberingType::CHARS_THAI;
225 setSuffixParenRight();
226 break;
227 case XML_thaiAlphaPeriod:
228 case XML_thaiNumPeriod:
229 mnNumberingType <<= NumberingType::CHARS_THAI;
230 setSuffixPeriod();
231 break;
232 }
233 }
234
setBulletSize(sal_Int16 nSize)235 void BulletList::setBulletSize(sal_Int16 nSize)
236 {
237 mnSize <<= nSize;
238 }
239
240
setFontSize(sal_Int16 nSize)241 void BulletList::setFontSize(sal_Int16 nSize)
242 {
243 mnFontSize <<= nSize;
244 }
245
apply(const BulletList & rSource)246 void BulletList::apply( const BulletList& rSource )
247 {
248 if ( rSource.maBulletColorPtr->isUsed() )
249 maBulletColorPtr = rSource.maBulletColorPtr;
250 if ( rSource.mbBulletColorFollowText.hasValue() )
251 mbBulletColorFollowText = rSource.mbBulletColorFollowText;
252 if ( rSource.mbBulletFontFollowText.hasValue() )
253 mbBulletFontFollowText = rSource.mbBulletFontFollowText;
254 maBulletFont.assignIfUsed( rSource.maBulletFont );
255 if ( rSource.msBulletChar.hasValue() )
256 msBulletChar = rSource.msBulletChar;
257 if ( rSource.mnStartAt.hasValue() )
258 mnStartAt = rSource.mnStartAt;
259 if ( rSource.mnNumberingType.hasValue() )
260 mnNumberingType = rSource.mnNumberingType;
261 if ( rSource.msNumberingPrefix.hasValue() )
262 msNumberingPrefix = rSource.msNumberingPrefix;
263 if ( rSource.msNumberingSuffix.hasValue() )
264 msNumberingSuffix = rSource.msNumberingSuffix;
265 if ( rSource.mnSize.hasValue() )
266 mnSize = rSource.mnSize;
267 if ( rSource.mnFontSize.hasValue() )
268 mnFontSize = rSource.mnFontSize;
269 if ( rSource.maStyleName.hasValue() )
270 maStyleName = rSource.maStyleName;
271 if ( rSource.maGraphic.hasValue() )
272 maGraphic = rSource.maGraphic;
273 }
274
pushToPropMap(const::oox::core::XmlFilterBase & rFilterBase,PropertyMap & rPropMap) const275 void BulletList::pushToPropMap( const ::oox::core::XmlFilterBase& rFilterBase, PropertyMap& rPropMap ) const
276 {
277 if( msNumberingPrefix.hasValue() )
278 rPropMap[ PROP_Prefix ] = msNumberingPrefix;
279 if( msNumberingSuffix.hasValue() )
280 rPropMap[ PROP_Suffix ] = msNumberingSuffix;
281 if( mnStartAt.hasValue() )
282 rPropMap[ PROP_StartWith ] = mnStartAt;
283 rPropMap[ PROP_Adjust ] <<= HoriOrientation::LEFT;
284
285 if( mnNumberingType.hasValue() )
286 rPropMap[ PROP_NumberingType ] = mnNumberingType;
287
288 OUString aBulletFontName;
289 sal_Int16 nBulletFontPitch = 0;
290 sal_Int16 nBulletFontFamily = 0;
291 if( maBulletFont.getFontData( aBulletFontName, nBulletFontPitch, nBulletFontFamily, rFilterBase ) )
292 {
293 FontDescriptor aFontDesc;
294 sal_Int16 nFontSize = 0;
295 if( mnFontSize >>= nFontSize )
296 aFontDesc.Height = nFontSize;
297
298 // TODO move the to the TextFont struct.
299 aFontDesc.Name = aBulletFontName;
300 aFontDesc.Pitch = nBulletFontPitch;
301 aFontDesc.Family = nBulletFontFamily;
302 rPropMap[ PROP_BulletFont ] <<= aFontDesc;
303 rPropMap[ PROP_BulletFontName ] <<= aBulletFontName;
304 }
305 if ( msBulletChar.hasValue() )
306 rPropMap[ PROP_BulletChar ] = msBulletChar;
307 if ( maGraphic.hasValue() )
308 {
309 Reference< com::sun::star::awt::XBitmap > xBitmap( maGraphic, UNO_QUERY );
310 if ( xBitmap.is() )
311 rPropMap[ PROP_Graphic ] <<= xBitmap;
312 }
313 if( mnSize.hasValue() )
314 rPropMap[ PROP_BulletRelSize ] = mnSize;
315 if ( maStyleName.hasValue() )
316 rPropMap[ PROP_CharStyleName ] <<= maStyleName;
317 if ( maBulletColorPtr->isUsed() )
318 rPropMap[ PROP_BulletColor ] <<= maBulletColorPtr->getColor( rFilterBase.getGraphicHelper() );
319 }
320
TextParagraphProperties()321 TextParagraphProperties::TextParagraphProperties()
322 : mnLevel( 0 )
323 {
324 }
325
~TextParagraphProperties()326 TextParagraphProperties::~TextParagraphProperties()
327 {
328 }
329
apply(const TextParagraphProperties & rSourceProps)330 void TextParagraphProperties::apply( const TextParagraphProperties& rSourceProps )
331 {
332 maTextParagraphPropertyMap.insert( rSourceProps.maTextParagraphPropertyMap.begin(), rSourceProps.maTextParagraphPropertyMap.end() );
333 maBulletList.apply( rSourceProps.maBulletList );
334 maTextCharacterProperties.assignUsed( rSourceProps.maTextCharacterProperties );
335 if ( rSourceProps.maParaTopMargin.bHasValue )
336 maParaTopMargin = rSourceProps.maParaTopMargin;
337 if ( rSourceProps.maParaBottomMargin.bHasValue )
338 maParaBottomMargin = rSourceProps.maParaBottomMargin;
339 if ( rSourceProps.moParaLeftMargin )
340 moParaLeftMargin = rSourceProps.moParaLeftMargin;
341 if ( rSourceProps.moFirstLineIndentation )
342 moFirstLineIndentation = rSourceProps.moFirstLineIndentation;
343 }
344
pushToPropSet(const::oox::core::XmlFilterBase & rFilterBase,const Reference<XPropertySet> & xPropSet,PropertyMap & rioBulletMap,const BulletList * pMasterBuList,sal_Bool bApplyBulletMap,float fCharacterSize) const345 void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
346 const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, const BulletList* pMasterBuList, sal_Bool bApplyBulletMap, float fCharacterSize ) const
347 {
348 PropertySet aPropSet( xPropSet );
349 aPropSet.setProperties( maTextParagraphPropertyMap );
350
351 sal_Int32 nNumberingType = NumberingType::NUMBER_NONE;
352 if ( maBulletList.mnNumberingType.hasValue() )
353 maBulletList.mnNumberingType >>= nNumberingType;
354 else if ( pMasterBuList && pMasterBuList->mnNumberingType.hasValue() )
355 pMasterBuList->mnNumberingType >>= nNumberingType;
356 if ( nNumberingType == NumberingType::NUMBER_NONE )
357 aPropSet.setProperty< sal_Int16 >( PROP_NumberingLevel, -1 );
358
359 maBulletList.pushToPropMap( rFilterBase, rioBulletMap );
360
361 if ( maParaTopMargin.bHasValue )
362 aPropSet.setProperty( PROP_ParaTopMargin, maParaTopMargin.toMargin( getCharHeightPoints( 18.0 ) ) );
363 if ( maParaBottomMargin.bHasValue )
364 aPropSet.setProperty( PROP_ParaBottomMargin, maParaBottomMargin.toMargin( getCharHeightPoints( 18.0 ) ) );
365 if ( nNumberingType == NumberingType::BITMAP )
366 {
367 fCharacterSize = getCharHeightPoints( fCharacterSize );
368
369 com::sun::star::awt::Size aBulletSize;
370 aBulletSize.Width = aBulletSize.Height = static_cast< sal_Int32 >( ( fCharacterSize * ( 2540.0 / 72.0 ) * 0.8 ) );
371 rioBulletMap[ PROP_GraphicSize ] <<= aBulletSize;
372 }
373
374 boost::optional< sal_Int32 > noParaLeftMargin( moParaLeftMargin );
375 boost::optional< sal_Int32 > noFirstLineIndentation( moFirstLineIndentation );
376
377 if ( nNumberingType != NumberingType::NUMBER_NONE )
378 {
379 if ( noParaLeftMargin )
380 {
381 rioBulletMap[ PROP_LeftMargin ] <<= static_cast< sal_Int32 >( *noParaLeftMargin );
382 noParaLeftMargin = boost::optional< sal_Int32 >( 0 );
383 }
384 if ( noFirstLineIndentation )
385 {
386 rioBulletMap[ PROP_FirstLineOffset ] <<= static_cast< sal_Int32 >( *noFirstLineIndentation );
387 noFirstLineIndentation = boost::optional< sal_Int32 >( 0 );
388 }
389 }
390
391 if ( bApplyBulletMap )
392 {
393 Reference< XIndexReplace > xNumRule;
394 aPropSet.getProperty( xNumRule, PROP_NumberingRules );
395 OSL_ENSURE( xNumRule.is(), "can't get Numbering rules");
396
397 if( xNumRule.is() )
398 {
399 if( !rioBulletMap.empty() )
400 {
401 Sequence< PropertyValue > aBulletPropSeq = rioBulletMap.makePropertyValueSequence();
402 xNumRule->replaceByIndex( getLevel(), makeAny( aBulletPropSeq ) );
403 }
404
405 aPropSet.setProperty( PROP_NumberingRules, xNumRule );
406 }
407 }
408 if ( noParaLeftMargin )
409 aPropSet.setProperty( PROP_ParaLeftMargin, *noParaLeftMargin );
410 if ( noFirstLineIndentation )
411 aPropSet.setProperty( PROP_ParaFirstLineIndent, *noFirstLineIndentation );
412 }
413
getCharHeightPoints(float fDefault) const414 float TextParagraphProperties::getCharHeightPoints( float fDefault ) const
415 {
416 return maTextCharacterProperties.getCharHeightPoints( fDefault );
417 }
418
419 } }
420