fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / oox / source / drawingml / textparagraphproperties.cxx
blob585695deb04254126919f220533ecd7c007c06b8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "oox/drawingml/textparagraphproperties.hxx"
22 #include <com/sun/star/text/XNumberingRulesSupplier.hpp>
23 #include <com/sun/star/container/XIndexReplace.hpp>
24 #include <com/sun/star/text/HoriOrientation.hpp>
25 #include <com/sun/star/awt/FontDescriptor.hpp>
26 #include <com/sun/star/awt/XBitmap.hpp>
27 #include <com/sun/star/graphic/XGraphic.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/style/TabStop.hpp>
30 #include <com/sun/star/text/PositionAndSpaceMode.hpp>
32 #include "oox/helper/helper.hxx"
33 #include "oox/helper/propertyset.hxx"
34 #include "oox/core/xmlfilterbase.hxx"
35 #include "oox/drawingml/drawingmltypes.hxx"
37 #if OSL_DEBUG_LEVEL > 0
38 #include <vcl/unohelp.hxx>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/text/XText.hpp>
41 #include <com/sun/star/drawing/XShape.hpp>
42 #include <comphelper/genericpropertyset.hxx>
43 #include <oox/ppt/pptimport.hxx>
44 #include <oox/ppt/slidepersist.hxx>
45 #endif
47 using namespace ::oox::core;
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::beans;
50 using namespace ::com::sun::star::style;
51 using namespace ::com::sun::star::text;
52 using namespace ::com::sun::star::container;
53 using ::com::sun::star::awt::FontDescriptor;
55 namespace oox { namespace drawingml {
57 BulletList::BulletList( )
58 : maBulletColorPtr( new Color() )
62 bool BulletList::is() const
64 return mnNumberingType.hasValue();
67 void BulletList::setBulletChar( const OUString & sChar )
69 mnNumberingType <<= NumberingType::CHAR_SPECIAL;
70 msBulletChar <<= sChar;
73 void BulletList::setGraphic( ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& rXGraphic )
75 mnNumberingType <<= NumberingType::BITMAP;
76 maGraphic <<= rXGraphic;
79 void BulletList::setNone( )
81 mnNumberingType <<= NumberingType::NUMBER_NONE;
84 void BulletList::setSuffixParenBoth()
86 msNumberingSuffix <<= OUString( ")" );
87 msNumberingPrefix <<= OUString( "(" );
90 void BulletList::setSuffixParenRight()
92 msNumberingSuffix <<= OUString( ")" );
93 msNumberingPrefix <<= OUString();
96 void BulletList::setSuffixPeriod()
98 msNumberingSuffix <<= OUString( "." );
99 msNumberingPrefix <<= OUString();
102 void BulletList::setSuffixNone()
104 msNumberingSuffix <<= OUString();
105 msNumberingPrefix <<= OUString();
108 void BulletList::setSuffixMinusRight()
110 msNumberingSuffix <<= OUString( "-" );
111 msNumberingPrefix <<= OUString();
114 void BulletList::setType( sal_Int32 nType )
116 OSL_ASSERT((nType & sal_Int32(0xFFFF0000))==0);
117 // OSL_TRACE( "OOX: set list numbering type %d", nType);
118 switch( nType )
120 case XML_alphaLcParenBoth:
121 mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
122 setSuffixParenBoth();
123 break;
124 case XML_alphaLcParenR:
125 mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
126 setSuffixParenRight();
127 break;
128 case XML_alphaLcPeriod:
129 mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
130 setSuffixPeriod();
131 break;
132 case XML_alphaUcParenBoth:
133 mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
134 setSuffixParenBoth();
135 break;
136 case XML_alphaUcParenR:
137 mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
138 setSuffixParenRight();
139 break;
140 case XML_alphaUcPeriod:
141 mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
142 setSuffixPeriod();
143 break;
144 case XML_arabic1Minus:
145 case XML_arabic2Minus:
146 case XML_arabicDbPeriod:
147 case XML_arabicDbPlain:
148 // TODO
149 break;
150 case XML_arabicParenBoth:
151 mnNumberingType <<= NumberingType::ARABIC;
152 setSuffixParenBoth();
153 break;
154 case XML_arabicParenR:
155 mnNumberingType <<= NumberingType::ARABIC;
156 setSuffixParenRight();
157 break;
158 case XML_arabicPeriod:
159 mnNumberingType <<= NumberingType::ARABIC;
160 setSuffixPeriod();
161 break;
162 case XML_arabicPlain:
163 mnNumberingType <<= NumberingType::ARABIC;
164 setSuffixNone();
165 break;
166 case XML_circleNumDbPlain:
167 case XML_circleNumWdBlackPlain:
168 case XML_circleNumWdWhitePlain:
169 mnNumberingType <<= NumberingType::CIRCLE_NUMBER;
170 break;
171 case XML_ea1ChsPeriod:
172 mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH;
173 setSuffixPeriod();
174 break;
175 case XML_ea1ChsPlain:
176 mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH;
177 setSuffixNone();
178 break;
179 case XML_ea1ChtPeriod:
180 mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH_TW;
181 setSuffixPeriod();
182 break;
183 case XML_ea1ChtPlain:
184 mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH_TW;
185 setSuffixNone();
186 break;
187 case XML_ea1JpnChsDbPeriod:
188 case XML_ea1JpnKorPeriod:
189 case XML_ea1JpnKorPlain:
190 break;
191 case XML_hebrew2Minus:
192 mnNumberingType <<= NumberingType::CHARS_HEBREW;
193 setSuffixMinusRight();
194 break;
195 case XML_hindiAlpha1Period:
196 case XML_hindiAlphaPeriod:
197 case XML_hindiNumParenR:
198 case XML_hindiNumPeriod:
199 // TODO
200 break;
201 case XML_romanLcParenBoth:
202 mnNumberingType <<= NumberingType::ROMAN_LOWER;
203 setSuffixParenBoth();
204 break;
205 case XML_romanLcParenR:
206 mnNumberingType <<= NumberingType::ROMAN_LOWER;
207 setSuffixParenRight();
208 break;
209 case XML_romanLcPeriod:
210 mnNumberingType <<= NumberingType::ROMAN_LOWER;
211 setSuffixPeriod();
212 break;
213 case XML_romanUcParenBoth:
214 mnNumberingType <<= NumberingType::ROMAN_UPPER;
215 setSuffixParenBoth();
216 break;
217 case XML_romanUcParenR:
218 mnNumberingType <<= NumberingType::ROMAN_UPPER;
219 setSuffixParenRight();
220 break;
221 case XML_romanUcPeriod:
222 mnNumberingType <<= NumberingType::ROMAN_UPPER;
223 setSuffixPeriod();
224 break;
225 case XML_thaiAlphaParenBoth:
226 case XML_thaiNumParenBoth:
227 mnNumberingType <<= NumberingType::CHARS_THAI;
228 setSuffixParenBoth();
229 break;
230 case XML_thaiAlphaParenR:
231 case XML_thaiNumParenR:
232 mnNumberingType <<= NumberingType::CHARS_THAI;
233 setSuffixParenRight();
234 break;
235 case XML_thaiAlphaPeriod:
236 case XML_thaiNumPeriod:
237 mnNumberingType <<= NumberingType::CHARS_THAI;
238 setSuffixPeriod();
239 break;
243 void BulletList::setBulletSize(sal_Int16 nSize)
245 mnSize <<= nSize;
249 void BulletList::setFontSize(sal_Int16 nSize)
251 mnFontSize <<= nSize;
254 void BulletList::apply( const BulletList& rSource )
256 if ( rSource.maBulletColorPtr->isUsed() )
257 maBulletColorPtr = rSource.maBulletColorPtr;
258 if ( rSource.mbBulletColorFollowText.hasValue() )
259 mbBulletColorFollowText = rSource.mbBulletColorFollowText;
260 if ( rSource.mbBulletFontFollowText.hasValue() )
261 mbBulletFontFollowText = rSource.mbBulletFontFollowText;
262 maBulletFont.assignIfUsed( rSource.maBulletFont );
263 if ( rSource.msBulletChar.hasValue() )
264 msBulletChar = rSource.msBulletChar;
265 if ( rSource.mnStartAt.hasValue() )
266 mnStartAt = rSource.mnStartAt;
267 if ( rSource.mnNumberingType.hasValue() )
268 mnNumberingType = rSource.mnNumberingType;
269 if ( rSource.msNumberingPrefix.hasValue() )
270 msNumberingPrefix = rSource.msNumberingPrefix;
271 if ( rSource.msNumberingSuffix.hasValue() )
272 msNumberingSuffix = rSource.msNumberingSuffix;
273 if ( rSource.mnSize.hasValue() )
274 mnSize = rSource.mnSize;
275 if ( rSource.mnFontSize.hasValue() )
276 mnFontSize = rSource.mnFontSize;
277 if ( rSource.maStyleName.hasValue() )
278 maStyleName = rSource.maStyleName;
279 if ( rSource.maGraphic.hasValue() )
280 maGraphic = rSource.maGraphic;
283 void BulletList::pushToPropMap( const ::oox::core::XmlFilterBase* pFilterBase, PropertyMap& rPropMap ) const
285 if( msNumberingPrefix.hasValue() )
286 rPropMap[ PROP_Prefix ] = msNumberingPrefix;
287 if( msNumberingSuffix.hasValue() )
288 rPropMap[ PROP_Suffix ] = msNumberingSuffix;
289 if( mnStartAt.hasValue() )
290 rPropMap[ PROP_StartWith ] = mnStartAt;
291 rPropMap[ PROP_Adjust ] <<= HoriOrientation::LEFT;
293 if( mnNumberingType.hasValue() )
294 rPropMap[ PROP_NumberingType ] = mnNumberingType;
296 OUString aBulletFontName;
297 sal_Int16 nBulletFontPitch = 0;
298 sal_Int16 nBulletFontFamily = 0;
299 sal_Bool bSymbolFont = sal_False;
300 if( pFilterBase) {
301 if (maBulletFont.getFontData( aBulletFontName, nBulletFontPitch, nBulletFontFamily, *pFilterBase ) )
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 if ( aBulletFontName.equalsIgnoreAsciiCase("Wingdings") ||
313 aBulletFontName.equalsIgnoreAsciiCase("Wingdings 2") ||
314 aBulletFontName.equalsIgnoreAsciiCase("Wingdings 3") ||
315 aBulletFontName.equalsIgnoreAsciiCase("Monotype Sorts") ||
316 aBulletFontName.equalsIgnoreAsciiCase("Monotype Sorts 2") ||
317 aBulletFontName.equalsIgnoreAsciiCase("Webdings") ||
318 aBulletFontName.equalsIgnoreAsciiCase("StarBats") ||
319 aBulletFontName.equalsIgnoreAsciiCase("StarMath") ||
320 aBulletFontName.equalsIgnoreAsciiCase("ZapfDingbats") ) {
321 aFontDesc.CharSet = RTL_TEXTENCODING_SYMBOL;
322 bSymbolFont = sal_True;
324 rPropMap[ PROP_BulletFont ] <<= aFontDesc;
325 rPropMap[ PROP_BulletFontName ] <<= aBulletFontName;
328 if ( msBulletChar.hasValue() ) {
329 OUString sBuChar;
331 msBulletChar >>= sBuChar;
333 if( pFilterBase && sBuChar.getLength() == 1 && maBulletFont.getFontData( aBulletFontName, nBulletFontPitch, nBulletFontFamily, *pFilterBase ) && bSymbolFont )
335 sal_Unicode nBuChar = sBuChar.toChar();
336 nBuChar &= 0x00ff;
337 nBuChar |= 0xf000;
338 sBuChar = OUString( &nBuChar, 1 );
341 rPropMap[ PROP_BulletChar ] <<= sBuChar;
343 if ( maGraphic.hasValue() )
345 Reference< com::sun::star::awt::XBitmap > xBitmap( maGraphic, UNO_QUERY );
346 if ( xBitmap.is() )
347 rPropMap[ PROP_Graphic ] <<= xBitmap;
349 if( mnSize.hasValue() )
350 rPropMap[ PROP_BulletRelSize ] = mnSize;
351 if ( maStyleName.hasValue() )
352 rPropMap[ PROP_CharStyleName ] <<= maStyleName;
353 if (pFilterBase ) {
354 if ( maBulletColorPtr->isUsed() )
355 rPropMap[ PROP_BulletColor ] <<= maBulletColorPtr->getColor( pFilterBase->getGraphicHelper() );
359 TextParagraphProperties::TextParagraphProperties()
360 : mnLevel( 0 )
364 TextParagraphProperties::~TextParagraphProperties()
368 void TextParagraphProperties::apply( const TextParagraphProperties& rSourceProps )
370 maTextParagraphPropertyMap.assignAll( rSourceProps.maTextParagraphPropertyMap );
371 maBulletList.apply( rSourceProps.maBulletList );
372 maTextCharacterProperties.assignUsed( rSourceProps.maTextCharacterProperties );
373 if ( rSourceProps.maParaTopMargin.bHasValue )
374 maParaTopMargin = rSourceProps.maParaTopMargin;
375 if ( rSourceProps.maParaBottomMargin.bHasValue )
376 maParaBottomMargin = rSourceProps.maParaBottomMargin;
377 if ( rSourceProps.moParaLeftMargin )
378 moParaLeftMargin = rSourceProps.moParaLeftMargin;
379 if ( rSourceProps.moFirstLineIndentation )
380 moFirstLineIndentation = rSourceProps.moFirstLineIndentation;
381 if( rSourceProps.mnLevel )
382 mnLevel = rSourceProps.mnLevel;
385 void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase* pFilterBase,
386 const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, const BulletList* pMasterBuList, sal_Bool bApplyBulletMap, float fCharacterSize,
387 bool bPushDefaultValues ) const
389 PropertySet aPropSet( xPropSet );
390 aPropSet.setProperties( maTextParagraphPropertyMap );
392 sal_Int32 nNumberingType = NumberingType::NUMBER_NONE;
393 if ( maBulletList.mnNumberingType.hasValue() )
394 maBulletList.mnNumberingType >>= nNumberingType;
395 else if ( pMasterBuList && pMasterBuList->mnNumberingType.hasValue() )
396 pMasterBuList->mnNumberingType >>= nNumberingType;
397 if ( nNumberingType == NumberingType::NUMBER_NONE )
398 aPropSet.setProperty< sal_Int16 >( PROP_NumberingLevel, -1 );
400 maBulletList.pushToPropMap( pFilterBase, rioBulletMap );
402 if ( maParaTopMargin.bHasValue || bPushDefaultValues )
403 aPropSet.setProperty( PROP_ParaTopMargin, maParaTopMargin.toMargin( fCharacterSize != 0.0 ? fCharacterSize : getCharHeightPoints ( 18.0 ) ) );
404 if ( maParaBottomMargin.bHasValue || bPushDefaultValues )
405 aPropSet.setProperty( PROP_ParaBottomMargin, maParaBottomMargin.toMargin( fCharacterSize != 0.0 ? fCharacterSize : getCharHeightPoints ( 18.0 ) ) );
406 if ( nNumberingType == NumberingType::BITMAP )
408 fCharacterSize = getCharHeightPoints( fCharacterSize );
410 com::sun::star::awt::Size aBulletSize;
411 aBulletSize.Width = aBulletSize.Height = static_cast< sal_Int32 >( ( fCharacterSize * ( 2540.0 / 72.0 ) * 0.8 ) );
412 rioBulletMap[ PROP_GraphicSize ] <<= aBulletSize;
415 boost::optional< sal_Int32 > noParaLeftMargin( moParaLeftMargin );
416 boost::optional< sal_Int32 > noFirstLineIndentation( moFirstLineIndentation );
418 if ( nNumberingType != NumberingType::NUMBER_NONE )
420 if ( noParaLeftMargin )
422 aPropSet.setProperty( PROP_ParaLeftMargin, static_cast< sal_Int32 >(0));
423 rioBulletMap[ PROP_LeftMargin ] <<= static_cast< sal_Int32 >( *noParaLeftMargin );
424 noParaLeftMargin = boost::none;
426 if ( noFirstLineIndentation )
428 // Force Paragraph property as zero - impress seems to use the value from previous
429 // (non) bullet line if not set to zero explicitly :(
430 aPropSet.setProperty( PROP_ParaFirstLineIndent, static_cast< sal_Int32 >(0) );
431 rioBulletMap[ PROP_FirstLineOffset ] <<= static_cast< sal_Int32 >( *noFirstLineIndentation );
432 noFirstLineIndentation = boost::none;
434 if ( nNumberingType != NumberingType::BITMAP && !rioBulletMap.hasProperty( PROP_BulletColor ) && pFilterBase )
435 rioBulletMap[ PROP_BulletColor ] <<= static_cast< sal_Int32 >( maTextCharacterProperties.maCharColor.getColor( pFilterBase->getGraphicHelper()));
438 if ( bApplyBulletMap )
440 Reference< XIndexReplace > xNumRule;
441 aPropSet.getProperty( xNumRule, PROP_NumberingRules );
442 OSL_ENSURE( xNumRule.is(), "can't get Numbering rules");
446 if( xNumRule.is() )
448 if( !rioBulletMap.empty() )
450 // fix default bullet size to be 100%
451 if( rioBulletMap.find( PROP_BulletRelSize ) == rioBulletMap.end() )
452 rioBulletMap[ PROP_BulletRelSize ] <<= static_cast< sal_Int16 >( 100 );
453 Sequence< PropertyValue > aBulletPropSeq = rioBulletMap.makePropertyValueSequence();
454 xNumRule->replaceByIndex( getLevel(), makeAny( aBulletPropSeq ) );
457 aPropSet.setProperty( PROP_NumberingRules, xNumRule );
460 catch (const Exception &)
462 // Don't warn for now, expected to fail for Writer.
465 if ( noParaLeftMargin )
466 aPropSet.setProperty( PROP_ParaLeftMargin, sal_Int32( *noParaLeftMargin ) );
467 if ( noFirstLineIndentation )
469 aPropSet.setProperty( PROP_ParaFirstLineIndent, *noFirstLineIndentation );
470 if( bPushDefaultValues )
472 // Reset TabStops - these would be auto calculated by Impress
473 TabStop aTabStop;
474 aTabStop.Position = 0;
475 Sequence< TabStop > aSeq(1);
476 aSeq[0] = aTabStop;
477 aPropSet.setProperty( PROP_ParaTabStops, aSeq );
482 float TextParagraphProperties::getCharHeightPoints( float fDefault ) const
484 return maTextCharacterProperties.getCharHeightPoints( fDefault );
487 #ifdef DBG_UTIL
488 // Note: Please don't remove this function. This is required for
489 // debugging pptx import problems.
490 void TextParagraphProperties::dump() const
492 Reference< ::com::sun::star::drawing::XShape > xShape( oox::ppt::PowerPointImport::mpDebugFilterBase->getModelFactory()->createInstance( "com.sun.star.presentation.TitleTextShape" ), UNO_QUERY );
493 Reference< ::com::sun::star::text::XText > xText( xShape, UNO_QUERY );
495 Reference< com::sun::star::drawing::XDrawPage > xDebugPage(ppt::SlidePersist::mxDebugPage.get(), UNO_QUERY);
496 if (xDebugPage.is())
497 xDebugPage->add( xShape );
499 PropertyMap emptyMap;
501 const OUString sText = "debug";
502 xText->setString( sText );
503 Reference< ::com::sun::star::text::XTextCursor > xStart( xText->createTextCursor(), UNO_QUERY );
504 Reference< ::com::sun::star::text::XTextRange > xRange( xStart, UNO_QUERY );
505 xStart->gotoEnd( sal_True );
506 Reference< XPropertySet > xPropSet( xRange, UNO_QUERY );
507 pushToPropSet( NULL, xPropSet, emptyMap, NULL, false, 0 );
508 PropertySet pSet( xPropSet );
509 pSet.dump();
511 #endif
514 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */