Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 : #include "ConversionHelper.hxx"
20 : #include "NumberingManager.hxx"
21 : #include "StyleSheetTable.hxx"
22 : #include "PropertyIds.hxx"
23 :
24 : #include <ooxml/resourceids.hxx>
25 :
26 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 : #include <com/sun/star/container/XNameContainer.hpp>
28 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
29 : #include <com/sun/star/style/NumberingType.hpp>
30 : #include <com/sun/star/text/HoriOrientation.hpp>
31 : #include <com/sun/star/text/PositionAndSpaceMode.hpp>
32 : #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
33 :
34 : #include <osl/diagnose.h>
35 : #include <rtl/ustring.hxx>
36 : #include <comphelper/sequence.hxx>
37 : #include <comphelper/propertyvalue.hxx>
38 :
39 : using namespace com::sun::star;
40 :
41 : #define MAKE_PROPVAL(NameId, Value) \
42 : beans::PropertyValue(aPropNameSupplier.GetName(NameId), 0, uno::makeAny(Value), beans::PropertyState_DIRECT_VALUE )
43 :
44 : #define NUMBERING_MAX_LEVELS 10
45 :
46 :
47 : namespace writerfilter {
48 : namespace dmapper {
49 :
50 : //--------------------------------------------------- Utility functions
51 :
52 8507 : sal_Int32 lcl_findProperty( const uno::Sequence< beans::PropertyValue >& aProps, const OUString& sName )
53 : {
54 8507 : sal_Int32 i = 0;
55 8507 : sal_Int32 nLen = aProps.getLength( );
56 8507 : sal_Int32 nPos = -1;
57 :
58 54650 : while ( nPos == -1 && i < nLen )
59 : {
60 37636 : if ( aProps[i].Name.equals( sName ) )
61 7868 : nPos = i;
62 : else
63 29768 : i++;
64 : }
65 :
66 8507 : return nPos;
67 : }
68 :
69 2722 : void lcl_mergeProperties( uno::Sequence< beans::PropertyValue >& aSrc,
70 : uno::Sequence< beans::PropertyValue >& aDst )
71 : {
72 8077 : for ( sal_Int32 i = 0, nSrcLen = aSrc.getLength( ); i < nSrcLen; i++ )
73 : {
74 : // Look for the same property in aDst
75 5355 : sal_Int32 nPos = lcl_findProperty( aDst, aSrc[i].Name );
76 5355 : if ( nPos >= 0 )
77 : {
78 : // Replace the property value by the one in aSrc
79 4850 : aDst[nPos] = aSrc[i];
80 : }
81 : else
82 : {
83 : // Simply add the new value
84 505 : aDst.realloc( aDst.getLength( ) + 1 );
85 505 : aDst[ aDst.getLength( ) - 1 ] = aSrc[i];
86 : }
87 : }
88 2722 : }
89 :
90 : //-------------------------------------------- ListLevel implementation
91 82499 : void ListLevel::SetValue( Id nId, sal_Int32 nValue )
92 : {
93 82499 : switch( nId )
94 : {
95 : case NS_ooxml::LN_CT_Lvl_start:
96 35114 : m_nIStartAt = nValue;
97 35114 : break;
98 : case NS_ooxml::LN_CT_Lvl_numFmt:
99 34520 : m_nNFC = nValue;
100 34520 : break;
101 : case NS_ooxml::LN_CT_Lvl_isLgl:
102 187 : m_nFLegal = nValue;
103 187 : break;
104 : case NS_ooxml::LN_CT_Lvl_legacy:
105 214 : m_nFPrevSpace = nValue;
106 214 : break;
107 : case NS_ooxml::LN_CT_Lvl_suff:
108 1409 : m_nXChFollow = nValue;
109 1409 : break;
110 : case NS_ooxml::LN_CT_TabStop_pos:
111 11055 : if (nValue < 0)
112 : {
113 : SAL_INFO("writerfilter",
114 : "unsupported list tab stop position " << nValue);
115 : }
116 : else
117 11055 : m_nTabstop = nValue;
118 11055 : break;
119 : default:
120 : OSL_FAIL( "this line should never be reached");
121 : }
122 82499 : }
123 :
124 786 : void ListLevel::SetParaStyle( std::shared_ptr< StyleSheetEntry > pStyle )
125 : {
126 786 : if (!pStyle)
127 786 : return;
128 786 : m_pParaStyle = pStyle;
129 : // AFAICT .docx spec does not identify which numberings or paragraph
130 : // styles are actually the ones to be used for outlines (chapter numbering),
131 : // it only kind of says somewhere that they should be named Heading1 to Heading9.
132 786 : const OUString styleId= pStyle->sConvertedStyleName;
133 786 : m_outline = ( styleId.getLength() == RTL_CONSTASCII_LENGTH( "Heading 1" )
134 314 : && styleId.match( "Heading ", 0 )
135 304 : && styleId[ RTL_CONSTASCII_LENGTH( "Heading " ) ] >= '1'
136 1090 : && styleId[ RTL_CONSTASCII_LENGTH( "Heading " ) ] <= '9' );
137 : }
138 :
139 36553 : sal_Int16 ListLevel::GetParentNumbering( const OUString& sText, sal_Int16 nLevel,
140 : OUString& rPrefix, OUString& rSuffix )
141 : {
142 36553 : sal_Int16 nParentNumbering = 1;
143 :
144 : //now parse the text to find %n from %1 to %nLevel+1
145 : //everything before the first % and the last %x is prefix and suffix
146 36553 : OUString sLevelText( sText );
147 36553 : sal_Int32 nCurrentIndex = 0;
148 36553 : sal_Int32 nFound = sLevelText.indexOf( '%', nCurrentIndex );
149 36553 : if( nFound > 0 )
150 : {
151 651 : rPrefix = sLevelText.copy( 0, nFound );
152 651 : sLevelText = sLevelText.copy( nFound );
153 : }
154 36553 : sal_Int32 nMinLevel = nLevel;
155 : //now the text should either be empty or start with %
156 36553 : nFound = sLevelText.getLength( ) > 1 ? 0 : -1;
157 110209 : while( nFound >= 0 )
158 : {
159 37103 : if( sLevelText.getLength() > 1 )
160 : {
161 37103 : sal_Unicode cLevel = sLevelText[1];
162 37103 : if( cLevel >= '1' && cLevel <= '9' )
163 : {
164 26759 : if( cLevel - '1' < nMinLevel )
165 2352 : nMinLevel = cLevel - '1';
166 : //remove first char - next char is removed later
167 26759 : sLevelText = sLevelText.copy( 1 );
168 : }
169 : }
170 : //remove old '%' or number
171 37103 : sLevelText = sLevelText.copy( 1 );
172 37103 : nCurrentIndex = 0;
173 37103 : nFound = sLevelText.indexOf( '%', nCurrentIndex );
174 : //remove the text before the next %
175 37103 : if(nFound > 0)
176 10332 : sLevelText = sLevelText.copy( nFound -1 );
177 : }
178 36553 : if( nMinLevel < nLevel )
179 : {
180 2352 : nParentNumbering = sal_Int16( nLevel - nMinLevel + 1);
181 : }
182 :
183 36553 : rSuffix = sLevelText;
184 :
185 36553 : return nParentNumbering;
186 : }
187 :
188 37914 : uno::Sequence< beans::PropertyValue > ListLevel::GetProperties( )
189 : {
190 37914 : uno::Sequence< beans::PropertyValue > aLevelProps = GetLevelProperties( );
191 37914 : if ( m_pParaStyle.get( ) )
192 1576 : AddParaProperties( &aLevelProps );
193 37914 : return aLevelProps;
194 : }
195 :
196 143338 : static bool IgnoreForCharStyle(const OUString& aStr)
197 : {
198 : //Names found in PropertyIds.cxx, Lines 56-396
199 249919 : return (aStr=="Adjust" || aStr=="IndentAt" || aStr=="FirstLineIndent"
200 179842 : || aStr=="FirstLineOffset" || aStr=="LeftMargin" || aStr=="CharFontName"
201 143338 : );
202 : }
203 37914 : uno::Sequence< beans::PropertyValue > ListLevel::GetCharStyleProperties( )
204 : {
205 37914 : PropertyValueVector_t rProperties;
206 :
207 75828 : uno::Sequence< beans::PropertyValue > vPropVals = PropertyMap::GetPropertyValues();
208 37914 : beans::PropertyValue* aValIter = vPropVals.begin();
209 37914 : beans::PropertyValue* aEndIter = vPropVals.end();
210 180342 : for( ; aValIter != aEndIter; ++aValIter )
211 : {
212 142428 : if (IgnoreForCharStyle(aValIter->Name))
213 125932 : continue;
214 16496 : else if(aValIter->Name=="CharInteropGrabBag" || aValIter->Name=="ParaInteropGrabBag") {
215 605 : uno::Sequence<beans::PropertyValue> vGrabVals;
216 605 : aValIter->Value >>= vGrabVals;
217 605 : beans::PropertyValue* aGrabIter = vGrabVals.begin();
218 1515 : for(; aGrabIter!=vGrabVals.end(); ++aGrabIter) {
219 910 : if(!IgnoreForCharStyle(aGrabIter->Name))
220 910 : rProperties.push_back(beans::PropertyValue(aGrabIter->Name, 0, aGrabIter->Value, beans::PropertyState_DIRECT_VALUE));
221 605 : }
222 : }
223 : else
224 15891 : rProperties.push_back(beans::PropertyValue(aValIter->Name, 0, aValIter->Value, beans::PropertyState_DIRECT_VALUE));
225 : }
226 :
227 37914 : uno::Sequence< beans::PropertyValue > aRet( rProperties.size() );
228 37914 : beans::PropertyValue* pValues = aRet.getArray();
229 37914 : PropertyValueVector_t::const_iterator aIt = rProperties.begin();
230 37914 : PropertyValueVector_t::const_iterator aEndIt = rProperties.end();
231 54715 : for(sal_uInt32 nIndex = 0; aIt != aEndIt; ++aIt,++nIndex)
232 : {
233 16801 : pValues[nIndex] = *aIt;
234 : }
235 75828 : return aRet;
236 : }
237 :
238 37914 : uno::Sequence< beans::PropertyValue > ListLevel::GetLevelProperties( )
239 : {
240 : const sal_Int16 aWWToUnoAdjust[] =
241 : {
242 : text::HoriOrientation::LEFT,
243 : text::HoriOrientation::CENTER,
244 : text::HoriOrientation::RIGHT,
245 37914 : };
246 :
247 37914 : PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
248 37914 : std::vector<beans::PropertyValue> aNumberingProperties;
249 :
250 37914 : if( m_nIStartAt >= 0)
251 37427 : aNumberingProperties.push_back( MAKE_PROPVAL(PROP_START_WITH, (sal_Int16)m_nIStartAt) );
252 :
253 37914 : sal_Int16 nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC);
254 37914 : if( m_nNFC >= 0)
255 : {
256 36759 : if (!m_sGraphicURL.isEmpty() || m_sGraphicBitmap.is())
257 39 : nNumberFormat = style::NumberingType::BITMAP;
258 36720 : else if (m_sBulletChar.isEmpty() && nNumberFormat != style::NumberingType::CHAR_SPECIAL)
259 : // w:lvlText is empty, that means no numbering in Word.
260 : // CHAR_SPECIAL is handled separately below.
261 1299 : nNumberFormat = style::NumberingType::NUMBER_NONE;
262 36759 : aNumberingProperties.push_back( MAKE_PROPVAL(PROP_NUMBERING_TYPE, nNumberFormat ));
263 : }
264 :
265 37914 : if( m_nJC >= 0 && m_nJC <= sal::static_int_cast<sal_Int32>(sizeof(aWWToUnoAdjust) / sizeof(sal_Int16)) )
266 0 : aNumberingProperties.push_back( MAKE_PROPVAL(PROP_ADJUST, aWWToUnoAdjust[m_nJC]));
267 :
268 37914 : if( !isOutlineNumbering())
269 : {
270 : // todo: this is not the bullet char
271 37208 : if( nNumberFormat == style::NumberingType::CHAR_SPECIAL )
272 : {
273 18789 : if (!m_sBulletChar.isEmpty())
274 : {
275 18761 : aNumberingProperties.push_back( MAKE_PROPVAL(PROP_BULLET_CHAR, m_sBulletChar.copy(0,1)));
276 : }
277 : else
278 : {
279 : // If w:lvlText's value is null - set bullet char to zero.
280 28 : aNumberingProperties.push_back( MAKE_PROPVAL(PROP_BULLET_CHAR, sal_Unicode(0x0)));
281 : }
282 : }
283 37208 : if (!m_sGraphicURL.isEmpty())
284 19 : aNumberingProperties.push_back(MAKE_PROPVAL(PROP_GRAPHIC_URL, m_sGraphicURL));
285 37208 : if (m_sGraphicBitmap.is())
286 39 : aNumberingProperties.push_back(MAKE_PROPVAL(PROP_GRAPHIC_BITMAP, m_sGraphicBitmap));
287 : }
288 :
289 37914 : aNumberingProperties.push_back( MAKE_PROPVAL( PROP_LISTTAB_STOP_POSITION, m_nTabstop ) );
290 :
291 : //TODO: handling of nFLegal?
292 : //TODO: nFNoRestart lower levels do not restart when higher levels are incremented, like:
293 : //1.
294 : //1.1
295 : //2.2
296 : //2.3
297 : //3.4
298 :
299 :
300 37914 : if( m_nFWord6 > 0) //Word 6 compatibility
301 : {
302 0 : if( m_nFPrev == 1)
303 0 : aNumberingProperties.push_back( MAKE_PROPVAL( PROP_PARENT_NUMBERING, (sal_Int16) NUMBERING_MAX_LEVELS ));
304 : //TODO: prefixing space nFPrevSpace; - has not been used in WW8 filter
305 : }
306 :
307 : // TODO: sRGBXchNums; array of inherited numbers
308 :
309 : // nXChFollow; following character 0 - tab, 1 - space, 2 - nothing
310 37914 : aNumberingProperties.push_back( MAKE_PROPVAL( PROP_LEVEL_FOLLOW, m_nXChFollow ));
311 :
312 37914 : const int nIds = 5;
313 : PropertyIds aReadIds[nIds] =
314 : {
315 : PROP_ADJUST, PROP_INDENT_AT, PROP_FIRST_LINE_INDENT,
316 : PROP_FIRST_LINE_OFFSET, PROP_LEFT_MARGIN
317 37914 : };
318 227484 : for(int i=0; i<nIds; ++i) {
319 189570 : boost::optional<PropertyMap::Property> aProp = getProperty(aReadIds[i]);
320 189570 : if (aProp)
321 : aNumberingProperties.push_back(
322 213668 : beans::PropertyValue( aPropNameSupplier.GetName(aProp->first), 0, aProp->second, beans::PropertyState_DIRECT_VALUE )
323 320502 : );
324 189570 : }
325 :
326 75828 : boost::optional<PropertyMap::Property> aPropFont = getProperty(PROP_CHAR_FONT_NAME);
327 37914 : if(aPropFont && !isOutlineNumbering())
328 : aNumberingProperties.push_back(
329 19095 : beans::PropertyValue( aPropNameSupplier.GetName(PROP_BULLET_FONT_NAME), 0, aPropFont->second, beans::PropertyState_DIRECT_VALUE )
330 38190 : );
331 :
332 75828 : return comphelper::containerToSequence(aNumberingProperties);
333 : }
334 :
335 : // Add the properties only if they do not already exist in the sequence.
336 1576 : void ListLevel::AddParaProperties( uno::Sequence< beans::PropertyValue >* props )
337 : {
338 1576 : uno::Sequence< beans::PropertyValue >& aProps = *props;
339 1576 : PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
340 :
341 : OUString sFirstLineIndent = aPropNameSupplier.GetName(
342 1576 : PROP_FIRST_LINE_INDENT );
343 : OUString sIndentAt = aPropNameSupplier.GetName(
344 1576 : PROP_INDENT_AT );
345 :
346 1576 : bool hasFirstLineIndent = lcl_findProperty( aProps, sFirstLineIndent );
347 1576 : bool hasIndentAt = lcl_findProperty( aProps, sIndentAt );
348 :
349 1576 : if( hasFirstLineIndent && hasIndentAt )
350 3152 : return; // has them all, nothing to add
351 :
352 0 : uno::Sequence< beans::PropertyValue > aParaProps = m_pParaStyle->pProperties->GetPropertyValues( );
353 :
354 : // ParaFirstLineIndent -> FirstLineIndent
355 : // ParaLeftMargin -> IndentAt
356 :
357 : OUString sParaIndent = aPropNameSupplier.GetName(
358 0 : PROP_PARA_FIRST_LINE_INDENT );
359 : OUString sParaLeftMargin = aPropNameSupplier.GetName(
360 0 : PROP_PARA_LEFT_MARGIN );
361 :
362 0 : sal_Int32 nLen = aParaProps.getLength( );
363 0 : for ( sal_Int32 i = 0; i < nLen; i++ )
364 : {
365 0 : if ( !hasFirstLineIndent && aParaProps[i].Name.equals( sParaIndent ) )
366 : {
367 0 : aProps.realloc( aProps.getLength() + 1 );
368 0 : aProps[aProps.getLength( ) - 1] = aParaProps[i];
369 0 : aProps[aProps.getLength( ) - 1].Name = sFirstLineIndent;
370 : }
371 0 : else if ( !hasIndentAt && aParaProps[i].Name.equals( sParaLeftMargin ) )
372 : {
373 0 : aProps.realloc( aProps.getLength() + 1 );
374 0 : aProps[aProps.getLength( ) - 1] = aParaProps[i];
375 0 : aProps[aProps.getLength( ) - 1].Name = sIndentAt;
376 : }
377 :
378 0 : }
379 : }
380 :
381 71 : NumPicBullet::NumPicBullet()
382 71 : : m_nId(0)
383 : {
384 71 : }
385 :
386 142 : NumPicBullet::~NumPicBullet()
387 : {
388 142 : }
389 :
390 71 : void NumPicBullet::SetId(sal_Int32 nId)
391 : {
392 71 : m_nId = nId;
393 71 : }
394 :
395 71 : void NumPicBullet::SetShape(uno::Reference<drawing::XShape> const& xShape)
396 : {
397 71 : m_xShape = xShape;
398 71 : }
399 :
400 :
401 :
402 : //--------------------------------------- AbstractListDef implementation
403 :
404 9414 : AbstractListDef::AbstractListDef( ) :
405 : m_nTmpl( -1 )
406 9414 : ,m_nId( -1 )
407 : {
408 9414 : }
409 :
410 13898 : AbstractListDef::~AbstractListDef( )
411 : {
412 13898 : }
413 :
414 4229 : void AbstractListDef::SetValue( sal_uInt32 nSprmId, sal_Int32 nValue )
415 : {
416 4229 : switch( nSprmId )
417 : {
418 : case NS_ooxml::LN_CT_AbstractNum_tmpl:
419 4229 : m_nTmpl = nValue;
420 4229 : break;
421 : default:
422 : OSL_FAIL( "this line should never be reached");
423 : }
424 4229 : }
425 :
426 73106 : ListLevel::Pointer AbstractListDef::GetLevel( sal_uInt16 nLvl )
427 : {
428 73106 : ListLevel::Pointer pLevel;
429 73106 : if ( m_aLevels.size( ) > nLvl )
430 37914 : pLevel = m_aLevels[ nLvl ];
431 73106 : return pLevel;
432 : }
433 :
434 35676 : void AbstractListDef::AddLevel( )
435 : {
436 35676 : ListLevel::Pointer pLevel( new ListLevel );
437 35676 : m_pCurrentLevel = pLevel;
438 35676 : m_aLevels.push_back( pLevel );
439 35676 : }
440 :
441 9596 : uno::Sequence< uno::Sequence< beans::PropertyValue > > AbstractListDef::GetPropertyValues( )
442 : {
443 9596 : uno::Sequence< uno::Sequence< beans::PropertyValue > > result( sal_Int32( m_aLevels.size( ) ) );
444 9596 : uno::Sequence< beans::PropertyValue >* aResult = result.getArray( );
445 :
446 9596 : int nLevels = m_aLevels.size( );
447 47510 : for ( int i = 0; i < nLevels; i++ )
448 : {
449 37914 : aResult[i] = m_aLevels[i]->GetProperties( );
450 : }
451 :
452 9596 : return result;
453 : }
454 :
455 : //---------------------------------------------- ListDef implementation
456 :
457 4930 : ListDef::ListDef( ) : AbstractListDef( )
458 : {
459 4930 : }
460 :
461 9860 : ListDef::~ListDef( )
462 : {
463 9860 : }
464 :
465 5183 : OUString ListDef::GetStyleName( sal_Int32 nId )
466 : {
467 5183 : OUString sStyleName( "WWNum" );
468 5183 : sStyleName += OUString::number( nId );
469 :
470 5183 : return sStyleName;
471 : }
472 :
473 4798 : uno::Sequence< uno::Sequence< beans::PropertyValue > > ListDef::GetPropertyValues( )
474 : {
475 4798 : if (!m_pAbstractDef)
476 0 : return uno::Sequence< uno::Sequence< beans::PropertyValue > >();
477 :
478 : // [1] Call the same method on the abstract list
479 4798 : uno::Sequence< uno::Sequence< beans::PropertyValue > > aAbstract = m_pAbstractDef->GetPropertyValues( );
480 :
481 : // [2] Call the upper class method
482 9596 : uno::Sequence< uno::Sequence< beans::PropertyValue > > aThis = AbstractListDef::GetPropertyValues( );
483 :
484 : // Merge the results of [2] in [1]
485 4798 : sal_Int32 nThisCount = aThis.getLength( );
486 4798 : sal_Int32 nAbstractCount = aAbstract.getLength( );
487 6159 : for ( sal_Int32 i = 0; i < nThisCount && i < nAbstractCount; i++ )
488 : {
489 1361 : uno::Sequence< beans::PropertyValue > level = aThis[i];
490 1361 : if ( level.hasElements() )
491 : {
492 : // If the element contains something, merge it
493 1361 : lcl_mergeProperties( level, aAbstract[i] );
494 : }
495 1361 : }
496 :
497 9596 : return aAbstract;
498 : }
499 :
500 4934 : uno::Reference< container::XNameContainer > lcl_getUnoNumberingStyles(
501 : uno::Reference<lang::XMultiServiceFactory> const& xFactory)
502 : {
503 4934 : uno::Reference< container::XNameContainer > xStyles;
504 :
505 : try
506 : {
507 4934 : uno::Reference< style::XStyleFamiliesSupplier > xFamilies( xFactory, uno::UNO_QUERY_THROW );
508 9770 : uno::Any oFamily = xFamilies->getStyleFamilies( )->getByName("NumberingStyles");
509 :
510 9770 : oFamily >>= xStyles;
511 : }
512 49 : catch ( const uno::Exception & )
513 : {
514 : }
515 :
516 4934 : return xStyles;
517 : }
518 :
519 4934 : void ListDef::CreateNumberingRules( DomainMapper& rDMapper,
520 : uno::Reference<lang::XMultiServiceFactory> const& xFactory)
521 : {
522 : // Get the UNO Numbering styles
523 4934 : uno::Reference< container::XNameContainer > xStyles = lcl_getUnoNumberingStyles( xFactory );
524 :
525 : // Do the whole thing
526 4934 : if( !m_xNumRules.is() && xFactory.is() && xStyles.is( ) )
527 : {
528 : try
529 : {
530 : // Create the numbering style
531 : uno::Reference< beans::XPropertySet > xStyle (
532 4884 : xFactory->createInstance("com.sun.star.style.NumberingStyle"),
533 4884 : uno::UNO_QUERY_THROW );
534 :
535 9768 : OUString sStyleName = GetStyleName( GetId( ) );
536 :
537 4970 : xStyles->insertByName( sStyleName, makeAny( xStyle ) );
538 :
539 9596 : uno::Any oStyle = xStyles->getByName( sStyleName );
540 4798 : xStyle.set( oStyle, uno::UNO_QUERY_THROW );
541 :
542 4798 : PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
543 :
544 : // Get the default OOo Numbering style rules
545 9596 : uno::Any aRules = xStyle->getPropertyValue( aPropNameSupplier.GetName( PROP_NUMBERING_RULES ) );
546 4798 : aRules >>= m_xNumRules;
547 :
548 9596 : uno::Sequence< uno::Sequence< beans::PropertyValue > > aProps = GetPropertyValues( );
549 :
550 4798 : sal_Int32 nAbstLevels = m_pAbstractDef ? m_pAbstractDef->Size() : 0;
551 4798 : sal_Int16 nLevel = 0;
552 46149 : while ( nLevel < nAbstLevels )
553 : {
554 36553 : ListLevel::Pointer pAbsLevel = m_pAbstractDef->GetLevel( nLevel );
555 73106 : ListLevel::Pointer pLevel = GetLevel( nLevel );
556 :
557 : // Get the merged level properties
558 73106 : auto aLvlProps = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aProps[sal_Int32(nLevel)]);
559 :
560 : // Get the char style
561 73106 : uno::Sequence< beans::PropertyValue > aAbsCharStyleProps = pAbsLevel->GetCharStyleProperties( );
562 36553 : uno::Sequence< beans::PropertyValue >& rAbsCharStyleProps = aAbsCharStyleProps;
563 36553 : if ( pLevel.get( ) )
564 : {
565 : uno::Sequence< beans::PropertyValue > aCharStyleProps =
566 1361 : pLevel->GetCharStyleProperties( );
567 1361 : uno::Sequence< beans::PropertyValue >& rCharStyleProps = aCharStyleProps;
568 1361 : lcl_mergeProperties( rAbsCharStyleProps, rCharStyleProps );
569 : }
570 :
571 36553 : if( aAbsCharStyleProps.getLength() )
572 : {
573 : // Change the sequence into a vector
574 10391 : PropertyValueVector_t aStyleProps;
575 27134 : for ( sal_Int32 i = 0, nLen = aAbsCharStyleProps.getLength() ; i < nLen; i++ )
576 : {
577 16743 : aStyleProps.push_back( aAbsCharStyleProps[i] );
578 : }
579 :
580 : //create (or find) a character style containing the character
581 : // attributes of the symbol and apply it to the numbering level
582 20782 : OUString sStyle = rDMapper.getOrCreateCharStyle( aStyleProps );
583 20782 : aLvlProps.push_back(comphelper::makePropertyValue(aPropNameSupplier.GetName(PROP_CHAR_STYLE_NAME), sStyle));
584 : }
585 :
586 : // Get the prefix / suffix / Parent numbering
587 : // and add them to the level properties
588 73106 : OUString sText = pAbsLevel->GetBulletChar( );
589 : // Inherit <w:lvlText> from the abstract level in case the override would be empty.
590 36553 : if (pLevel.get() && !pLevel->GetBulletChar().isEmpty())
591 206 : sText = pLevel->GetBulletChar( );
592 :
593 73106 : OUString sPrefix;
594 73106 : OUString sSuffix;
595 36553 : OUString& rPrefix = sPrefix;
596 36553 : OUString& rSuffix = sSuffix;
597 : sal_Int16 nParentNum = ListLevel::GetParentNumbering(
598 36553 : sText, nLevel, rPrefix, rSuffix );
599 :
600 36553 : aLvlProps.push_back(comphelper::makePropertyValue(aPropNameSupplier.GetName(PROP_PREFIX), rPrefix));
601 :
602 36553 : if (sText.isEmpty())
603 : {
604 : // Empty <w:lvlText>? Then put a Unicode "zero width space" as a suffix, so LabelFollowedBy is still shown, as in Word.
605 : // With empty suffix, Writer does not show LabelFollowedBy, either.
606 3700 : auto it = std::find_if(aLvlProps.begin(), aLvlProps.end(), [](const beans::PropertyValue& rValue) { return rValue.Name == "NumberingType"; });
607 1327 : if (it != aLvlProps.end())
608 : {
609 1327 : sal_Int16 nNumberFormat = it->Value.get<sal_Int16>();
610 1327 : if (nNumberFormat == style::NumberingType::NUMBER_NONE)
611 1299 : rSuffix = OUString(static_cast<sal_Unicode>(0x200B));
612 : }
613 : }
614 :
615 36553 : aLvlProps.push_back(comphelper::makePropertyValue(aPropNameSupplier.GetName(PROP_SUFFIX), rSuffix));
616 36553 : aLvlProps.push_back(comphelper::makePropertyValue(aPropNameSupplier.GetName(PROP_PARENT_NUMBERING), nParentNum));
617 :
618 36553 : aLvlProps.push_back(comphelper::makePropertyValue(aPropNameSupplier.GetName(PROP_POSITION_AND_SPACE_MODE), sal_Int16(text::PositionAndSpaceMode::LABEL_ALIGNMENT)));
619 :
620 :
621 : // Replace the numbering rules for the level
622 36553 : m_xNumRules->replaceByIndex(nLevel, uno::makeAny(comphelper::containerToSequence(aLvlProps)));
623 :
624 : // Handle the outline level here
625 36553 : if ( pAbsLevel->isOutlineNumbering())
626 : {
627 : uno::Reference< text::XChapterNumberingSupplier > xOutlines (
628 632 : xFactory, uno::UNO_QUERY_THROW );
629 : uno::Reference< container::XIndexReplace > xOutlineRules =
630 1264 : xOutlines->getChapterNumberingRules( );
631 :
632 1264 : StyleSheetEntryPtr pParaStyle = pAbsLevel->GetParaStyle( );
633 632 : aLvlProps.push_back(comphelper::makePropertyValue(aPropNameSupplier.GetName(PROP_HEADING_STYLE_NAME), pParaStyle->sConvertedStyleName));
634 :
635 1264 : xOutlineRules->replaceByIndex(nLevel, uno::makeAny(comphelper::containerToSequence(aLvlProps)));
636 : }
637 :
638 36553 : nLevel++;
639 36553 : }
640 :
641 : // Create the numbering style for these rules
642 9596 : OUString sNumRulesName = aPropNameSupplier.GetName( PROP_NUMBERING_RULES );
643 9682 : xStyle->setPropertyValue( sNumRulesName, uno::makeAny( m_xNumRules ) );
644 : }
645 0 : catch( const lang::IllegalArgumentException& e )
646 : {
647 : SAL_WARN( "writerfilter", "Exception: " << e.Message );
648 : assert( !"Incorrect argument to UNO call" );
649 : }
650 0 : catch( const uno::RuntimeException& e )
651 : {
652 : SAL_WARN( "writerfilter", "Exception: " << e.Message );
653 : assert( !"Incorrect argument to UNO call" );
654 : }
655 86 : catch( const uno::Exception& e )
656 : {
657 : SAL_WARN( "writerfilter", "Exception: " << e.Message );
658 : }
659 4934 : }
660 :
661 4934 : }
662 :
663 : //------------------------------------- NumberingManager implementation
664 :
665 :
666 494 : ListsManager::ListsManager(DomainMapper& rDMapper,
667 : const uno::Reference<lang::XMultiServiceFactory> & xFactory)
668 : : LoggedProperties("ListsManager")
669 : , LoggedTable("ListsManager")
670 : , m_rDMapper(rDMapper)
671 : , m_xFactory(xFactory)
672 494 : , m_bIsLFOImport(false)
673 : {
674 494 : }
675 :
676 1482 : ListsManager::~ListsManager( )
677 : {
678 494 : DisposeNumPicBullets();
679 988 : }
680 :
681 673 : void ListsManager::DisposeNumPicBullets( )
682 : {
683 673 : uno::Reference<drawing::XShape> xShape;
684 751 : for (std::vector<NumPicBullet::Pointer>::iterator it = m_aNumPicBullets.begin(); it != m_aNumPicBullets.end(); ++it)
685 : {
686 78 : xShape = (*it)->GetShape();
687 78 : if (xShape.is())
688 : {
689 78 : uno::Reference<lang::XComponent> xShapeComponent(xShape, uno::UNO_QUERY);
690 78 : xShapeComponent->dispose();
691 : }
692 673 : }
693 673 : }
694 :
695 213305 : void ListsManager::lcl_attribute( Id nName, Value& rVal )
696 : {
697 213305 : ListLevel::Pointer pCurrentLvl;
698 :
699 213305 : if (nName != NS_ooxml::LN_CT_NumPicBullet_numPicBulletId)
700 : {
701 : OSL_ENSURE( m_pCurrentDefinition.get(), "current entry has to be set here");
702 213234 : if(!m_pCurrentDefinition.get())
703 0 : return ;
704 213234 : pCurrentLvl = m_pCurrentDefinition->GetCurrentLevel( );
705 : }
706 : else
707 : {
708 : SAL_WARN_IF(!m_pCurrentNumPicBullet.get(), "writerfilter", "current entry has to be set here");
709 71 : if (!m_pCurrentNumPicBullet.get())
710 0 : return;
711 : }
712 213305 : int nIntValue = rVal.getInt();
713 :
714 :
715 :
716 213305 : switch(nName)
717 : {
718 : case NS_ooxml::LN_CT_LevelText_val:
719 : {
720 : //this strings contains the definition of the level
721 : //the level number is marked as %n
722 : //these numbers can be mixed randomly together with separators pre- and suffixes
723 : //the Writer supports only a number of upper levels to show, separators is always a dot
724 : //and each level can have a prefix and a suffix
725 34524 : if(pCurrentLvl.get())
726 34521 : pCurrentLvl->SetBulletChar( rVal.getString() );
727 : }
728 34524 : break;
729 : case NS_ooxml::LN_CT_Lvl_start:
730 : case NS_ooxml::LN_CT_Lvl_numFmt:
731 : case NS_ooxml::LN_CT_Lvl_isLgl:
732 : case NS_ooxml::LN_CT_Lvl_legacy:
733 0 : if ( pCurrentLvl.get( ) )
734 0 : pCurrentLvl->SetValue( nName, sal_Int32( nIntValue ) );
735 0 : break;
736 : case NS_ooxml::LN_CT_Num_numId:
737 4802 : m_pCurrentDefinition->SetId( rVal.getString().toInt32( ) );
738 4802 : break;
739 : case NS_ooxml::LN_CT_AbstractNum_nsid:
740 128 : m_pCurrentDefinition->SetId( nIntValue );
741 128 : break;
742 : case NS_ooxml::LN_CT_AbstractNum_tmpl:
743 0 : m_pCurrentDefinition->SetValue( nName, nIntValue );
744 0 : break;
745 : case NS_ooxml::LN_CT_NumLvl_ilvl:
746 : {
747 : //add a new level to the level vector and make it the current one
748 1361 : m_pCurrentDefinition->AddLevel();
749 :
750 1361 : writerfilter::Reference<Properties>::Pointer_t pProperties;
751 1361 : if((pProperties = rVal.getProperties()).get())
752 5 : pProperties->resolve(*this);
753 : }
754 1361 : break;
755 : case NS_ooxml::LN_CT_AbstractNum_abstractNumId:
756 : {
757 : // This one corresponds to the AbstractNum Id definition
758 : // The reference to the abstract num is in the sprm method
759 4483 : sal_Int32 nVal = rVal.getString().toInt32();
760 4483 : m_pCurrentDefinition->SetId( nVal );
761 : }
762 4483 : break;
763 : case NS_ooxml::LN_CT_Ind_left:
764 31530 : pCurrentLvl->Insert(
765 63060 : PROP_INDENT_AT, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
766 31530 : break;
767 : case NS_ooxml::LN_CT_Ind_hanging:
768 32203 : pCurrentLvl->Insert(
769 64406 : PROP_FIRST_LINE_INDENT, uno::makeAny( - ConversionHelper::convertTwipToMM100( nIntValue ) ));
770 32203 : break;
771 : case NS_ooxml::LN_CT_Ind_firstLine:
772 473 : pCurrentLvl->Insert(
773 946 : PROP_FIRST_LINE_INDENT, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
774 473 : break;
775 : case NS_ooxml::LN_CT_Lvl_ilvl: //overrides previous level - unsupported
776 : case NS_ooxml::LN_CT_Lvl_tplc: //template code - unsupported
777 : case NS_ooxml::LN_CT_Lvl_tentative: //marks level as unused in the document - unsupported
778 80418 : break;
779 : case NS_ooxml::LN_CT_TabStop_pos:
780 : {
781 : //no paragraph attributes in ListTable char style sheets
782 11055 : if ( pCurrentLvl.get( ) )
783 : pCurrentLvl->SetValue( nName,
784 11055 : ConversionHelper::convertTwipToMM100( nIntValue ) );
785 : }
786 11055 : break;
787 : case NS_ooxml::LN_CT_TabStop_val:
788 : {
789 : // TODO Do something of that
790 : }
791 11055 : break;
792 : case NS_ooxml::LN_CT_NumPicBullet_numPicBulletId:
793 71 : m_pCurrentNumPicBullet->SetId(rVal.getString().toInt32());
794 71 : break;
795 : default:
796 : SAL_WARN("writerfilter", "ListsManager::lcl_attribute: unhandled token: " << nName);
797 213305 : }
798 : }
799 :
800 340719 : void ListsManager::lcl_sprm( Sprm& rSprm )
801 : {
802 : //fill the attributes of the style sheet
803 340719 : sal_uInt32 nSprmId = rSprm.getId();
804 691048 : if( m_pCurrentDefinition.get() ||
805 5126 : nSprmId == NS_ooxml::LN_CT_Numbering_abstractNum ||
806 196 : nSprmId == NS_ooxml::LN_CT_Numbering_num ||
807 340790 : (nSprmId == NS_ooxml::LN_CT_NumPicBullet_pict && m_pCurrentNumPicBullet.get()) ||
808 : nSprmId == NS_ooxml::LN_CT_Numbering_numPicBullet)
809 : {
810 : static bool bIsStartVisited = false;
811 340665 : sal_Int32 nIntValue = rSprm.getValue()->getInt();
812 340665 : switch( nSprmId )
813 : {
814 : case NS_ooxml::LN_CT_Numbering_abstractNum:
815 : {
816 4484 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
817 4484 : if(pProperties.get())
818 : {
819 : //create a new Abstract list entry
820 : OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
821 4484 : m_pCurrentDefinition.reset( new AbstractListDef );
822 4484 : pProperties->resolve( *this );
823 : //append it to the table
824 4484 : m_aAbstractLists.push_back( m_pCurrentDefinition );
825 4484 : m_pCurrentDefinition = AbstractListDef::Pointer();
826 4484 : }
827 : }
828 4484 : break;
829 : case NS_ooxml::LN_CT_Numbering_num:
830 : {
831 4930 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
832 4930 : if(pProperties.get())
833 : {
834 : // Create a new list entry
835 : OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
836 4930 : ListDef::Pointer listDef( new ListDef );
837 4930 : m_pCurrentDefinition = listDef;
838 4930 : pProperties->resolve( *this );
839 : //append it to the table
840 4930 : m_aLists.push_back( listDef );
841 :
842 4930 : m_pCurrentDefinition = AbstractListDef::Pointer();
843 4930 : }
844 : }
845 4930 : break;
846 : case NS_ooxml::LN_CT_Numbering_numPicBullet:
847 : {
848 71 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
849 71 : if (pProperties.get())
850 : {
851 71 : NumPicBullet::Pointer numPicBullet(new NumPicBullet());
852 71 : m_pCurrentNumPicBullet = numPicBullet;
853 71 : pProperties->resolve(*this);
854 71 : m_aNumPicBullets.push_back(numPicBullet);
855 71 : m_pCurrentNumPicBullet = NumPicBullet::Pointer();
856 71 : }
857 : }
858 71 : break;
859 : case NS_ooxml::LN_CT_NumPicBullet_pict:
860 : {
861 71 : uno::Reference<drawing::XShape> xShape = m_rDMapper.PopPendingShape();
862 71 : m_pCurrentNumPicBullet->SetShape(xShape);
863 : }
864 71 : break;
865 : case NS_ooxml::LN_CT_Lvl_lvlPicBulletId:
866 : {
867 50 : uno::Reference<drawing::XShape> xShape;
868 95 : for (std::vector<NumPicBullet::Pointer>::iterator it = m_aNumPicBullets.begin(); it != m_aNumPicBullets.end(); ++it)
869 : {
870 95 : if ((*it)->GetId() == nIntValue)
871 : {
872 50 : xShape = (*it)->GetShape();
873 50 : break;
874 : }
875 : }
876 50 : if (xShape.is())
877 : {
878 50 : uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
879 : try
880 : {
881 70 : uno::Any aAny = xPropertySet->getPropertyValue("GraphicURL");
882 30 : if (aAny.has<OUString>())
883 19 : m_pCurrentDefinition->GetCurrentLevel()->SetGraphicURL(aAny.get<OUString>());
884 20 : } catch(const beans::UnknownPropertyException&)
885 : {}
886 : try
887 : {
888 50 : uno::Reference< graphic::XGraphic > gr;
889 50 : xPropertySet->getPropertyValue("Bitmap") >>= gr;
890 50 : m_pCurrentDefinition->GetCurrentLevel()->SetGraphicBitmap( gr );
891 0 : } catch(const beans::UnknownPropertyException&)
892 : {}
893 :
894 : // Now that we saved the URL of the graphic, remove it from the document.
895 100 : uno::Reference<lang::XComponent> xShapeComponent(xShape, uno::UNO_QUERY);
896 100 : xShapeComponent->dispose();
897 50 : }
898 : }
899 50 : break;
900 : case NS_ooxml::LN_CT_Num_abstractNumId:
901 : {
902 4930 : sal_Int32 nAbstractNumId = rSprm.getValue()->getInt();
903 4930 : ListDef* pListDef = dynamic_cast< ListDef* >( m_pCurrentDefinition.get( ) );
904 4930 : if ( pListDef != nullptr )
905 : {
906 : // The current def should be a ListDef
907 : pListDef->SetAbstractDefinition(
908 4930 : GetAbstractList( nAbstractNumId ) );
909 : }
910 : }
911 4930 : break;
912 : case NS_ooxml::LN_CT_AbstractNum_multiLevelType:
913 4230 : break;
914 : case NS_ooxml::LN_CT_AbstractNum_tmpl:
915 4229 : m_pCurrentDefinition->SetValue( nSprmId, nIntValue );
916 4229 : break;
917 : case NS_ooxml::LN_CT_AbstractNum_lvl:
918 : {
919 34315 : m_pCurrentDefinition->AddLevel();
920 34315 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
921 34315 : if(pProperties.get())
922 34315 : pProperties->resolve(*this);
923 : }
924 34315 : break;
925 : case NS_ooxml::LN_CT_Lvl_start:
926 34015 : if (m_pCurrentDefinition->GetCurrentLevel().get())
927 34012 : m_pCurrentDefinition->GetCurrentLevel( )->SetValue( nSprmId, nIntValue );
928 34015 : bIsStartVisited = true;
929 34015 : break;
930 : case NS_ooxml::LN_CT_Lvl_numFmt:
931 : case NS_ooxml::LN_CT_Lvl_isLgl:
932 : case NS_ooxml::LN_CT_Lvl_legacy:
933 34924 : if (m_pCurrentDefinition->GetCurrentLevel().get())
934 : {
935 34921 : m_pCurrentDefinition->GetCurrentLevel( )->SetValue( nSprmId, nIntValue );
936 34921 : if( !bIsStartVisited )
937 : {
938 5 : m_pCurrentDefinition->GetCurrentLevel( )->SetValue( NS_ooxml::LN_CT_Lvl_start, 0 );
939 5 : bIsStartVisited = true;
940 : }
941 : }
942 34924 : break;
943 : case NS_ooxml::LN_CT_Lvl_suff:
944 : {
945 1412 : if (m_pCurrentDefinition->GetCurrentLevel().get())
946 : {
947 1409 : SvxNumberFormat::LabelFollowedBy value = SvxNumberFormat::LISTTAB;
948 1409 : if( rSprm.getValue()->getString() == "tab" )
949 458 : value = SvxNumberFormat::LISTTAB;
950 951 : else if( rSprm.getValue()->getString() == "space" )
951 35 : value = SvxNumberFormat::SPACE;
952 916 : else if( rSprm.getValue()->getString() == "nothing" )
953 916 : value = SvxNumberFormat::NOTHING;
954 : else
955 : SAL_WARN( "writerfilter", "Unknown ST_LevelSuffix value "
956 : << rSprm.getValue()->getString());
957 1409 : m_pCurrentDefinition->GetCurrentLevel()->SetValue( nSprmId, value );
958 : }
959 : }
960 1412 : break;
961 : case NS_ooxml::LN_CT_Lvl_lvlText:
962 : case NS_ooxml::LN_CT_Lvl_rPr : //contains LN_EG_RPrBase_rFonts
963 : {
964 56585 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
965 56585 : if(pProperties.get())
966 56585 : pProperties->resolve(*this);
967 : }
968 56585 : break;
969 : case NS_ooxml::LN_CT_NumLvl_lvl:
970 : {
971 : // overwrite level
972 206 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
973 206 : if(pProperties.get())
974 206 : pProperties->resolve(*this);
975 : }
976 206 : break;
977 : case NS_ooxml::LN_CT_Lvl_lvlJc:
978 : {
979 34512 : sal_Int16 nValue = 0;
980 34512 : switch (nIntValue)
981 : {
982 : case NS_ooxml::LN_Value_ST_Jc_left:
983 : case NS_ooxml::LN_Value_ST_Jc_start:
984 30876 : nValue = text::HoriOrientation::LEFT;
985 30876 : break;
986 : case NS_ooxml::LN_Value_ST_Jc_center:
987 12 : nValue = text::HoriOrientation::CENTER;
988 12 : break;
989 : case NS_ooxml::LN_Value_ST_Jc_right:
990 : case NS_ooxml::LN_Value_ST_Jc_end:
991 3624 : nValue = text::HoriOrientation::RIGHT;
992 3624 : break;
993 : }
994 69024 : m_pCurrentDefinition->GetCurrentLevel( )->Insert(
995 103536 : PROP_ADJUST, uno::makeAny( nValue ) );
996 34512 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
997 : }
998 34512 : break;
999 : case NS_ooxml::LN_CT_Lvl_pPr:
1000 : case NS_ooxml::LN_CT_PPrBase_ind:
1001 : {
1002 : //todo: how to handle paragraph properties within numbering levels (except LeftIndent and FirstLineIndent)?
1003 65484 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1004 65484 : if(pProperties.get())
1005 65484 : pProperties->resolve(*this);
1006 : }
1007 65484 : break;
1008 : case NS_ooxml::LN_CT_PPrBase_tabs:
1009 : case NS_ooxml::LN_CT_Tabs_tab:
1010 : {
1011 22110 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1012 22110 : if(pProperties.get())
1013 22110 : pProperties->resolve(*this);
1014 : }
1015 22110 : break;
1016 : case NS_ooxml::LN_CT_Lvl_pStyle:
1017 : {
1018 786 : OUString sStyleName = rSprm.getValue( )->getString( );
1019 1572 : ListLevel::Pointer pLevel = m_pCurrentDefinition->GetCurrentLevel( );
1020 1572 : StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( );
1021 1572 : const StyleSheetEntryPtr pStyle = pStylesTable->FindStyleSheetByISTD( sStyleName );
1022 1572 : pLevel->SetParaStyle( pStyle );
1023 : }
1024 786 : break;
1025 : case NS_ooxml::LN_CT_Num_lvlOverride:
1026 : {
1027 1361 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1028 1361 : if (pProperties.get())
1029 1361 : pProperties->resolve(*this);
1030 : }
1031 1361 : break;
1032 : case NS_ooxml::LN_CT_NumLvl_startOverride:
1033 : {
1034 1097 : if(m_pCurrentDefinition)
1035 : {
1036 1097 : if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel())
1037 : // <w:num> -> <w:lvlOverride> -> <w:startOverride> is the non-abstract equivalent of
1038 : // <w:abstractNum> -> <w:lvl> -> <w:start>
1039 1097 : pCurrentLevel->SetValue(NS_ooxml::LN_CT_Lvl_start, nIntValue);
1040 : }
1041 : }
1042 1097 : break;
1043 : case NS_ooxml::LN_CT_AbstractNum_numStyleLink:
1044 : {
1045 14 : OUString sStyleName = rSprm.getValue( )->getString( );
1046 14 : AbstractListDef* pAbstractListDef = dynamic_cast< AbstractListDef* >( m_pCurrentDefinition.get( ) );
1047 14 : pAbstractListDef->SetNumStyleLink(sStyleName);
1048 : }
1049 14 : break;
1050 : case NS_ooxml::LN_EG_RPrBase_rFonts: //contains font properties
1051 : case NS_ooxml::LN_EG_RPrBase_color:
1052 : case NS_ooxml::LN_EG_RPrBase_u:
1053 : case NS_ooxml::LN_EG_RPrBase_sz:
1054 : case NS_ooxml::LN_EG_RPrBase_lang:
1055 : case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
1056 : //no break!
1057 : default:
1058 30849 : if( m_pCurrentDefinition->GetCurrentLevel( ).get())
1059 : {
1060 26497 : m_rDMapper.PushListProperties( m_pCurrentDefinition->GetCurrentLevel( ) );
1061 26497 : m_rDMapper.sprm( rSprm );
1062 26497 : m_rDMapper.PopListProperties();
1063 : }
1064 : }
1065 : }
1066 340719 : }
1067 :
1068 379 : void ListsManager::lcl_entry( int /* pos */,
1069 : writerfilter::Reference<Properties>::Pointer_t ref )
1070 : {
1071 379 : if( m_rDMapper.IsOOXMLImport() || m_rDMapper.IsRTFImport() )
1072 : {
1073 379 : ref->resolve(*this);
1074 : }
1075 : else
1076 : {
1077 0 : if ( m_bIsLFOImport )
1078 : {
1079 : // Create ListDef's
1080 : OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
1081 0 : ListDef::Pointer pList( new ListDef() );
1082 0 : m_pCurrentDefinition = pList;
1083 0 : ref->resolve(*this);
1084 : //append it to the table
1085 0 : m_aLists.push_back( pList );
1086 0 : m_pCurrentDefinition = AbstractListDef::Pointer();
1087 : }
1088 : else
1089 : {
1090 : // Create AbstractListDef's
1091 : OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
1092 0 : m_pCurrentDefinition.reset( new AbstractListDef( ) );
1093 0 : ref->resolve(*this);
1094 : //append it to the table
1095 0 : m_aAbstractLists.push_back( m_pCurrentDefinition );
1096 0 : m_pCurrentDefinition = AbstractListDef::Pointer();
1097 : }
1098 : }
1099 379 : }
1100 :
1101 4930 : AbstractListDef::Pointer ListsManager::GetAbstractList( sal_Int32 nId )
1102 : {
1103 4930 : AbstractListDef::Pointer pAbstractList;
1104 :
1105 4930 : int nLen = m_aAbstractLists.size( );
1106 4930 : int i = 0;
1107 93633 : while ( !pAbstractList.get( ) && i < nLen )
1108 : {
1109 83785 : if ( m_aAbstractLists[i]->GetId( ) == nId )
1110 : {
1111 4892 : if ( m_aAbstractLists[i]->GetNumStyleLink().getLength() > 0 )
1112 : {
1113 : // If the abstract num has a style linked, check the linked style's number id.
1114 14 : StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( );
1115 :
1116 : const StyleSheetEntryPtr pStyleSheetEntry =
1117 16 : pStylesTable->FindStyleSheetByISTD( m_aAbstractLists[i]->GetNumStyleLink() );
1118 :
1119 : const StyleSheetPropertyMap* pStyleSheetProperties =
1120 14 : dynamic_cast<const StyleSheetPropertyMap*>(pStyleSheetEntry ? pStyleSheetEntry->pProperties.get() : nullptr);
1121 :
1122 14 : if( pStyleSheetProperties && pStyleSheetProperties->GetNumId() >= 0 )
1123 : {
1124 14 : ListDef::Pointer pList = GetList( pStyleSheetProperties->GetNumId() );
1125 14 : if ( pList!=nullptr )
1126 12 : return pList->GetAbstractDefinition();
1127 : else
1128 2 : pAbstractList = m_aAbstractLists[i];
1129 2 : }
1130 :
1131 : }
1132 : else
1133 : {
1134 4878 : pAbstractList = m_aAbstractLists[i];
1135 : }
1136 : }
1137 83773 : i++;
1138 : }
1139 :
1140 4918 : return pAbstractList;
1141 : }
1142 :
1143 3743 : ListDef::Pointer ListsManager::GetList( sal_Int32 nId )
1144 : {
1145 3743 : ListDef::Pointer pList;
1146 :
1147 3743 : int nLen = m_aLists.size( );
1148 3743 : int i = 0;
1149 23595 : while ( !pList.get( ) && i < nLen )
1150 : {
1151 16109 : if ( m_aLists[i]->GetId( ) == nId )
1152 2466 : pList = m_aLists[i];
1153 16109 : i++;
1154 : }
1155 :
1156 3743 : return pList;
1157 : }
1158 :
1159 379 : void ListsManager::CreateNumberingRules( )
1160 : {
1161 : // Loop over the definitions
1162 379 : std::vector< ListDef::Pointer >::iterator listIt = m_aLists.begin( );
1163 5313 : for ( ; listIt != m_aLists.end( ); ++listIt )
1164 : {
1165 4934 : (*listIt)->CreateNumberingRules( m_rDMapper, m_xFactory );
1166 : }
1167 379 : }
1168 :
1169 : } }
1170 :
1171 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|