merge the formfield patch from ooo-build
[ooovba.git] / writerfilter / source / dmapper / NumberingManager.cxx
blob65788d073ce305ad00b9fc0bf29697bd53dd44a9
1 #include "ConversionHelper.hxx"
2 #include "NumberingManager.hxx"
3 #include "StyleSheetTable.hxx"
4 #include "PropertyIds.hxx"
6 #include <doctok/resourceids.hxx>
7 #include <doctok/sprmids.hxx>
8 #include <ooxml/resourceids.hxx>
10 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
11 #include <com/sun/star/container/XNameContainer.hpp>
12 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
13 #include <com/sun/star/style/NumberingType.hpp>
14 #include <com/sun/star/text/HoriOrientation.hpp>
15 #include <com/sun/star/text/PositionAndSpaceMode.hpp>
16 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
18 using namespace rtl;
19 using namespace com::sun::star;
21 #define MAKE_PROPVAL(NameId, Value) \
22 beans::PropertyValue(aPropNameSupplier.GetName(NameId), 0, uno::makeAny(Value), beans::PropertyState_DIRECT_VALUE )
24 #define OUSTR_TO_C( x ) OUStringToOString( x, RTL_TEXTENCODING_UTF8 ).getStr( )
26 #define NUMBERING_MAX_LEVELS 10
29 namespace writerfilter {
30 namespace dmapper {
32 //--------------------------------------------------- Utility functions
34 void lcl_printProperties( uno::Sequence< beans::PropertyValue > aProps )
36 sal_Int32 nLen = aProps.getLength( );
37 for ( sal_Int32 i = 0; i < nLen; i++ )
39 uno::Any aValue = aProps[i].Value;
40 sal_Int32 nValue;
41 OUString sValue;
43 if ( !( aValue >>= sValue ) && ( aValue >>= nValue ) )
44 sValue = OUString::valueOf( nValue );
46 fprintf( stderr, "Property %s: %s\n",
47 OUSTR_TO_C( aProps[i].Name ),
48 OUSTR_TO_C( sValue ) );
52 sal_Int32 lcl_findProperty( uno::Sequence< beans::PropertyValue > aProps, OUString sName )
54 sal_Int32 i = 0;
55 sal_Int32 nLen = aProps.getLength( );
56 sal_Int32 nPos = -1;
58 while ( nPos == -1 && i < nLen )
60 if ( aProps[i].Name.equals( sName ) )
61 nPos = i;
62 else
63 i++;
66 return nPos;
69 void lcl_mergeProperties( uno::Sequence< beans::PropertyValue >& aSrc,
70 uno::Sequence< beans::PropertyValue >& aDst )
72 for ( sal_Int32 i = 0, nSrcLen = aSrc.getLength( ); i < nSrcLen; i++ )
74 // Look for the same property in aDst
75 sal_Int32 nPos = lcl_findProperty( aDst, aSrc[i].Name );
76 if ( nPos >= 0 )
78 // Replace the property value by the one in aSrc
79 aDst[nPos] = aSrc[i];
81 else
83 // Simply add the new value
84 aDst.realloc( aDst.getLength( ) + 1 );
85 aDst[ aDst.getLength( ) - 1 ] = aSrc[i];
90 //-------------------------------------------- ListLevel implementation
91 void ListLevel::SetValue( Id nId, sal_Int32 nValue )
93 switch( nId )
95 case NS_rtf::LN_ISTARTAT:
96 m_nIStartAt = nValue;
97 break;
98 case NS_rtf::LN_NFC:
99 m_nNFC = nValue;
100 break;
101 case NS_rtf::LN_JC:
102 m_nJC = nValue;
103 break;
104 case NS_rtf::LN_FLEGAL:
105 m_nFLegal = nValue;
106 break;
107 case NS_rtf::LN_FNORESTART:
108 m_nFNoRestart = nValue;
109 break;
110 case NS_rtf::LN_FPREV:
111 m_nFPrev = nValue;
112 break;
113 case NS_rtf::LN_FPREVSPACE:
114 m_nFPrevSpace = nValue;
115 break;
116 case NS_rtf::LN_FWORD6:
117 m_nFWord6 = nValue;
118 break;
119 case NS_rtf::LN_IXCHFOLLOW:
120 m_nXChFollow = nValue;
121 break;
122 case NS_ooxml::LN_CT_TabStop_pos:
123 m_nTabstop = nValue;
124 break;
125 default:
126 OSL_ENSURE( false, "this line should never be reached");
130 sal_Int16 ListLevel::GetParentNumbering( OUString sText, sal_Int16 nLevel,
131 OUString& rPrefix, OUString& rSuffix )
133 sal_Int16 nParentNumbering = nLevel;
135 //now parse the text to find %n from %1 to %nLevel+1
136 //everything before the first % and the last %x is prefix and suffix
137 OUString sLevelText( sText );
138 sal_Int32 nCurrentIndex = 0;
139 sal_Int32 nFound = sLevelText.indexOf( '%', nCurrentIndex );
140 if( nFound > 0 )
142 rPrefix = sLevelText.copy( 0, nFound );
143 sLevelText = sLevelText.copy( nFound );
145 sal_Int32 nMinLevel = nLevel;
146 //now the text should either be empty or start with %
147 nFound = 0;
148 while( nFound >= 0 )
150 if( sLevelText.getLength() > 1 )
152 sal_Unicode cLevel = sLevelText.getStr()[1];
153 if( cLevel >= '1' && cLevel <= '9' )
155 if( cLevel - '1' < nMinLevel )
156 nMinLevel = cLevel - '1';
157 //remove first char - next char is removed later
158 sLevelText = sLevelText.copy( 1 );
161 //remove old '%' or number
162 sLevelText = sLevelText.copy( 1 );
163 nCurrentIndex = 0;
164 nFound = sLevelText.indexOf( '%', nCurrentIndex );
165 //remove the text before the next %
166 if(nFound > 0)
167 sLevelText = sLevelText.copy( nFound -1 );
169 if( nMinLevel < nLevel )
171 nParentNumbering = sal_Int16( nLevel - nMinLevel + 1);
174 rSuffix = sLevelText;
176 return nParentNumbering;
179 uno::Sequence< beans::PropertyValue > ListLevel::GetProperties( )
181 uno::Sequence< beans::PropertyValue > aLevelProps = GetLevelProperties( );
182 if ( m_pParaStyle.get( ) )
184 // Merge with the paragraph properties
185 uno::Sequence< beans::PropertyValue > aParaProps = GetParaProperties( );
186 lcl_mergeProperties( aParaProps, aLevelProps );
188 return aLevelProps;
191 uno::Sequence< beans::PropertyValue > ListLevel::GetCharStyleProperties( )
193 PropertyValueVector_t rProperties;
194 PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
196 _PropertyMap::const_iterator aMapIter = begin();
197 _PropertyMap::const_iterator aEndIter = end();
198 for( ; aMapIter != aEndIter; ++aMapIter )
200 switch( aMapIter->first.eId )
202 case PROP_ADJUST:
203 case PROP_INDENT_AT:
204 case PROP_FIRST_LINE_INDENT:
205 case PROP_FIRST_LINE_OFFSET:
206 case PROP_LEFT_MARGIN:
207 case PROP_CHAR_FONT_NAME:
208 // Do nothing: handled in the GetPropertyValues method
209 break;
210 default:
212 rProperties.push_back(
213 beans::PropertyValue(
214 aPropNameSupplier.GetName( aMapIter->first.eId ), 0,
215 aMapIter->second, beans::PropertyState_DIRECT_VALUE ));
220 uno::Sequence< beans::PropertyValue > aRet( rProperties.size() );
221 beans::PropertyValue* pValues = aRet.getArray();
222 PropertyValueVector_t::const_iterator aIt = rProperties.begin();
223 PropertyValueVector_t::const_iterator aEndIt = rProperties.end();
224 for(sal_uInt32 nIndex = 0; aIt != aEndIt; ++aIt,++nIndex)
226 pValues[nIndex] = *aIt;
228 return aRet;
231 uno::Sequence< beans::PropertyValue > ListLevel::GetLevelProperties( )
233 const sal_Int16 aWWToUnoAdjust[] =
235 text::HoriOrientation::LEFT,
236 text::HoriOrientation::CENTER,
237 text::HoriOrientation::RIGHT,
240 PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
241 PropertyValueVector_t aNumberingProperties;
243 if( m_nIStartAt >= 0)
244 aNumberingProperties.push_back( MAKE_PROPVAL(PROP_START_WITH, (sal_Int16)m_nIStartAt) );
246 sal_Int16 nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC);
247 if( m_nNFC >= 0)
248 aNumberingProperties.push_back( MAKE_PROPVAL(PROP_NUMBERING_TYPE, nNumberFormat ));
250 if( m_nJC >= 0 && m_nJC <= sal::static_int_cast<sal_Int32>(sizeof(aWWToUnoAdjust) / sizeof(sal_Int16)) )
251 aNumberingProperties.push_back( MAKE_PROPVAL(PROP_ADJUST, aWWToUnoAdjust[m_nJC]));
253 // todo: this is not the bullet char
254 if( nNumberFormat == style::NumberingType::CHAR_SPECIAL && m_sBulletChar.getLength() )
255 aNumberingProperties.push_back( MAKE_PROPVAL(PROP_BULLET_CHAR, m_sBulletChar.copy(0,1)));
257 aNumberingProperties.push_back( MAKE_PROPVAL( PROP_LISTTAB_STOP_POSITION, m_nTabstop ) );
259 //TODO: handling of nFLegal?
260 //TODO: nFNoRestart lower levels do not restart when higher levels are incremented, like:
261 //1.
262 //1.1
263 //2.2
264 //2.3
265 //3.4
268 if( m_nFWord6 > 0) //Word 6 compatibility
270 if( m_nFPrev == 1)
271 aNumberingProperties.push_back( MAKE_PROPVAL( PROP_PARENT_NUMBERING, (sal_Int16) NUMBERING_MAX_LEVELS ));
272 //TODO: prefixing space nFPrevSpace; - has not been used in WW8 filter
275 // TODO: sRGBXchNums; array of inherited numbers
277 // TODO: nXChFollow; following character 0 - tab, 1 - space, 2 - nothing
279 _PropertyMap::const_iterator aMapIter = begin();
280 _PropertyMap::const_iterator aEndIter = end();
281 for( ; aMapIter != aEndIter; ++aMapIter )
283 switch( aMapIter->first.eId )
285 case PROP_ADJUST:
286 case PROP_INDENT_AT:
287 case PROP_FIRST_LINE_INDENT:
288 case PROP_FIRST_LINE_OFFSET:
289 case PROP_LEFT_MARGIN:
290 aNumberingProperties.push_back(
291 beans::PropertyValue( aPropNameSupplier.GetName( aMapIter->first.eId ), 0, aMapIter->second, beans::PropertyState_DIRECT_VALUE ));
292 break;
293 case PROP_CHAR_FONT_NAME:
294 aNumberingProperties.push_back(
295 beans::PropertyValue( aPropNameSupplier.GetName( PROP_BULLET_FONT_NAME ), 0, aMapIter->second, beans::PropertyState_DIRECT_VALUE ));
296 break;
297 default:
299 // Handled in GetCharStyleProperties method
305 uno::Sequence< beans::PropertyValue > aRet(aNumberingProperties.size());
306 beans::PropertyValue* pValues = aRet.getArray();
307 PropertyValueVector_t::const_iterator aIt = aNumberingProperties.begin();
308 PropertyValueVector_t::const_iterator aEndIt = aNumberingProperties.end();
309 for(sal_uInt32 nIndex = 0; aIt != aEndIt; ++aIt,++nIndex)
311 pValues[nIndex] = *aIt;
313 return aRet;
316 uno::Sequence< beans::PropertyValue > ListLevel::GetParaProperties( )
318 PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
320 uno::Sequence< beans::PropertyValue > aParaProps = m_pParaStyle->pProperties->GetPropertyValues( );
321 uno::Sequence< beans::PropertyValue > aProps;
323 // ParaFirstLineIndent -> FirstLineIndent
324 // ParaLeftMargin -> IndentAt
326 OUString sParaIndent = aPropNameSupplier.GetName(
327 PROP_PARA_FIRST_LINE_INDENT );
328 OUString sFirstLineIndent = aPropNameSupplier.GetName(
329 PROP_FIRST_LINE_INDENT );
330 OUString sParaLeftMargin = aPropNameSupplier.GetName(
331 PROP_PARA_LEFT_MARGIN );
332 OUString sIndentAt = aPropNameSupplier.GetName(
333 PROP_INDENT_AT );
335 sal_Int32 nLen = aParaProps.getLength( );
336 for ( sal_Int32 i = 0; i < nLen; i++ )
338 if ( aParaProps[i].Name.equals( sParaIndent ) )
340 aProps.realloc( aProps.getLength() + 1 );
341 aProps[aProps.getLength( ) - 1] = aParaProps[i];
342 aProps[aProps.getLength( ) - 1].Name = sFirstLineIndent;
344 else if ( aParaProps[i].Name.equals( sParaLeftMargin ) )
346 aProps.realloc( aProps.getLength() + 1 );
347 aProps[aProps.getLength( ) - 1] = aParaProps[i];
348 aProps[aProps.getLength( ) - 1].Name = sIndentAt;
353 return aProps;
356 //--------------------------------------- AbstractListDef implementation
358 AbstractListDef::AbstractListDef( ) :
359 m_nTPLC( -1 )
360 ,m_nSimpleList( -1 )
361 ,m_nRestart( -1 )
362 ,m_nUnsigned( -1 )
363 ,m_nId( -1 )
367 AbstractListDef::~AbstractListDef( )
371 void AbstractListDef::SetValue( sal_uInt32 nSprmId, sal_Int32 nValue )
373 switch( nSprmId )
375 case NS_rtf::LN_TPLC:
376 m_nTPLC = nValue;
377 break;
378 case NS_rtf::LN_FSIMPLELIST:
379 m_nSimpleList = nValue;
380 break;
381 case NS_rtf::LN_FRESTARTHDN:
382 m_nRestart = nValue;
383 break;
384 case NS_rtf::LN_UNSIGNED26_2:
385 m_nUnsigned = nValue;
386 break;
387 default:
388 OSL_ENSURE( false, "this line should never be reached");
392 ListLevel::Pointer AbstractListDef::GetLevel( sal_uInt16 nLvl )
394 ListLevel::Pointer pLevel;
395 if ( m_aLevels.size( ) > nLvl )
396 pLevel = m_aLevels[ nLvl ];
397 return pLevel;
400 void AbstractListDef::AddLevel( )
402 ListLevel::Pointer pLevel( new ListLevel );
403 m_pCurrentLevel = pLevel;
404 m_aLevels.push_back( pLevel );
407 uno::Sequence< uno::Sequence< beans::PropertyValue > > AbstractListDef::GetPropertyValues( )
409 uno::Sequence< uno::Sequence< beans::PropertyValue > > result( sal_Int32( m_aLevels.size( ) ) );
410 uno::Sequence< beans::PropertyValue >* aResult = result.getArray( );
412 int nLevels = m_aLevels.size( );
413 for ( int i = 0; i < nLevels; i++ )
415 aResult[i] = m_aLevels[i]->GetProperties( );
418 return result;
421 //---------------------------------------------- ListDef implementation
423 ListDef::ListDef( ) : AbstractListDef( )
427 ListDef::~ListDef( )
431 OUString ListDef::GetStyleName( sal_Int32 nId )
433 OUString sStyleName( OUString::createFromAscii( "WWNum" ) );
434 sStyleName += OUString::valueOf( nId );
436 return sStyleName;
439 uno::Sequence< uno::Sequence< beans::PropertyValue > > ListDef::GetPropertyValues( )
441 // [1] Call the same method on the abstract list
442 uno::Sequence< uno::Sequence< beans::PropertyValue > > aAbstract = m_pAbstractDef->GetPropertyValues( );
444 // [2] Call the upper class method
445 uno::Sequence< uno::Sequence< beans::PropertyValue > > aThis = AbstractListDef::GetPropertyValues( );
447 // Merge the results of [2] in [1]
448 sal_Int32 nThisCount = aThis.getLength( );
449 for ( sal_Int32 i = 0; i < nThisCount; i++ )
451 uno::Sequence< beans::PropertyValue > level = aThis[i];
452 if ( level.getLength( ) == 0 )
454 // If the the element contains something, merge it
455 lcl_mergeProperties( level, aAbstract[i] );
459 return aAbstract;
462 uno::Reference< container::XNameContainer > lcl_getUnoNumberingStyles(
463 uno::Reference< lang::XMultiServiceFactory > xFactory )
465 uno::Reference< container::XNameContainer > xStyles;
469 uno::Reference< style::XStyleFamiliesSupplier > xFamilies( xFactory, uno::UNO_QUERY_THROW );
470 uno::Any oFamily = xFamilies->getStyleFamilies( )->getByName( OUString::createFromAscii( "NumberingStyles" ) );
472 oFamily >>= xStyles;
474 catch ( const uno::Exception )
478 return xStyles;
481 void ListDef::CreateNumberingRules( DomainMapper& rDMapper,
482 uno::Reference< lang::XMultiServiceFactory> xFactory )
484 // Get the UNO Numbering styles
485 uno::Reference< container::XNameContainer > xStyles = lcl_getUnoNumberingStyles( xFactory );
487 // Do the whole thing
488 if( !m_xNumRules.is() && xFactory.is() && xStyles.is( ) )
492 // Create the numbering style
493 uno::Reference< beans::XPropertySet > xStyle (
494 xFactory->createInstance(
495 OUString::createFromAscii("com.sun.star.style.NumberingStyle")),
496 uno::UNO_QUERY_THROW );
498 rtl::OUString sStyleName = GetStyleName( GetId( ) );
499 #if DEBUG
500 fprintf( stderr, "Creating numbering style: %s\n", OUSTR_TO_C( sStyleName ) );
501 #endif
503 xStyles->insertByName( sStyleName, makeAny( xStyle ) );
505 uno::Any oStyle = xStyles->getByName( sStyleName );
506 xStyle.set( oStyle, uno::UNO_QUERY_THROW );
508 PropertyNameSupplier& aPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
510 // Get the default OOo Numbering style rules
511 uno::Any aRules = xStyle->getPropertyValue( aPropNameSupplier.GetName( PROP_NUMBERING_RULES ) );
512 aRules >>= m_xNumRules;
514 uno::Sequence< uno::Sequence< beans::PropertyValue > > aProps = GetPropertyValues( );
516 sal_Int32 nAbstLevels = m_pAbstractDef->Size( );
517 sal_Int16 nLevel = 0;
518 while ( nLevel < nAbstLevels )
520 ListLevel::Pointer pAbsLevel = m_pAbstractDef->GetLevel( nLevel );
521 ListLevel::Pointer pLevel = GetLevel( nLevel );
523 // Get the merged level properties
524 uno::Sequence< beans::PropertyValue > aLvlProps = aProps[sal_Int32( nLevel )];
526 // Get the char style
527 uno::Sequence< beans::PropertyValue > aAbsCharStyleProps = pAbsLevel->GetCharStyleProperties( );
528 uno::Sequence< beans::PropertyValue >& rAbsCharStyleProps = aAbsCharStyleProps;
529 if ( pLevel.get( ) )
531 uno::Sequence< beans::PropertyValue > aCharStyleProps =
532 pLevel->GetCharStyleProperties( );
533 uno::Sequence< beans::PropertyValue >& rCharStyleProps = aCharStyleProps;
534 lcl_mergeProperties( rAbsCharStyleProps, rCharStyleProps );
537 if( aAbsCharStyleProps.getLength() )
539 // Change the sequence into a vector
540 PropertyValueVector_t aStyleProps;
541 for ( sal_Int32 i = 0, nLen = aAbsCharStyleProps.getLength() ; i < nLen; i++ )
543 aStyleProps.push_back( aAbsCharStyleProps[i] );
546 //create (or find) a character style containing the character
547 // attributes of the symbol and apply it to the numbering level
548 OUString sStyle = rDMapper.getOrCreateCharStyle( aStyleProps );
549 aLvlProps.realloc( aLvlProps.getLength() + 1);
550 aLvlProps[aLvlProps.getLength() - 1].Name = aPropNameSupplier.GetName( PROP_CHAR_STYLE_NAME );
551 aLvlProps[aLvlProps.getLength() - 1].Value <<= sStyle;
554 // Get the prefix / suffix / Parent numbering
555 // and add them to the level properties
556 OUString sText = pAbsLevel->GetBulletChar( );
557 if ( pLevel.get( ) )
558 sText = pLevel->GetBulletChar( );
560 OUString sPrefix;
561 OUString sSuffix;
562 OUString& rPrefix = sPrefix;
563 OUString& rSuffix = sSuffix;
564 sal_Int16 nParentNum = ListLevel::GetParentNumbering(
565 sText, nLevel, rPrefix, rSuffix );
567 aLvlProps.realloc( aLvlProps.getLength( ) + 4 );
568 aLvlProps[ aLvlProps.getLength( ) - 4 ] = MAKE_PROPVAL( PROP_PREFIX, rPrefix );
569 aLvlProps[ aLvlProps.getLength( ) - 3 ] = MAKE_PROPVAL( PROP_SUFFIX, rSuffix );
570 aLvlProps[ aLvlProps.getLength( ) - 2 ] = MAKE_PROPVAL( PROP_PARENT_NUMBERING, nParentNum );
572 aLvlProps[ aLvlProps.getLength( ) - 1 ] = MAKE_PROPVAL( PROP_POSITION_AND_SPACE_MODE,
573 sal_Int16( text::PositionAndSpaceMode::LABEL_ALIGNMENT ) );
574 // Replace the numbering rules for the level
575 m_xNumRules->replaceByIndex( nLevel, uno::makeAny( aLvlProps ) );
577 // Handle the outline level here
578 StyleSheetEntryPtr pParaStyle = pAbsLevel->GetParaStyle( );
579 if ( pParaStyle.get( ) )
581 uno::Reference< text::XChapterNumberingSupplier > xOutlines (
582 xFactory, uno::UNO_QUERY_THROW );
583 uno::Reference< container::XIndexReplace > xOutlineRules =
584 xOutlines->getChapterNumberingRules( );
586 aLvlProps.realloc( aLvlProps.getLength() + 1 );
587 aLvlProps[aLvlProps.getLength( ) - 1] = MAKE_PROPVAL( PROP_HEADING_STYLE_NAME, pParaStyle->sConvertedStyleName );
589 xOutlineRules->replaceByIndex( nLevel, uno::makeAny( aLvlProps ) );
592 nLevel++;
595 // Create the numbering style for these rules
596 OUString sNumRulesName = aPropNameSupplier.GetName( PROP_NUMBERING_RULES );
597 xStyle->setPropertyValue( sNumRulesName, uno::makeAny( m_xNumRules ) );
599 catch( const uno::Exception& rEx)
601 OSL_ENSURE( false, "ListTable::CreateNumberingRules");
607 //------------------------------------- NumberingManager implementation
610 ListsManager::ListsManager( DomainMapper& rDMapper,
611 const uno::Reference< lang::XMultiServiceFactory > xFactory ) :
612 m_rDMapper( rDMapper ),
613 m_xFactory( xFactory )
617 ListsManager::~ListsManager( )
621 void ListsManager::attribute( Id nName, Value& rVal )
623 OSL_ENSURE( m_pCurrentDefinition.get(), "current entry has to be set here");
624 if(!m_pCurrentDefinition.get())
625 return ;
626 int nIntValue = rVal.getInt();
628 ListLevel::Pointer pCurrentLvl = m_pCurrentDefinition->GetCurrentLevel( );
631 /* WRITERFILTERSTATUS: table: ListTable_attributedata */
632 switch(nName)
634 /* WRITERFILTERSTATUS: done: 50, planned: 0, spent: 0 */
635 case NS_rtf::LN_RGBXCHNUMS:
636 if(pCurrentLvl.get())
637 pCurrentLvl->AddRGBXchNums( rVal.getString( ) );
638 break;
639 /* WRITERFILTERSTATUS: done: 0, planned: 0, spent: 0 */
640 case NS_ooxml::LN_CT_LevelText_val:
642 //this strings contains the definition of the level
643 //the level number is marked as %n
644 //these numbers can be mixed randomly toghether with seperators pre- and suffixes
645 //the Writer supports only a number of upper levels to show, separators is always a dot
646 //and each level can have a prefix and a suffix
647 if(pCurrentLvl.get())
648 pCurrentLvl->SetBulletChar( rVal.getString() );
650 break;
651 // case NS_rtf::LN_ISTD: break;
652 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
653 case NS_rtf::LN_ISTARTAT:
654 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
655 case NS_rtf::LN_NFC:
656 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
657 case NS_rtf::LN_JC:
658 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
659 case NS_rtf::LN_FLEGAL:
660 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
661 case NS_rtf::LN_FNORESTART:
662 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
663 case NS_rtf::LN_FPREV:
664 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
665 case NS_rtf::LN_FPREVSPACE:
666 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
667 case NS_rtf::LN_FWORD6:
668 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
669 case NS_rtf::LN_IXCHFOLLOW:
670 if ( pCurrentLvl.get( ) )
671 pCurrentLvl->SetValue( nName, sal_Int32( nIntValue ) );
672 break;
673 /* WRITERFILTERSTATUS: done: 100, planned: 0, spent: 0 */
674 case NS_rtf::LN_UNUSED5_7:
675 //unused
676 break;
677 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
678 case NS_rtf::LN_RGISTD:
679 m_pCurrentDefinition->AddRGISTD( rVal.getString() );
680 break;
681 case NS_ooxml::LN_CT_Num_numId:
682 m_pCurrentDefinition->SetId( rVal.getString().toInt32( ) );
683 break;
684 case NS_rtf::LN_LSID:
685 m_pCurrentDefinition->SetId( nIntValue );
686 break;
687 case NS_rtf::LN_TPLC:
688 case NS_rtf::LN_FSIMPLELIST:
689 case NS_rtf::LN_FRESTARTHDN:
690 case NS_rtf::LN_UNSIGNED26_2:
691 m_pCurrentDefinition->SetValue( nName, nIntValue );
692 break;
693 case NS_ooxml::LN_CT_NumLvl_ilvl:
694 case NS_rtf::LN_LISTLEVEL:
696 //add a new level to the level vector and make it the current one
697 m_pCurrentDefinition->AddLevel();
699 writerfilter::Reference<Properties>::Pointer_t pProperties;
700 if((pProperties = rVal.getProperties()).get())
701 pProperties->resolve(*this);
703 break;
704 /* WRITERFILTERSTATUS: done: 100, planned: 0, spent: 0 */
705 case NS_ooxml::LN_CT_AbstractNum_abstractNumId:
707 // This one corresponds to the AbstractNum Id definition
708 // The reference to the abstract num is in the sprm method
709 sal_Int32 nVal = rVal.getString().toInt32();
710 m_pCurrentDefinition->SetId( nVal );
712 break;
713 case NS_ooxml::LN_CT_Ind_left:
714 /* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */
715 pCurrentLvl->Insert(
716 PROP_INDENT_AT, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
717 break;
718 case NS_ooxml::LN_CT_Ind_hanging:
719 /* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */
720 pCurrentLvl->Insert(
721 PROP_FIRST_LINE_INDENT, true, uno::makeAny( - ConversionHelper::convertTwipToMM100( nIntValue ) ));
722 break;
723 case NS_ooxml::LN_CT_Ind_firstLine:
724 /* WRITERFILTERSTATUS: done: 100, planned: 0.5, spent: 0 */
725 pCurrentLvl->Insert(
726 PROP_FIRST_LINE_INDENT, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
727 break;
728 case NS_ooxml::LN_CT_Lvl_ilvl: //overrides previous level - unsupported
729 case NS_ooxml::LN_CT_Lvl_tplc: //template code - unsupported
730 case NS_ooxml::LN_CT_Lvl_tentative: //marks level as unused in the document - unsupported
731 break;
732 case NS_ooxml::LN_CT_TabStop_pos:
734 //no paragraph attributes in ListTable char style sheets
735 if ( pCurrentLvl.get( ) )
736 pCurrentLvl->SetValue( nName,
737 ConversionHelper::convertTwipToMM100( nIntValue ) );
739 break;
740 case NS_ooxml::LN_CT_TabStop_val:
742 // TODO Do something of that
744 break;
745 default:
747 #if OSL_DEBUG_LEVEL > 0
748 ::rtl::OString sMessage( "ListTable::attribute() - Id: ");
749 sMessage += ::rtl::OString::valueOf( sal_Int32( nName ), 10 );
750 sMessage += ::rtl::OString(" / 0x");
751 sMessage += ::rtl::OString::valueOf( sal_Int32( nName ), 16 );
752 sMessage += ::rtl::OString(" value: ");
753 sMessage += ::rtl::OString::valueOf( sal_Int32( nIntValue ), 10 );
754 sMessage += ::rtl::OString(" / 0x");
755 sMessage += ::rtl::OString::valueOf( sal_Int32( nIntValue ), 16 );
756 OSL_ENSURE( false, sMessage.getStr()); //
757 #endif
762 void ListsManager::sprm( Sprm& rSprm )
764 //fill the attributes of the style sheet
765 sal_uInt32 nSprmId = rSprm.getId();
766 if( m_pCurrentDefinition.get() ||
767 nSprmId == NS_ooxml::LN_CT_Numbering_abstractNum ||
768 nSprmId == NS_ooxml::LN_CT_Numbering_num )
770 sal_Int32 nIntValue = rSprm.getValue()->getInt();
771 /* WRITERFILTERSTATUS: table: ListTable_sprm */
772 switch( nSprmId )
774 /* WRITERFILTERSTATUS: done: 100, planned: 0, spent: 0 */
775 case NS_ooxml::LN_CT_Numbering_abstractNum:
777 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
778 if(pProperties.get())
780 //create a new Abstract list entry
781 OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
782 m_pCurrentDefinition.reset( new AbstractListDef );
783 pProperties->resolve( *this );
784 //append it to the table
785 m_aAbstractLists.push_back( m_pCurrentDefinition );
786 m_pCurrentDefinition = AbstractListDef::Pointer();
789 break;
790 /* WRITERFILTERSTATUS: done: 50, planned: 0, spent: 0 */
791 case NS_ooxml::LN_CT_Numbering_num:
793 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
794 if(pProperties.get())
796 // Create a new list entry
797 OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
798 ListDef::Pointer listDef( new ListDef );
799 m_pCurrentDefinition = listDef;
800 pProperties->resolve( *this );
801 //append it to the table
802 m_aLists.push_back( listDef );
804 m_pCurrentDefinition = AbstractListDef::Pointer();
807 break;
808 case NS_ooxml::LN_CT_Num_abstractNumId:
810 sal_Int32 nAbstractNumId = rSprm.getValue()->getInt();
811 ListDef* pListDef = dynamic_cast< ListDef* >( m_pCurrentDefinition.get( ) );
812 if ( pListDef != NULL )
814 // The current def should be a ListDef
815 pListDef->SetAbstractDefinition(
816 m_aAbstractLists[ nAbstractNumId ] );
819 break;
820 /* WRITERFILTERSTATUS: done: 0, planned: 0, spent: 0 */
821 case NS_ooxml::LN_CT_AbstractNum_multiLevelType:
822 break;
823 /* WRITERFILTERSTATUS: done: 50, planned: 0, spent: 0 */
824 case NS_rtf::LN_TPLC:
825 m_pCurrentDefinition->SetValue( nSprmId, nIntValue );
826 break;
827 /* WRITERFILTERSTATUS: done: 100, planned: 0, spent: 0 */
828 case NS_ooxml::LN_CT_AbstractNum_lvl:
830 m_pCurrentDefinition->AddLevel();
831 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
832 if(pProperties.get())
833 pProperties->resolve(*this);
835 break;
836 /* WRITERFILTERSTATUS: done: 0, planned: 0, spent: 0 */
837 case NS_rtf::LN_RGBXCHNUMS: break;
838 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
839 case NS_rtf::LN_ISTARTAT:
840 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
841 case NS_rtf::LN_NFC:
842 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
843 case NS_rtf::LN_JC:
844 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
845 case NS_rtf::LN_FLEGAL:
846 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
847 case NS_rtf::LN_FNORESTART:
848 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
849 case NS_rtf::LN_FPREV:
850 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
851 case NS_rtf::LN_FPREVSPACE:
852 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
853 case NS_rtf::LN_FWORD6:
854 /* WRITERFILTERSTATUS: done: 75, planned: 0, spent: 0 */
855 case NS_rtf::LN_IXCHFOLLOW:
856 m_pCurrentDefinition->GetCurrentLevel( )->SetValue( nSprmId, nIntValue );
857 break;
858 case NS_ooxml::LN_CT_Lvl_lvlText:
859 case NS_ooxml::LN_CT_Lvl_rPr : //contains LN_EG_RPrBase_rFonts
861 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
862 if(pProperties.get())
863 pProperties->resolve(*this);
865 break;
866 case NS_ooxml::LN_CT_NumLvl_lvl:
868 // overwrite level
869 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
870 if(pProperties.get())
871 pProperties->resolve(*this);
873 break;
874 case NS_ooxml::LN_CT_Lvl_lvlJc:
876 static sal_Int16 aWWAlignments[ ] =
878 text::HoriOrientation::LEFT,
879 text::HoriOrientation::CENTER,
880 text::HoriOrientation::RIGHT
882 m_pCurrentDefinition->GetCurrentLevel( )->Insert(
883 PROP_ADJUST, true, uno::makeAny( aWWAlignments[ nIntValue ] ) );
884 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
886 break;
887 case NS_ooxml::LN_CT_Lvl_pPr:
888 case NS_ooxml::LN_CT_PPrBase_ind:
890 //todo: how to handle paragraph properties within numbering levels (except LeftIndent and FirstLineIndent)?
891 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
892 if(pProperties.get())
893 pProperties->resolve(*this);
895 break;
896 case NS_ooxml::LN_CT_PPrBase_tabs:
897 case NS_ooxml::LN_CT_Tabs_tab:
899 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
900 if(pProperties.get())
901 pProperties->resolve(*this);
903 break;
904 case NS_ooxml::LN_CT_Lvl_suff:
905 //todo: currently unsupported suffix
906 //can be: "none", "space", "tab"
907 break;
908 case NS_ooxml::LN_CT_Lvl_pStyle:
910 OUString sStyleName = rSprm.getValue( )->getString( );
911 ListLevel::Pointer pLevel = m_pCurrentDefinition->GetCurrentLevel( );
912 StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( );
913 const StyleSheetEntryPtr pStyle = pStylesTable->FindStyleSheetByISTD( sStyleName );
914 pLevel->SetParaStyle( pStyle );
916 break;
917 case NS_ooxml::LN_EG_RPrBase_rFonts: //contains font properties
918 case NS_ooxml::LN_EG_RPrBase_color:
919 case NS_ooxml::LN_EG_RPrBase_u:
920 case NS_sprm::LN_CHps: // sprmCHps
921 case NS_ooxml::LN_EG_RPrBase_lang:
922 case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
923 //no break!
924 default:
925 if( m_pCurrentDefinition->GetCurrentLevel( ).get())
927 m_rDMapper.PushListProperties( m_pCurrentDefinition->GetCurrentLevel( ) );
928 m_rDMapper.sprm( rSprm );
929 m_rDMapper.PopListProperties();
935 void ListsManager::entry( int /* pos */,
936 writerfilter::Reference<Properties>::Pointer_t ref )
938 if( m_rDMapper.IsOOXMLImport() )
940 ref->resolve(*this);
942 else
944 if ( m_bIsLFOImport )
946 // Create ListDef's
947 OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
948 ListDef::Pointer pList( new ListDef() );
949 m_pCurrentDefinition = pList;
950 ref->resolve(*this);
951 //append it to the table
952 m_aLists.push_back( pList );
953 m_pCurrentDefinition = AbstractListDef::Pointer();
955 else
957 // Create AbstractListDef's
958 OSL_ENSURE( !m_pCurrentDefinition.get(), "current entry has to be NULL here");
959 m_pCurrentDefinition.reset( new AbstractListDef( ) );
960 ref->resolve(*this);
961 //append it to the table
962 m_aAbstractLists.push_back( m_pCurrentDefinition );
963 m_pCurrentDefinition = AbstractListDef::Pointer();
969 ListDef::Pointer ListsManager::GetList( sal_Int32 nId )
971 ListDef::Pointer pList;
973 int nLen = m_aLists.size( );
974 int i = 0;
975 while ( !pList.get( ) && i < nLen )
977 if ( m_aLists[i]->GetId( ) == nId )
978 pList = m_aLists[i];
979 i++;
982 return pList;
985 void ListsManager::CreateNumberingRules( )
987 // Loop over the definitions
988 std::vector< ListDef::Pointer >::iterator listIt = m_aLists.begin( );
989 for ( ; listIt != m_aLists.end( ); listIt++ )
991 (*listIt)->CreateNumberingRules( m_rDMapper, m_xFactory );