xref: /trunk/main/oox/source/drawingml/textparagraphproperties.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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