LCOV - code coverage report
Current view: top level - writerfilter/source/dmapper - NumberingManager.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 508 546 93.0 %
Date: 2015-06-13 12:38:46 Functions: 40 40 100.0 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.11