blob: 6cfe2580308626b193dbffefdbe2bc0f77c9e57f [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include "ConversionHelper.hxx"
#include "NumberingManager.hxx"
#include "StyleSheetTable.hxx"
#include "PropertyIds.hxx"
#include <doctok/resourceids.hxx>
#include <doctok/sprmids.hxx>
#include <ooxml/resourceids.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/style/NumberingType.hpp>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/PositionAndSpaceMode.hpp>
#include <com/sun/star/text/XChapterNumberingSupplier.hpp>
#if DEBUG
#include <stdio.h>
#endif
#include "dmapperLoggers.hxx"
using namespace rtl;
using namespace com::sun::star;
#define MAKE_PROPVAL(NameId, Value) \
beans::PropertyValue(aPropNameSupplier.GetName(NameId), 0, uno::makeAny(Value), beans::PropertyState_DIRECT_VALUE )
#define OUSTR_TO_C( x ) OUStringToOString( x, RTL_TEXTENCODING_UTF8 ).getStr( )
#define NUMBERING_MAX_LEVELS 10
namespace writerfilter {
namespace dmapper {
//--------------------------------------------------- Utility functions
void lcl_printProperties( uno::Sequence< beans::PropertyValue > aProps )
{
sal_Int32 nLen = aProps.getLength( );
for ( sal_Int32 i = 0; i < nLen; i++ )
{
uno::Any aValue = aProps[i].Value;
sal_Int32 nValue = 0;
OUString sValue;
if ( !( aValue >>= sValue ) && ( aValue >>= nValue ) )
sValue = OUString::valueOf( nValue );
#if DEBUG
fprintf( stderr, "Property %s: %s\n",
OUSTR_TO_C( aProps[i].Name ),
OUSTR_TO_C( sValue ) );
#endif
}
}
sal_Int32 lcl_findProperty( uno::Sequence< beans::PropertyValue > aProps, OUString sName )
{
sal_Int32 i = 0;
sal_Int32 nLen = aProps.getLength( );
sal_Int32 nPos = -1;
while ( nPos == -1 && i < nLen )
{
if ( aProps[i].Name.equals( sName ) )
nPos = i;
else
i++;
}
return nPos;
}
void lcl_mergeProperties( uno::Sequence< beans::PropertyValue >& aSrc,
uno::Sequence< beans::PropertyValue >& aDst )
{
for ( sal_Int32 i = 0, nSrcLen = aSrc.getLength( ); i < nSrcLen; i++ )
{
// Look for the same property in aDst
sal_Int32 nPos = lcl_findProperty( aDst, aSrc[i].Name );
if ( nPos >= 0 )
{
// Replace the property value by the one in aSrc
aDst[nPos] = aSrc[i];
}
else
{
// Simply add the new value
aDst.realloc( aDst.getLength( ) + 1 );
aDst[ aDst.getLength( ) - 1 ] = aSrc[i];
}
}
}
//-------------------------------------------- ListLevel implementation
void ListLevel::SetValue( Id nId, sal_Int32 nValue )
{
switch( nId )
{
case NS_rtf::LN_ISTARTAT:
m_nIStartAt = nValue;
break;
case NS_rtf::LN_NFC:
m_nNFC = nValue;
break;
case NS_rtf::LN_JC:
m_nJC = nValue;
break;
case NS_rtf::LN_FLEGAL:
m_nFLegal = nValue;
break;
case NS_rtf::LN_FNORESTART:
m_nFNoRestart = nValue;
break;
case NS_rtf::LN_FIDENTSAV:
m_nFPrev = nValue;
break;
case NS_rtf::LN_FCONVERTED:
m_nFPrevSpace = nValue;
break;
#if 0
case NS_rtf::LN_FWORD6:
m_nFWord6 = nValue;
break;
#endif
case NS_rtf::LN_IXCHFOLLOW:
m_nXChFollow = nValue;
break;
case NS_ooxml::LN_CT_TabStop_pos:
m_nTabstop = nValue;
break;
default:
OSL_ENSURE( false, "this line should never be reached");
}
}
sal_Int16 ListLevel::GetParentNumbering( OUString sText, sal_Int16 nLevel,
OUString& rPrefix, OUString& rSuffix )
{
sal_Int16 nParentNumbering = nLevel;
//now parse the text to find %n from %1 to %nLevel+1
//everything before the first % and the last %x is prefix and suffix
OUString sLevelText( sText );
sal_Int32 nCurrentIndex = 0;
sal_Int32 nFound = sLevelText.indexOf( '%', nCurrentIndex );
if( nFound > 0 )
{
rPrefix = sLevelText.copy( 0, nFound );
sLevelText = sLevelText.copy( nFound );
}
sal_Int32 nMinLevel = nLevel;
//now the text should either be empty or start with %
nFound = sLevelText.getLength( ) > 1 ? 0 : -1;
while( nFound >= 0 )
{
if( sLevelText.getLength() > 1 )
{
sal_Unicode cLevel = sLevelText.getStr()[1];
if( cLevel >= '1' && cLevel <= '9' )
{
if( cLevel - '1' < nMinLevel )
nMinLevel = cLevel - '1';
//remove first char - next char is removed later
sLevelText = sLevelText.copy( 1 );
}
}
//remove old '%' or number
sLevelText = sLevelText.copy( 1 );
nCurrentIndex = 0;
nFound = sLevelText.indexOf( '%', nCurrentIndex );
//remove the text before the next %
if(nFound > 0)
sLevelText = sLevelText.copy( nFound -1 );
}
if( nMinLevel < nLevel )
{
nParentNumbering = sal_Int16( nLevel - nMinLevel + 1);
}
rSuffix = sLevelText;
return nParentNumbering;
}
uno::Sequence< beans::PropertyValue > ListLevel::GetProperties( )
{
uno::Sequence< beans::PropertyValue > aLevelProps = GetLevelProperties( );
if ( m_pParaStyle.get( ) )
{
// Merge with the paragraph properties
uno::Sequence< beans::PropertyValue > aParaProps = GetParaProperties( );
lcl_mergeProperties( aParaProps, aLevelProps );
}
return aLevelProps;
}
uno::Sequence< beans::PropertyValue > ListLevel::GetCharStyleProperties( )
{
PropertyValueVector_t rProperties;
PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
_PropertyMap::const_iterator aMapIter = begin();
_PropertyMap::const_iterator aEndIter = end();
for( ; aMapIter != aEndIter; ++aMapIter )
{
switch( aMapIter->first.eId )
{
case PROP_ADJUST:
case PROP_INDENT_AT:
case PROP_FIRST_LINE_INDENT:
case PROP_FIRST_LINE_OFFSET:
case PROP_LEFT_MARGIN:
case PROP_CHAR_FONT_NAME:
// Do nothing: handled in the GetPropertyValues method
break;
default:
{
rProperties.push_back(
beans::PropertyValue(
aPropNameSupplier.GetName( aMapIter->first.eId ), 0,
aMapIter->second, beans::PropertyState_DIRECT_VALUE ));
}
}
}
uno::Sequence< beans::PropertyValue > aRet( rProperties.size() );
beans::PropertyValue* pValues = aRet.getArray();
PropertyValueVector_t::const_iterator aIt = rProperties.begin();
PropertyValueVector_t::const_iterator aEndIt = rProperties.end();
for(sal_uInt32 nIndex = 0; aIt != aEndIt; ++aIt,++nIndex)
{
pValues[nIndex] = *aIt;
}
return aRet;
}
uno::Sequence< beans::PropertyValue > ListLevel::GetLevelProperties( )
{
const sal_Int16 aWWToUnoAdjust[] =
{
text::HoriOrientation::LEFT,
text::HoriOrientation::CENTER,
text::HoriOrientation::RIGHT,
};
PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
PropertyValueVector_t aNumberingProperties;
if( m_nIStartAt >= 0)
aNumberingProperties.push_back( MAKE_PROPVAL(PROP_START_WITH, (sal_Int16)m_nIStartAt) );
sal_Int16 nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC);
if( m_nNFC >= 0)
aNumberingProperties.push_back( MAKE_PROPVAL(PROP_NUMBERING_TYPE, nNumberFormat ));
if( m_nJC >= 0 && m_nJC <= sal::static_int_cast<sal_Int32>(sizeof(aWWToUnoAdjust) / sizeof(sal_Int16)) )
aNumberingProperties.push_back( MAKE_PROPVAL(PROP_ADJUST, aWWToUnoAdjust[m_nJC]));
// todo: this is not the bullet char
if( nNumberFormat == style::NumberingType::CHAR_SPECIAL && m_sBulletChar.getLength() )
aNumberingProperties.push_back( MAKE_PROPVAL(PROP_BULLET_CHAR, m_sBulletChar.copy(0,1)));
aNumberingProperties.push_back( MAKE_PROPVAL( PROP_LISTTAB_STOP_POSITION, m_nTabstop ) );
//TODO: handling of nFLegal?
//TODO: nFNoRestart lower levels do not restart when higher levels are incremented, like:
//1.
//1.1
//2.2
//2.3
//3.4
//
if( m_nFWord6 > 0) //Word 6 compatibility
{
if( m_nFPrev == 1)
aNumberingProperties.push_back( MAKE_PROPVAL( PROP_PARENT_NUMBERING, (sal_Int16) NUMBERING_MAX_LEVELS ));
//TODO: prefixing space nFPrevSpace; - has not been used in WW8 filter
}
// TODO: sRGBXchNums; array of inherited numbers
// TODO: nXChFollow; following character 0 - tab, 1 - space, 2 - nothing
_PropertyMap::const_iterator aMapIter = begin();
_PropertyMap::const_iterator aEndIter = end();
for( ; aMapIter != aEndIter; ++aMapIter )
{
switch( aMapIter->first.eId )
{
case PROP_ADJUST:
case PROP_INDENT_AT:
case PROP_FIRST_LINE_INDENT:
case PROP_FIRST_LINE_OFFSET:
case PROP_LEFT_MARGIN:
aNumberingProperties.push_back(
beans::PropertyValue( aPropNameSupplier.GetName( aMapIter->first.eId ), 0, aMapIter->second, beans::PropertyState_DIRECT_VALUE ));
break;
case PROP_CHAR_FONT_NAME:
aNumberingProperties.push_back(
beans::PropertyValue( aPropNameSupplier.GetName( PROP_BULLET_FONT_NAME ), 0, aMapIter->second, beans::PropertyState_DIRECT_VALUE ));
break;
default:
{
// Handled in GetCharStyleProperties method
}
}
}
uno::Sequence< beans::PropertyValue > aRet(aNumberingProperties.size());
beans::PropertyValue* pValues = aRet.getArray();
PropertyValueVector_t::const_iterator aIt = aNumberingProperties.begin();
PropertyValueVector_t::const_iterator aEndIt = aNumberingProperties.end();
for(sal_uInt32 nIndex = 0; aIt != aEndIt; ++aIt,++nIndex)
{
pValues[nIndex] = *aIt;
}
return aRet;
}
uno::Sequence< beans::PropertyValue > ListLevel::GetParaProperties( )
{
PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
uno::Sequence< beans::PropertyValue > aParaProps = m_pParaStyle->pProperties->GetPropertyValues( );
uno::Sequence< beans::PropertyValue > aProps;
// ParaFirstLineIndent -> FirstLineIndent
// ParaLeftMargin -> IndentAt
OUString sParaIndent = aPropNameSupplier.GetName(
PROP_PARA_FIRST_LINE_INDENT );
OUString sFirstLineIndent = aPropNameSupplier.GetName(
PROP_FIRST_LINE_INDENT );
OUString sParaLeftMargin = aPropNameSupplier.GetName(
PROP_PARA_LEFT_MARGIN );
OUString sIndentAt = aPropNameSupplier.GetName(
PROP_INDENT_AT );
sal_Int32 nLen = aParaProps.getLength( );
for ( sal_Int32 i = 0; i < nLen; i++ )
{
if ( aParaProps[i].Name.equals( sParaIndent ) )
{
aProps.realloc( aProps.getLength() + 1 );
aProps[aProps.getLength( ) - 1] = aParaProps[i];
aProps[aProps.getLength( ) - 1].Name = sFirstLineIndent;
}
else if ( aParaProps[i].Name.equals( sParaLeftMargin ) )
{
aProps.realloc( aProps.getLength() + 1 );
aProps[aProps.getLength( ) - 1] = aParaProps[i];
aProps[aProps.getLength( ) - 1].Name = sIndentAt;
}
}
return aProps;
}
//--------------------------------------- AbstractListDef implementation
AbstractListDef::AbstractListDef( ) :
m_nTPLC( -1 )
,m_nSimpleList( -1 )
,m_nRestart( -1 )
,m_nUnsigned( -1 )
,m_nId( -1 )
{
}
AbstractListDef::~AbstractListDef( )
{
}
void AbstractListDef::SetValue( sal_uInt32 nSprmId, sal_Int32 nValue )
{
switch( nSprmId )
{
case NS_rtf::LN_TPLC:
m_nTPLC = nValue;
break;
case NS_rtf::LN_FSIMPLELIST:
m_nSimpleList = nValue;
break;
case NS_rtf::LN_fAutoNum:
m_nRestart = nValue;
break;
case NS_rtf::LN_fHybrid:
m_nUnsigned = nValue;
break;
default:
OSL_ENSURE( false, "this line should never be reached");
}
}
ListLevel::Pointer AbstractListDef::GetLevel( sal_uInt16 nLvl )
{
ListLevel::Pointer pLevel;
if ( m_aLevels.size( ) > nLvl )
pLevel = m_aLevels[ nLvl ];
return pLevel;
}
void AbstractListDef::AddLevel( )
{
ListLevel::Pointer pLevel( new ListLevel );
m_pCurrentLevel = pLevel;
m_aLevels.push_back( pLevel );
}
uno::Sequence< uno::Sequence< beans::PropertyValue > > AbstractListDef::GetPropertyValues( )
{
uno::Sequence< uno::Sequence< beans::PropertyValue > > result( sal_Int32( m_aLevels.size( ) ) );
uno::Sequence< beans::PropertyValue >* aResult = result.getArray( );
int nLevels = m_aLevels.size( );
for ( int i = 0; i < nLevels; i++ )
{
aResult[i] = m_aLevels[i]->GetProperties( );
}
return result;
}
//---------------------------------------------- ListDef implementation
ListDef::ListDef( ) : AbstractListDef( )
{
}
ListDef::~ListDef( )
{
}
OUString ListDef::GetStyleName( sal_Int32 nId )
{
OUString sStyleName( OUString::createFromAscii( "WWNum" ) );
sStyleName += OUString::valueOf( nId );
return sStyleName;
}
uno::Sequence< uno::Sequence< beans::PropertyValue > > ListDef::GetPropertyValues( )
{
// [1] Call the same method on the abstract list
uno::Sequence< uno::Sequence< beans::PropertyValue > > aAbstract = m_pAbstractDef->GetPropertyValues( );
// [2] Call the upper class method
uno::Sequence< uno::Sequence< beans::PropertyValue > > aThis = AbstractListDef::GetPropertyValues( );
// Merge the results of [2] in [1]
sal_Int32 nThisCount = aThis.getLength( );
for ( sal_Int32 i = 0; i < nThisCount; i++ )
{
uno::Sequence< beans::PropertyValue > level = aThis[i];
if ( level.getLength( ) == 0 )
{
// If the the element contains something, merge it
lcl_mergeProperties( level, aAbstract[i] );
}
}
return aAbstract;
}
uno::Reference< container::XNameContainer > lcl_getUnoNumberingStyles(
uno::Reference< lang::XMultiServiceFactory > xFactory )
{
uno::Reference< container::XNameContainer > xStyles;
try
{
uno::Reference< style::XStyleFamiliesSupplier > xFamilies( xFactory, uno::UNO_QUERY_THROW );
uno::Any oFamily = xFamilies->getStyleFamilies( )->getByName( OUString::createFromAscii( "NumberingStyles" ) );
oFamily >>= xStyles;
}
catch ( const uno::Exception )
{
}
return xStyles;
}
void ListDef::CreateNumberingRules( DomainMapper& rDMapper,
uno::Reference< lang::XMultiServiceFactory> xFactory )
{
// Get the UNO Numbering styles
uno::Reference< container::XNameContainer > xStyles = lcl_getUnoNumberingStyles( xFactory );
// Do the whole thing
if( !m_xNumRules.is() && xFactory.is() && xStyles.is( ) )
{
try
{
// Create the numbering style
uno::Reference< beans::XPropertySet > xStyle (
xFactory->createInstance(
OUString::createFromAscii("com.sun.star.style.NumberingStyle")),
uno::UNO_QUERY_THROW );
rtl::OUString sStyleName = GetStyleName( GetId( ) );
xStyles->insertByName( sStyleName, makeAny( xStyle ) );
uno::Any oStyle = xStyles->getByName( sStyleName );
xStyle.set( oStyle, uno::UNO_QUERY_THROW );
PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
// Get the default OOo Numbering style rules
uno::Any aRules = xStyle->getPropertyValue( aPropNameSupplier.GetName( PROP_NUMBERING_RULES ) );
aRules >>= m_xNumRules;
uno::Sequence< uno::Sequence< beans::PropertyValue > > aProps = GetPropertyValues( );
sal_Int32 nAbstLevels = m_pAbstractDef->Size( );
sal_Int16 nLevel = 0;
while ( nLevel < nAbstLevels )
{
ListLevel::Pointer pAbsLevel = m_pAbstractDef->GetLevel( nLevel );
ListLevel::Pointer pLevel = GetLevel( nLevel );
// Get the merged level properties
uno::Sequence< beans::PropertyValue > aLvlProps = aProps[sal_Int32( nLevel )];
lcl_printProperties( aLvlProps );
// Get the char style
uno::Sequence< beans::PropertyValue > aAbsCharStyleProps = pAbsLevel->GetCharStyleProperties( );
uno::Sequence< beans::PropertyValue >& rAbsCharStyleProps = aAbsCharStyleProps;
if ( pLevel.get( ) )
{
uno::Sequence< beans::PropertyValue > aCharStyleProps =
pLevel->GetCharStyleProperties( );
uno::Sequence< beans::PropertyValue >& rCharStyleProps = aCharStyleProps;
lcl_mergeProperties( rAbsCharStyleProps, rCharStyleProps );
}
if( aAbsCharStyleProps.getLength() )
{
// Change the sequence into a vector
PropertyValueVector_t aStyleProps;
for ( sal_Int32 i = 0, nLen = aAbsCharStyleProps.getLength() ; i < nLen; i++ )
{
aStyleProps.push_back( aAbsCharStyleProps[i] );
}
//create (or find) a character style containing the character
// attributes of the symbol and apply it to the numbering level
OUString sStyle = rDMapper.getOrCreateCharStyle( aStyleProps );
aLvlProps.realloc( aLvlProps.getLength() + 1);
aLvlProps[aLvlProps.getLength() - 1].Name = aPropNameSupplier.GetName( PROP_CHAR_STYLE_NAME );
aLvlProps[aLvlProps.getLength() - 1].Value <<= sStyle;
}
// Get the prefix / suffix / Parent numbering
// and add them to the level properties
OUString sText = pAbsLevel->GetBulletChar( );
if ( pLevel.get( ) )
sText = pLevel->GetBulletChar( );
OUString sPrefix;
OUString sSuffix;
OUString& rPrefix = sPrefix;
OUString& rSuffix = sSuffix;
sal_Int16 nParentNum = ListLevel::GetParentNumbering(
sText, nLevel, rPrefix, rSuffix );
aLvlProps.realloc( aLvlProps.getLength( ) + 4 );
aLvlProps[ aLvlProps.getLength( ) - 4 ] = MAKE_PROPVAL( PROP_PREFIX, rPrefix );
aLvlProps[ aLvlProps.getLength( ) - 3 ] = MAKE_PROPVAL( PROP_SUFFIX, rSuffix );
aLvlProps[ aLvlProps.getLength( ) - 2 ] = MAKE_PROPVAL( PROP_PARENT_NUMBERING, nParentNum );
aLvlProps[ aLvlProps.getLength( ) - 1 ] = MAKE_PROPVAL( PROP_POSITION_AND_SPACE_MODE,
sal_Int16( text::PositionAndSpaceMode::LABEL_ALIGNMENT ) );
// Replace the numbering rules for the level
m_xNumRules->replaceByIndex( nLevel, uno::makeAny( aLvlProps ) );
// Handle the outline level here
StyleSheetEntryPtr pParaStyle = pAbsLevel->GetParaStyle( );
if ( pParaStyle.get( ) )
{
uno::Reference< text::XChapterNumberingSupplier > xOutlines (
xFactory, uno::UNO_QUERY_THROW );
uno::Reference< container::XIndexReplace > xOutlineRules =
xOutlines->getChapterNumberingRules( );
aLvlProps.realloc( aLvlProps.getLength() + 1 );
aLvlProps[aLvlProps.getLength( ) - 1] = MAKE_PROPVAL( PROP_HEADING_STYLE_NAME, pParaStyle->sConvertedStyleName );
xOutlineRules->replaceByIndex( nLevel, uno::makeAny( aLvlProps ) );
}
nLevel++;
}
// Create the numbering style for these rules
OUString sNumRulesName = aPropNameSupplier.GetName( PROP_NUMBERING_RULES );
xStyle->setPropertyValue( sNumRulesName, uno::makeAny( m_xNumRules ) );
}
catch( const uno::Exception& rEx)
{
OSL_ENSURE( false, "ListTable::CreateNumberingRules");
}
}
}
//------------------------------------- NumberingManager implementation
ListsManager::ListsManager(DomainMapper& rDMapper,
const uno::Reference< lang::XMultiServiceFactory > xFactory) :
LoggedProperties(dmapper_logger, "ListsManager"),
LoggedTable(dmapper_logger, "ListsManager"),
m_rDMapper( rDMapper ),
m_xFactory( xFactory )
{
}
ListsManager::~ListsManager( )
{
}
void ListsManager::lcl_attribute( Id nName, Value& rVal )
{
OSL_ENSURE( m_pCurrentDefinition.get(), "current entry has to be set here");
if(!m_pCurrentDefinition.get())
return ;
int nIntValue = rVal.getInt();
ListLevel::Pointer pCurrentLvl = m_pCurrentDefinition->GetCurrentLevel( );
/* WRITERFILTERSTATUS: table: ListTable_attributedata */
switch(nName)
{
/* WRITERFILTERSTATUS: done: 50, planned: 0, spent: 0 */
case NS_rtf::LN_RGBXCHNUMS:
if(pCurrentLvl.get())
pCurrentLvl->AddRGBXchNums( rVal.getString( ) );
break;
/* WRITERFILTERSTATUS: done: 0, planned: 0, spent: 0 */
case NS_ooxml::LN_CT_LevelText_val:
{
//this strings contains the definition of the level
//the level number is marked as %n
//these numbers can be mixed randomly toghether with seperators pre- and suffixes
//the Writer supports only a number of upper levels to show, separators is always a dot
//and each level can have a prefix and a suffix
if(pCurrentLvl.get())
pCurrentLvl->SetBulletChar( rVal.getString() );
}
break;
// case NS_rtf::LN_ISTD: break;
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_ISTARTAT:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_NFC:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_JC:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FLEGAL:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FNORESTART:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FIDENTSAV:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FCONVERTED:
#if 0
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FWORD6:
#endif
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_IXCHFOLLOW:
if ( pCurrentLvl.get( ) )
pCurrentLvl->SetValue( nName, sal_Int32( nIntValue ) );
break;
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_RGISTD:
m_pCurrentDefinition->AddRGISTD( rVal.getString() );
break;
case NS_ooxml::LN_CT_Num_numId:
m_pCurrentDefinition->SetId( rVal.getString().toInt32( ) );
break;
case NS_rtf::LN_LSID:
m_pCurrentDefinition->SetId( nIntValue );
break;
case NS_rtf::LN_TPLC:
case NS_rtf::LN_FSIMPLELIST:
case NS_rtf::LN_fAutoNum:
case NS_rtf::LN_fHybrid:
m_pCurrentDefinition->SetValue( nName, nIntValue );
break;
case NS_ooxml::LN_CT_NumLvl_ilvl:
case NS_rtf::LN_LISTLEVEL:
{
//add a new level to the level vector and make it the current one
m_pCurrentDefinition->AddLevel();
writerfilter::Reference<Properties>::Pointer_t pProperties;
if((pProperties = rVal.getProperties()).get())
pProperties->resolve(*this);
}
break;
/* WRITERFILTERSTATUS: done: 100, planned: 0, spent: 0 */
case NS_ooxml::LN_CT_AbstractNum_abstractNumId:
{
// This one corresponds to the AbstractNum Id definition
// The reference to the abstract num is in the sprm method
sal_Int32 nVal = rVal.getString().toInt32();
m_pCurrentDefinition->SetId( nVal );
}
break;
case NS_ooxml::LN_CT_Ind_left:
/* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */
pCurrentLvl->Insert(
PROP_INDENT_AT, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
break;
case NS_ooxml::LN_CT_Ind_hanging:
/* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */
pCurrentLvl->Insert(
PROP_FIRST_LINE_INDENT, true, uno::makeAny( - ConversionHelper::convertTwipToMM100( nIntValue ) ));
break;
case NS_ooxml::LN_CT_Ind_firstLine:
/* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */
pCurrentLvl->Insert(
PROP_FIRST_LINE_INDENT, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
break;
case NS_ooxml::LN_CT_Lvl_ilvl: //overrides previous level - unsupported
case NS_ooxml::LN_CT_Lvl_tplc: //template code - unsupported
case NS_ooxml::LN_CT_Lvl_tentative: //marks level as unused in the document - unsupported
break;
case NS_ooxml::LN_CT_TabStop_pos:
{
//no paragraph attributes in ListTable char style sheets
if ( pCurrentLvl.get( ) )
pCurrentLvl->SetValue( nName,
ConversionHelper::convertTwipToMM100( nIntValue ) );
}
break;
case NS_ooxml::LN_CT_TabStop_val:
{
// TODO Do something of that
}
break;
default:
{
#if OSL_DEBUG_LEVEL > 0
::rtl::OString sMessage( "ListTable::attribute() - Id: ");
sMessage += ::rtl::OString::valueOf( sal_Int32( nName ), 10 );
sMessage += ::rtl::OString(" / 0x");
sMessage += ::rtl::OString::valueOf( sal_Int32( nName ), 16 );
sMessage += ::rtl::OString(" value: ");
sMessage += ::rtl::OString::valueOf( sal_Int32( nIntValue ), 10 );
sMessage += ::rtl::OString(" / 0x");
sMessage += ::rtl::OString::valueOf( sal_Int32( nIntValue ), 16 );
OSL_ENSURE( false, sMessage.getStr()); //
#endif
}
}
}
void ListsManager::lcl_sprm( Sprm& rSprm )
{
//fill the attributes of the style sheet
sal_uInt32 nSprmId = rSprm.getId();
if( m_pCurrentDefinition.get() ||
nSprmId == NS_ooxml::LN_CT_Numbering_abstractNum ||
nSprmId == NS_ooxml::LN_CT_Numbering_num )
{
sal_Int32 nIntValue = rSprm.getValue()->getInt();
/* WRITERFILTERSTATUS: table: ListTable_sprm */
switch( nSprmId )
{
/* WRITERFILTERSTATUS: done: 100, planned: 0, spent: 0 */
case NS_ooxml::LN_CT_Numbering_abstractNum:
{
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if(pProperties.get())
{
//create a new Abstract list entry
OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
m_pCurrentDefinition.reset( new AbstractListDef );
pProperties->resolve( *this );
//append it to the table
m_aAbstractLists.push_back( m_pCurrentDefinition );
m_pCurrentDefinition = AbstractListDef::Pointer();
}
}
break;
/* WRITERFILTERSTATUS: done: 50, planned: 0, spent: 0 */
case NS_ooxml::LN_CT_Numbering_num:
{
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if(pProperties.get())
{
// Create a new list entry
OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
ListDef::Pointer listDef( new ListDef );
m_pCurrentDefinition = listDef;
pProperties->resolve( *this );
//append it to the table
m_aLists.push_back( listDef );
m_pCurrentDefinition = AbstractListDef::Pointer();
}
}
break;
case NS_ooxml::LN_CT_Num_abstractNumId:
{
sal_Int32 nAbstractNumId = rSprm.getValue()->getInt();
ListDef* pListDef = dynamic_cast< ListDef* >( m_pCurrentDefinition.get( ) );
if ( pListDef != NULL )
{
// The current def should be a ListDef
pListDef->SetAbstractDefinition(
GetAbstractList( nAbstractNumId ) );
}
}
break;
/* WRITERFILTERSTATUS: done: 0, planned: 0, spent: 0 */
case NS_ooxml::LN_CT_AbstractNum_multiLevelType:
break;
/* WRITERFILTERSTATUS: done: 50, planned: 0, spent: 0 */
case NS_rtf::LN_TPLC:
m_pCurrentDefinition->SetValue( nSprmId, nIntValue );
break;
/* WRITERFILTERSTATUS: done: 100, planned: 0, spent: 0 */
case NS_ooxml::LN_CT_AbstractNum_lvl:
{
m_pCurrentDefinition->AddLevel();
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if(pProperties.get())
pProperties->resolve(*this);
}
break;
/* WRITERFILTERSTATUS: done: 0, planned: 0, spent: 0 */
case NS_rtf::LN_RGBXCHNUMS: break;
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_ISTARTAT:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_NFC:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_JC:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FLEGAL:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FNORESTART:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FIDENTSAV:
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FCONVERTED:
#if 0
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_FWORD6:
#endif
/* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
case NS_rtf::LN_IXCHFOLLOW:
m_pCurrentDefinition->GetCurrentLevel( )->SetValue( nSprmId, nIntValue );
break;
case NS_ooxml::LN_CT_Lvl_lvlText:
case NS_ooxml::LN_CT_Lvl_rPr : //contains LN_EG_RPrBase_rFonts
{
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if(pProperties.get())
pProperties->resolve(*this);
}
break;
case NS_ooxml::LN_CT_NumLvl_lvl:
{
// overwrite level
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if(pProperties.get())
pProperties->resolve(*this);
}
break;
case NS_ooxml::LN_CT_Lvl_lvlJc:
{
static sal_Int16 aWWAlignments[ ] =
{
text::HoriOrientation::LEFT,
text::HoriOrientation::CENTER,
text::HoriOrientation::RIGHT
};
m_pCurrentDefinition->GetCurrentLevel( )->Insert(
PROP_ADJUST, true, uno::makeAny( aWWAlignments[ nIntValue ] ) );
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
}
break;
case NS_ooxml::LN_CT_Lvl_pPr:
case NS_ooxml::LN_CT_PPrBase_ind:
{
//todo: how to handle paragraph properties within numbering levels (except LeftIndent and FirstLineIndent)?
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if(pProperties.get())
pProperties->resolve(*this);
}
break;
case NS_ooxml::LN_CT_PPrBase_tabs:
case NS_ooxml::LN_CT_Tabs_tab:
{
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if(pProperties.get())
pProperties->resolve(*this);
}
break;
case NS_ooxml::LN_CT_Lvl_suff:
//todo: currently unsupported suffix
//can be: "none", "space", "tab"
break;
case NS_ooxml::LN_CT_Lvl_pStyle:
{
OUString sStyleName = rSprm.getValue( )->getString( );
ListLevel::Pointer pLevel = m_pCurrentDefinition->GetCurrentLevel( );
StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( );
const StyleSheetEntryPtr pStyle = pStylesTable->FindStyleSheetByISTD( sStyleName );
pLevel->SetParaStyle( pStyle );
}
break;
case NS_ooxml::LN_CT_AbstractNum_numStyleLink:
{
OUString sStyleName = rSprm.getValue( )->getString( );
AbstractListDef* pAbstractListDef = dynamic_cast< AbstractListDef* >( m_pCurrentDefinition.get( ) );
pAbstractListDef->SetNumStyleLink(sStyleName);
}
break;
case NS_ooxml::LN_EG_RPrBase_rFonts: //contains font properties
case NS_ooxml::LN_EG_RPrBase_color:
case NS_ooxml::LN_EG_RPrBase_u:
case NS_sprm::LN_CHps: // sprmCHps
case NS_ooxml::LN_EG_RPrBase_lang:
case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
//no break!
default:
if( m_pCurrentDefinition->GetCurrentLevel( ).get())
{
m_rDMapper.PushListProperties( m_pCurrentDefinition->GetCurrentLevel( ) );
m_rDMapper.sprm( rSprm );
m_rDMapper.PopListProperties();
}
}
}
}
void ListsManager::lcl_entry( int /* pos */,
writerfilter::Reference<Properties>::Pointer_t ref )
{
if( m_rDMapper.IsOOXMLImport() )
{
ref->resolve(*this);
}
else
{
if ( m_bIsLFOImport )
{
// Create ListDef's
OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
ListDef::Pointer pList( new ListDef() );
m_pCurrentDefinition = pList;
ref->resolve(*this);
//append it to the table
m_aLists.push_back( pList );
m_pCurrentDefinition = AbstractListDef::Pointer();
}
else
{
// Create AbstractListDef's
OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
m_pCurrentDefinition.reset( new AbstractListDef( ) );
ref->resolve(*this);
//append it to the table
m_aAbstractLists.push_back( m_pCurrentDefinition );
m_pCurrentDefinition = AbstractListDef::Pointer();
}
}
}
AbstractListDef::Pointer ListsManager::GetAbstractList( sal_Int32 nId )
{
AbstractListDef::Pointer pAbstractList;
int nLen = m_aAbstractLists.size( );
int i = 0;
while ( !pAbstractList.get( ) && i < nLen )
{
if ( m_aAbstractLists[i]->GetId( ) == nId )
{
if ( m_aAbstractLists[i]->GetNumStyleLink().getLength() > 0 )
{
// If the abstract num has a style linked, check the linked style's number id.
StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( );
const StyleSheetEntryPtr pStyleSheetEntry =
pStylesTable->FindStyleSheetByISTD( m_aAbstractLists[i]->GetNumStyleLink() );
const StyleSheetPropertyMap* pStyleSheetProperties =
dynamic_cast<const StyleSheetPropertyMap*>(pStyleSheetEntry ? pStyleSheetEntry->pProperties.get() : 0);
if( pStyleSheetProperties && pStyleSheetProperties->GetNumId() >= 0 )
{
ListDef::Pointer pList = GetList( pStyleSheetProperties->GetNumId() );
if( bool(pList) )
return pList->GetAbstractDefinition();
else
pAbstractList = m_aAbstractLists[i];
}
}
else
{
pAbstractList = m_aAbstractLists[i];
}
}
i++;
}
return pAbstractList;
}
ListDef::Pointer ListsManager::GetList( sal_Int32 nId )
{
ListDef::Pointer pList;
int nLen = m_aLists.size( );
int i = 0;
while ( !pList.get( ) && i < nLen )
{
if ( m_aLists[i]->GetId( ) == nId )
pList = m_aLists[i];
i++;
}
return pList;
}
void ListsManager::CreateNumberingRules( )
{
// Loop over the definitions
std::vector< ListDef::Pointer >::iterator listIt = m_aLists.begin( );
for ( ; listIt != m_aLists.end( ); listIt++ )
{
(*listIt)->CreateNumberingRules( m_rDMapper, m_xFactory );
}
}
} }