1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: textparagraphproperties.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/drawingml/textparagraphproperties.hxx"
33 #include <com/sun/star/text/XNumberingRulesSupplier.hpp>
34 #include <com/sun/star/container/XIndexReplace.hpp>
35 #include <com/sun/star/text/HoriOrientation.hpp>
36 #include <com/sun/star/awt/FontDescriptor.hpp>
37 #include <com/sun/star/awt/XBitmap.hpp>
38 #include <com/sun/star/graphic/XGraphic.hpp>
39 #include <com/sun/star/beans/PropertyValue.hpp>
41 #include "oox/helper/helper.hxx"
42 #include "oox/helper/propertyset.hxx"
43 #include "oox/core/namespaces.hxx"
44 #include "oox/core/xmlfilterbase.hxx"
45 #include "oox/drawingml/drawingmltypes.hxx"
46 #include "properties.hxx"
50 using namespace ::oox::core
;
51 using namespace ::com::sun::star::uno
;
52 using namespace ::com::sun::star::beans
;
53 using namespace ::com::sun::star::style
;
54 using namespace ::com::sun::star::text
;
55 using namespace ::com::sun::star::container
;
56 using ::com::sun::star::awt::FontDescriptor
;
58 namespace oox
{ namespace drawingml
{
60 BulletList::BulletList( )
61 : maBulletColorPtr( new Color() )
65 bool BulletList::is() const
67 return mnNumberingType
.hasValue();
70 void BulletList::setBulletChar( const ::rtl::OUString
& sChar
)
72 mnNumberingType
<<= NumberingType::CHAR_SPECIAL
;
73 msBulletChar
<<= sChar
;
76 void BulletList::setGraphic( ::com::sun::star::uno::Reference
< ::com::sun::star::graphic::XGraphic
>& rXGraphic
)
78 mnNumberingType
<<= NumberingType::BITMAP
;
79 maGraphic
<<= rXGraphic
;
82 void BulletList::setNone( )
84 mnNumberingType
<<= NumberingType::NUMBER_NONE
;
87 void BulletList::setSuffixParenBoth()
89 msNumberingSuffix
<<= CREATE_OUSTRING( ")" );
90 msNumberingPrefix
<<= CREATE_OUSTRING( "(" );
93 void BulletList::setSuffixParenRight()
95 msNumberingSuffix
<<= CREATE_OUSTRING( ")" );
96 msNumberingPrefix
<<= OUString();
99 void BulletList::setSuffixPeriod()
101 msNumberingSuffix
<<= CREATE_OUSTRING( "." );
102 msNumberingPrefix
<<= OUString();
105 void BulletList::setSuffixNone()
107 msNumberingSuffix
<<= OUString();
108 msNumberingPrefix
<<= OUString();
111 void BulletList::setSuffixMinusRight()
113 msNumberingSuffix
<<= CREATE_OUSTRING( "-" );
114 msNumberingPrefix
<<= OUString();
117 void BulletList::setType( sal_Int32 nType
)
119 // OSL_TRACE( "OOX: set list numbering type %d", nType);
122 case XML_alphaLcParenBoth
:
123 mnNumberingType
<<= NumberingType::CHARS_LOWER_LETTER
;
124 setSuffixParenBoth();
126 case XML_alphaLcParenR
:
127 mnNumberingType
<<= NumberingType::CHARS_LOWER_LETTER
;
128 setSuffixParenRight();
130 case XML_alphaLcPeriod
:
131 mnNumberingType
<<= NumberingType::CHARS_LOWER_LETTER
;
134 case XML_alphaUcParenBoth
:
135 mnNumberingType
<<= NumberingType::CHARS_UPPER_LETTER
;
136 setSuffixParenBoth();
138 case XML_alphaUcParenR
:
139 mnNumberingType
<<= NumberingType::CHARS_UPPER_LETTER
;
140 setSuffixParenRight();
142 case XML_alphaUcPeriod
:
143 mnNumberingType
<<= NumberingType::CHARS_UPPER_LETTER
;
146 case XML_arabic1Minus
:
147 case XML_arabic2Minus
:
148 case XML_arabicDbPeriod
:
149 case XML_arabicDbPlain
:
152 case XML_arabicParenBoth
:
153 mnNumberingType
<<= NumberingType::ARABIC
;
154 setSuffixParenBoth();
156 case XML_arabicParenR
:
157 mnNumberingType
<<= NumberingType::ARABIC
;
158 setSuffixParenRight();
160 case XML_arabicPeriod
:
161 mnNumberingType
<<= NumberingType::ARABIC
;
164 case XML_arabicPlain
:
165 mnNumberingType
<<= NumberingType::ARABIC
;
168 case XML_circleNumDbPlain
:
169 case XML_circleNumWdBlackPlain
:
170 case XML_circleNumWdWhitePlain
:
171 mnNumberingType
<<= NumberingType::CIRCLE_NUMBER
;
173 case XML_ea1ChsPeriod
:
174 mnNumberingType
<<= NumberingType::NUMBER_UPPER_ZH
;
177 case XML_ea1ChsPlain
:
178 mnNumberingType
<<= NumberingType::NUMBER_UPPER_ZH
;
181 case XML_ea1ChtPeriod
:
182 mnNumberingType
<<= NumberingType::NUMBER_UPPER_ZH_TW
;
185 case XML_ea1ChtPlain
:
186 mnNumberingType
<<= NumberingType::NUMBER_UPPER_ZH_TW
;
189 case XML_ea1JpnChsDbPeriod
:
190 case XML_ea1JpnKorPeriod
:
191 case XML_ea1JpnKorPlain
:
193 case XML_hebrew2Minus
:
194 mnNumberingType
<<= NumberingType::CHARS_HEBREW
;
195 setSuffixMinusRight();
197 case XML_hindiAlpha1Period
:
198 case XML_hindiAlphaPeriod
:
199 case XML_hindiNumParenR
:
200 case XML_hindiNumPeriod
:
203 case XML_romanLcParenBoth
:
204 mnNumberingType
<<= NumberingType::ROMAN_LOWER
;
205 setSuffixParenBoth();
207 case XML_romanLcParenR
:
208 mnNumberingType
<<= NumberingType::ROMAN_LOWER
;
209 setSuffixParenRight();
211 case XML_romanLcPeriod
:
212 mnNumberingType
<<= NumberingType::ROMAN_LOWER
;
215 case XML_romanUcParenBoth
:
216 mnNumberingType
<<= NumberingType::ROMAN_UPPER
;
217 setSuffixParenBoth();
219 case XML_romanUcParenR
:
220 mnNumberingType
<<= NumberingType::ROMAN_UPPER
;
221 setSuffixParenRight();
223 case XML_romanUcPeriod
:
224 mnNumberingType
<<= NumberingType::ROMAN_UPPER
;
227 case XML_thaiAlphaParenBoth
:
228 case XML_thaiNumParenBoth
:
229 mnNumberingType
<<= NumberingType::CHARS_THAI
;
230 setSuffixParenBoth();
232 case XML_thaiAlphaParenR
:
233 case XML_thaiNumParenR
:
234 mnNumberingType
<<= NumberingType::CHARS_THAI
;
235 setSuffixParenRight();
237 case XML_thaiAlphaPeriod
:
238 case XML_thaiNumPeriod
:
239 mnNumberingType
<<= NumberingType::CHARS_THAI
;
245 void BulletList::setBulletSize(sal_Int16 nSize
)
251 void BulletList::setFontSize(sal_Int16 nSize
)
253 mnFontSize
<<= nSize
;
256 void BulletList::apply( const BulletList
& rSource
)
258 if ( rSource
.maBulletColorPtr
->isUsed() )
259 maBulletColorPtr
= rSource
.maBulletColorPtr
;
260 if ( rSource
.mbBulletColorFollowText
.hasValue() )
261 mbBulletColorFollowText
= rSource
.mbBulletColorFollowText
;
262 if ( rSource
.mbBulletFontFollowText
.hasValue() )
263 mbBulletFontFollowText
= rSource
.mbBulletFontFollowText
;
264 maBulletFont
.assignIfUsed( rSource
.maBulletFont
);
265 if ( rSource
.msBulletChar
.hasValue() )
266 msBulletChar
= rSource
.msBulletChar
;
267 if ( rSource
.mnStartAt
.hasValue() )
268 mnStartAt
= rSource
.mnStartAt
;
269 if ( rSource
.mnNumberingType
.hasValue() )
270 mnNumberingType
= rSource
.mnNumberingType
;
271 if ( rSource
.msNumberingPrefix
.hasValue() )
272 msNumberingPrefix
= rSource
.msNumberingPrefix
;
273 if ( rSource
.msNumberingSuffix
.hasValue() )
274 msNumberingSuffix
= rSource
.msNumberingSuffix
;
275 if ( rSource
.mnSize
.hasValue() )
276 mnSize
= rSource
.mnSize
;
277 if ( rSource
.mnFontSize
.hasValue() )
278 mnFontSize
= rSource
.mnFontSize
;
279 if ( rSource
.maStyleName
.hasValue() )
280 maStyleName
= rSource
.maStyleName
;
281 if ( rSource
.maGraphic
.hasValue() )
282 maGraphic
= rSource
.maGraphic
;
285 void BulletList::pushToPropMap( const ::oox::core::XmlFilterBase
& rFilterBase
, PropertyMap
& rPropMap
) const
287 if( msNumberingPrefix
.hasValue() )
288 rPropMap
[ PROP_Prefix
] = msNumberingPrefix
;
289 if( msNumberingSuffix
.hasValue() )
290 rPropMap
[ PROP_Suffix
] = msNumberingSuffix
;
291 if( mnStartAt
.hasValue() )
292 rPropMap
[ PROP_StartWith
] = mnStartAt
;
293 rPropMap
[ PROP_Adjust
] <<= HoriOrientation::LEFT
;
295 if( mnNumberingType
.hasValue() )
296 rPropMap
[ PROP_NumberingType
] = mnNumberingType
;
298 OUString aBulletFontName
;
299 sal_Int16 nBulletFontPitch
= 0;
300 sal_Int16 nBulletFontFamily
= 0;
301 if( maBulletFont
.getFontData( aBulletFontName
, nBulletFontPitch
, nBulletFontFamily
, rFilterBase
) )
303 FontDescriptor aFontDesc
;
304 sal_Int16 nFontSize
= 0;
305 if( mnFontSize
>>= nFontSize
)
306 aFontDesc
.Height
= nFontSize
;
308 // TODO move the to the TextFont struct.
309 aFontDesc
.Name
= aBulletFontName
;
310 aFontDesc
.Pitch
= nBulletFontPitch
;
311 aFontDesc
.Family
= nBulletFontFamily
;
312 rPropMap
[ PROP_BulletFont
] <<= aFontDesc
;
313 rPropMap
[ PROP_BulletFontName
] <<= aBulletFontName
;
315 if ( msBulletChar
.hasValue() )
316 rPropMap
[ PROP_BulletChar
] = msBulletChar
;
317 if ( maGraphic
.hasValue() )
319 Reference
< com::sun::star::awt::XBitmap
> xBitmap( maGraphic
, UNO_QUERY
);
321 rPropMap
[ PROP_Graphic
] <<= xBitmap
;
323 if( mnSize
.hasValue() )
324 rPropMap
[ PROP_BulletRelSize
] = mnSize
;
325 if ( maStyleName
.hasValue() )
326 rPropMap
[ PROP_CharStyleName
] <<= maStyleName
;
327 if ( maBulletColorPtr
->isUsed() )
328 rPropMap
[ PROP_BulletColor
] <<= maBulletColorPtr
->getColor( rFilterBase
);
331 TextParagraphProperties::TextParagraphProperties()
336 TextParagraphProperties::~TextParagraphProperties()
340 void TextParagraphProperties::apply( const TextParagraphProperties
& rSourceProps
)
342 maTextParagraphPropertyMap
.insert( rSourceProps
.maTextParagraphPropertyMap
.begin(), rSourceProps
.maTextParagraphPropertyMap
.end() );
343 maBulletList
.apply( rSourceProps
.maBulletList
);
344 maTextCharacterProperties
.assignUsed( rSourceProps
.maTextCharacterProperties
);
345 if ( rSourceProps
.maParaTopMargin
.bHasValue
)
346 maParaTopMargin
= rSourceProps
.maParaTopMargin
;
347 if ( rSourceProps
.maParaBottomMargin
.bHasValue
)
348 maParaBottomMargin
= rSourceProps
.maParaBottomMargin
;
349 if ( rSourceProps
.moParaLeftMargin
)
350 moParaLeftMargin
= rSourceProps
.moParaLeftMargin
;
351 if ( rSourceProps
.moFirstLineIndentation
)
352 moFirstLineIndentation
= rSourceProps
.moFirstLineIndentation
;
355 void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase
& rFilterBase
,
356 const Reference
< XPropertySet
>& xPropSet
, PropertyMap
& rioBulletMap
, const BulletList
* pMasterBuList
, sal_Bool bApplyBulletMap
, float fCharacterSize
) const
358 PropertySet
aPropSet( xPropSet
);
359 aPropSet
.setProperties( maTextParagraphPropertyMap
);
361 sal_Int32 nNumberingType
= NumberingType::NUMBER_NONE
;
362 if ( maBulletList
.mnNumberingType
.hasValue() )
363 maBulletList
.mnNumberingType
>>= nNumberingType
;
364 else if ( pMasterBuList
&& pMasterBuList
->mnNumberingType
.hasValue() )
365 pMasterBuList
->mnNumberingType
>>= nNumberingType
;
366 if ( nNumberingType
== NumberingType::NUMBER_NONE
)
367 aPropSet
.setProperty
< sal_Int16
>( PROP_NumberingLevel
, -1 );
369 maBulletList
.pushToPropMap( rFilterBase
, rioBulletMap
);
371 if ( maParaTopMargin
.bHasValue
)
372 aPropSet
.setProperty( PROP_ParaTopMargin
, maParaTopMargin
.toMargin( getCharHeightPoints( 18.0 ) ) );
373 if ( maParaBottomMargin
.bHasValue
)
374 aPropSet
.setProperty( PROP_ParaBottomMargin
, maParaBottomMargin
.toMargin( getCharHeightPoints( 18.0 ) ) );
375 if ( nNumberingType
== NumberingType::BITMAP
)
377 fCharacterSize
= getCharHeightPoints( fCharacterSize
);
379 com::sun::star::awt::Size aBulletSize
;
380 aBulletSize
.Width
= aBulletSize
.Height
= static_cast< sal_Int32
>( ( fCharacterSize
* ( 2540.0 / 72.0 ) * 0.8 ) );
381 rioBulletMap
[ PROP_GraphicSize
] <<= aBulletSize
;
384 boost::optional
< sal_Int32
> noParaLeftMargin( moParaLeftMargin
);
385 boost::optional
< sal_Int32
> noFirstLineIndentation( moFirstLineIndentation
);
387 if ( nNumberingType
!= NumberingType::NUMBER_NONE
)
389 if ( noParaLeftMargin
)
391 rioBulletMap
[ PROP_LeftMargin
] <<= static_cast< sal_Int32
>( *noParaLeftMargin
);
392 noParaLeftMargin
= boost::optional
< sal_Int32
>( 0 );
394 if ( noFirstLineIndentation
)
396 rioBulletMap
[ PROP_FirstLineOffset
] <<= static_cast< sal_Int32
>( *noFirstLineIndentation
);
397 noFirstLineIndentation
= boost::optional
< sal_Int32
>( 0 );
401 if ( bApplyBulletMap
)
403 Reference
< XIndexReplace
> xNumRule
;
404 aPropSet
.getProperty( xNumRule
, PROP_NumberingRules
);
405 OSL_ENSURE( xNumRule
.is(), "can't get Numbering rules");
409 if( !rioBulletMap
.empty() )
411 Sequence
< PropertyValue
> aBulletPropSeq
= rioBulletMap
.makePropertyValueSequence();
412 xNumRule
->replaceByIndex( getLevel(), makeAny( aBulletPropSeq
) );
415 aPropSet
.setProperty( PROP_NumberingRules
, xNumRule
);
418 if ( noParaLeftMargin
)
419 aPropSet
.setProperty( PROP_ParaLeftMargin
, *noParaLeftMargin
);
420 if ( noFirstLineIndentation
)
421 aPropSet
.setProperty( PROP_ParaFirstLineIndent
, *noFirstLineIndentation
);
424 float TextParagraphProperties::getCharHeightPoints( float fDefault
) const
426 return maTextCharacterProperties
.getCharHeightPoints( fDefault
);