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