update emoji autocorrect entries from po-files
[LibreOffice.git] / writerfilter / source / dmapper / StyleSheetTable.cxx
blobe95e755e4f57d833d1bef11fa2f8a28b8a0b8360
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <StyleSheetTable.hxx>
20 #include "util.hxx"
21 #include <NumberingManager.hxx>
22 #include <ConversionHelper.hxx>
23 #include <TblStylePrHandler.hxx>
24 #include <BorderHandler.hxx>
25 #include <LatentStyleHandler.hxx>
26 #include <ooxml/resourceids.hxx>
27 #include <vector>
28 #include <com/sun/star/beans/XMultiPropertySet.hpp>
29 #include <com/sun/star/beans/XPropertyState.hpp>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/container/XNameContainer.hpp>
32 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
33 #include <com/sun/star/text/XTextDocument.hpp>
34 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
35 #include <com/sun/star/style/XStyle.hpp>
36 #include <com/sun/star/style/ParagraphAdjust.hpp>
37 #include <com/sun/star/text/WritingMode.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <map>
40 #include <set>
41 #include <stdio.h>
42 #include <osl/diagnose.h>
43 #include <rtl/ustrbuf.hxx>
44 #include <comphelper/string.hxx>
45 #include <comphelper/sequence.hxx>
47 using namespace ::com::sun::star;
49 namespace writerfilter {
50 namespace dmapper
53 typedef ::std::map< OUString, OUString> StringPairMap_t;
57 StyleSheetEntry::StyleSheetEntry() :
58 sStyleIdentifierI()
59 ,sStyleIdentifierD()
60 ,bIsDefaultStyle(false)
61 ,bInvalidHeight(false)
62 ,bHasUPE(false)
63 ,nStyleTypeCode(STYLE_TYPE_UNKNOWN)
64 ,sBaseStyleIdentifier()
65 ,sNextStyleIdentifier()
66 ,pProperties(new StyleSheetPropertyMap)
67 ,bAutoRedefine(false)
71 StyleSheetEntry::~StyleSheetEntry()
75 TableStyleSheetEntry::TableStyleSheetEntry( StyleSheetEntry& rEntry, StyleSheetTable* pStyles ):
76 StyleSheetEntry( ),
77 m_pStyleSheet( pStyles )
80 bIsDefaultStyle = rEntry.bIsDefaultStyle;
81 bInvalidHeight = rEntry.bInvalidHeight;
82 bHasUPE = rEntry.bHasUPE;
83 nStyleTypeCode = STYLE_TYPE_TABLE;
84 sBaseStyleIdentifier = rEntry.sBaseStyleIdentifier;
85 sNextStyleIdentifier = rEntry.sNextStyleIdentifier;
86 sStyleName = rEntry.sStyleName;
87 sStyleName1 = rEntry.sStyleName1;
88 sStyleIdentifierI = rEntry.sStyleIdentifierI;
89 sStyleIdentifierD = rEntry.sStyleIdentifierD;
91 m_nColBandSize = 1;
92 m_nRowBandSize = 1;
95 TableStyleSheetEntry::~TableStyleSheetEntry( )
97 m_pStyleSheet = nullptr;
100 void TableStyleSheetEntry::AddTblStylePr( TblStyleType nType, PropertyMapPtr pProps )
102 static const int nTypesProps = 4;
103 static const TblStyleType pTypesToFix[nTypesProps] =
105 TBL_STYLE_FIRSTROW,
106 TBL_STYLE_LASTROW,
107 TBL_STYLE_FIRSTCOL,
108 TBL_STYLE_LASTCOL
111 static const PropertyIds pPropsToCheck[nTypesProps] =
113 PROP_BOTTOM_BORDER,
114 PROP_TOP_BORDER,
115 PROP_RIGHT_BORDER,
116 PROP_LEFT_BORDER
119 for (int i=0; i < nTypesProps; ++i )
121 if ( nType == pTypesToFix[i] )
123 PropertyIds nChecked = pPropsToCheck[i];
124 boost::optional<PropertyMap::Property> pChecked = pProps->getProperty(nChecked);
126 PropertyIds nInsideProp = ( i < 2 ) ? META_PROP_HORIZONTAL_BORDER : META_PROP_VERTICAL_BORDER;
127 boost::optional<PropertyMap::Property> pInside = pProps->getProperty(nInsideProp);
129 if ( pChecked && pProps )
131 // In this case, remove the inside border
132 pProps->Erase( nInsideProp );
135 break;
139 // Append the tblStylePr
140 m_aStyles[nType] = pProps;
143 PropertyMapPtr TableStyleSheetEntry::GetProperties( sal_Int32 nMask, StyleSheetEntryDequePtr pStack )
145 PropertyMapPtr pProps( new PropertyMap );
147 // First get the parent properties
148 StyleSheetEntryPtr pEntry = m_pStyleSheet->FindParentStyleSheet( sBaseStyleIdentifier );
150 if ( pEntry.get( ) )
152 if (pStack.get() == nullptr)
153 pStack.reset(new StyleSheetEntryDeque());
155 StyleSheetEntryDeque::const_iterator aIt = find(pStack->begin(), pStack->end(), pEntry);
157 if (aIt != pStack->end())
159 pStack->push_back(pEntry);
161 TableStyleSheetEntry* pParent = static_cast<TableStyleSheetEntry *>( pEntry.get( ) );
162 pProps->InsertProps(pParent->GetProperties(nMask));
164 pStack->pop_back();
168 // And finally get the mask ones
169 pProps->InsertProps(GetLocalPropertiesFromMask(nMask));
171 return pProps;
174 beans::PropertyValues StyleSheetEntry::GetInteropGrabBagSeq()
176 uno::Sequence<beans::PropertyValue> aSeq(m_aInteropGrabBag.size());
177 beans::PropertyValue* pSeq = aSeq.getArray();
178 for (std::vector<beans::PropertyValue>::iterator i = m_aInteropGrabBag.begin(); i != m_aInteropGrabBag.end(); ++i)
179 *pSeq++ = *i;
181 return aSeq;
184 beans::PropertyValue StyleSheetEntry::GetInteropGrabBag()
186 beans::PropertyValue aRet;
187 aRet.Name = sStyleIdentifierI;
189 beans::PropertyValues aSeq = GetInteropGrabBagSeq();;
190 aRet.Value = uno::makeAny(aSeq);
191 return aRet;
194 void StyleSheetEntry::AppendInteropGrabBag(const beans::PropertyValue& rValue)
196 m_aInteropGrabBag.push_back(rValue);
199 void lcl_mergeProps( PropertyMapPtr pToFill, PropertyMapPtr pToAdd, TblStyleType nStyleId )
201 static const PropertyIds pPropsToCheck[] =
203 PROP_BOTTOM_BORDER,
204 PROP_TOP_BORDER,
205 PROP_RIGHT_BORDER,
206 PROP_LEFT_BORDER,
209 bool pRemoveInside[] =
211 ( nStyleId == TBL_STYLE_FIRSTROW ),
212 ( nStyleId == TBL_STYLE_LASTROW ),
213 ( nStyleId == TBL_STYLE_LASTCOL ),
214 ( nStyleId == TBL_STYLE_FIRSTCOL )
217 for ( unsigned i = 0 ; i != sizeof(pPropsToCheck) / sizeof(PropertyIds); i++ )
219 PropertyIds nId = pPropsToCheck[i];
220 boost::optional<PropertyMap::Property> pProp = pToAdd->getProperty(nId);
222 if ( pProp )
224 if ( pRemoveInside[i] )
226 // Remove the insideH and insideV depending on the cell pos
227 PropertyIds nInsideProp = ( i < 2 ) ? META_PROP_HORIZONTAL_BORDER : META_PROP_VERTICAL_BORDER;
228 pToFill->Erase(nInsideProp);
233 pToFill->InsertProps(pToAdd);
236 PropertyMapPtr TableStyleSheetEntry::GetLocalPropertiesFromMask( sal_Int32 nMask )
238 // Order from right to left
239 struct TblStyleTypeAndMask {
240 sal_Int32 mask;
241 TblStyleType type;
244 static const TblStyleTypeAndMask aOrderedStyleTable[] =
246 { 0x010, TBL_STYLE_BAND2HORZ },
247 { 0x020, TBL_STYLE_BAND1HORZ },
248 { 0x040, TBL_STYLE_BAND2VERT },
249 { 0x080, TBL_STYLE_BAND1VERT },
250 { 0x100, TBL_STYLE_LASTCOL },
251 { 0x200, TBL_STYLE_FIRSTCOL },
252 { 0x400, TBL_STYLE_LASTROW },
253 { 0x800, TBL_STYLE_FIRSTROW },
254 { 0x001, TBL_STYLE_SWCELL },
255 { 0x002, TBL_STYLE_SECELL },
256 { 0x004, TBL_STYLE_NWCELL },
257 { 0x008, TBL_STYLE_NECELL }
260 // Get the properties applying according to the mask
261 PropertyMapPtr pProps( new PropertyMap( ) );
262 for (size_t i = 0; i < sizeof(aOrderedStyleTable)/sizeof(aOrderedStyleTable[0]); ++i)
264 TblStylePrs::iterator pIt = m_aStyles.find( aOrderedStyleTable[ i ].type );
265 if ( ( nMask & aOrderedStyleTable[ i ].mask ) && ( pIt != m_aStyles.end( ) ) )
266 lcl_mergeProps( pProps, pIt->second, aOrderedStyleTable[ i ].type );
268 return pProps;
273 struct ListCharStylePropertyMap_t
275 OUString sCharStyleName;
276 PropertyValueVector_t aPropertyValues;
278 ListCharStylePropertyMap_t(const OUString& rCharStyleName, const PropertyValueVector_t& rPropertyValues):
279 sCharStyleName( rCharStyleName ),
280 aPropertyValues( rPropertyValues )
283 typedef std::vector< ListCharStylePropertyMap_t > ListCharStylePropertyVector_t;
286 struct StyleSheetTable_Impl
288 DomainMapper& m_rDMapper;
289 uno::Reference< text::XTextDocument> m_xTextDocument;
290 uno::Reference< beans::XPropertySet> m_xTextDefaults;
291 std::vector< StyleSheetEntryPtr > m_aStyleSheetEntries;
292 StyleSheetEntryPtr m_pCurrentEntry;
293 PropertyMapPtr m_pDefaultParaProps, m_pDefaultCharProps;
294 PropertyMapPtr m_pCurrentProps;
295 StringPairMap_t m_aStyleNameMap;
296 /// Style names which should not be used without a " (user)" suffix.
297 std::set<OUString> m_aReservedStyleNames;
298 ListCharStylePropertyVector_t m_aListCharStylePropertyVector;
299 bool m_bIsNewDoc;
301 StyleSheetTable_Impl(DomainMapper& rDMapper, uno::Reference< text::XTextDocument> const& xTextDocument, bool bIsNewDoc);
303 OUString HasListCharStyle( const PropertyValueVector_t& rCharProperties );
305 /// Appends the given key-value pair to the list of latent style properties of the current entry.
306 void AppendLatentStyleProperty(const OUString& aName, Value& rValue);
310 StyleSheetTable_Impl::StyleSheetTable_Impl(DomainMapper& rDMapper,
311 uno::Reference< text::XTextDocument> const& xTextDocument,
312 bool const bIsNewDoc)
314 m_rDMapper( rDMapper ),
315 m_xTextDocument( xTextDocument ),
316 m_pCurrentEntry(),
317 m_pDefaultParaProps(new PropertyMap),
318 m_pDefaultCharProps(new PropertyMap),
319 m_bIsNewDoc(bIsNewDoc)
321 //set font height default to 10pt
322 uno::Any aVal = uno::makeAny( double(10.) );
323 m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT, aVal );
324 m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT_ASIAN, aVal );
325 m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT_COMPLEX, aVal );
329 OUString StyleSheetTable_Impl::HasListCharStyle( const PropertyValueVector_t& rPropValues )
331 OUString sRet;
332 ListCharStylePropertyVector_t::const_iterator aListVectorIter = m_aListCharStylePropertyVector.begin();
333 while( aListVectorIter != m_aListCharStylePropertyVector.end() )
335 //if size is identical
336 if( aListVectorIter->aPropertyValues.size() == rPropValues.size() )
338 bool bBreak = false;
339 //then search for all contained properties
340 PropertyValueVector_t::const_iterator aList1Iter = rPropValues.begin();
341 while( aList1Iter != rPropValues.end() && !bBreak)
343 //find the property
344 bool bElementFound = false;
345 PropertyValueVector_t::const_iterator aList2Iter = aListVectorIter->aPropertyValues.begin();
346 while( aList2Iter != aListVectorIter->aPropertyValues.end() && !bBreak )
348 if( aList2Iter->Name == aList1Iter->Name )
350 bElementFound = true;
351 if( aList2Iter->Value != aList1Iter->Value )
352 bBreak = true;
353 break;
355 ++aList2Iter;
357 //set break flag if property hasn't been found
358 if(!bElementFound )
360 bBreak = true;
361 break;
363 ++aList1Iter;
365 if( !bBreak )
366 return aListVectorIter->sCharStyleName;
368 ++aListVectorIter;
370 return sRet;
373 void StyleSheetTable_Impl::AppendLatentStyleProperty(const OUString& aName, Value& rValue)
375 beans::PropertyValue aValue;
376 aValue.Name = aName;
377 aValue.Value <<= rValue.getString();
378 m_pCurrentEntry->aLatentStyles.push_back(aValue);
382 StyleSheetTable::StyleSheetTable(DomainMapper& rDMapper,
383 uno::Reference< text::XTextDocument> const& xTextDocument,
384 bool const bIsNewDoc)
385 : LoggedProperties("StyleSheetTable")
386 , LoggedTable("StyleSheetTable")
387 , m_pImpl( new StyleSheetTable_Impl(rDMapper, xTextDocument, bIsNewDoc) )
392 StyleSheetTable::~StyleSheetTable()
394 delete m_pImpl;
397 PropertyMapPtr StyleSheetTable::GetDefaultCharProps()
399 return m_pImpl->m_pDefaultCharProps;
402 void StyleSheetTable::lcl_attribute(Id Name, Value & val)
404 OSL_ENSURE( m_pImpl->m_pCurrentEntry, "current entry has to be set here");
405 if(!m_pImpl->m_pCurrentEntry)
406 return ;
407 int nIntValue = val.getInt();
408 OUString sValue = val.getString();
410 // The default type is paragraph, and it needs to be processed first,
411 // because the NS_ooxml::LN_CT_Style_type handling may set m_pImpl->m_pCurrentEntry
412 // to point to a different object.
413 if( m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_UNKNOWN )
415 if( Name != NS_ooxml::LN_CT_Style_type )
416 m_pImpl->m_pCurrentEntry->nStyleTypeCode = STYLE_TYPE_PARA;
418 switch(Name)
420 case NS_ooxml::LN_CT_Style_type:
422 SAL_WARN_IF( m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN,
423 "writerfilter", "Style type needs to be processed first" );
424 StyleType nType(STYLE_TYPE_UNKNOWN);
425 switch (nIntValue)
427 case NS_ooxml::LN_Value_ST_StyleType_paragraph:
428 nType = STYLE_TYPE_PARA;
429 break;
430 case NS_ooxml::LN_Value_ST_StyleType_character:
431 nType = STYLE_TYPE_CHAR;
432 break;
433 case NS_ooxml::LN_Value_ST_StyleType_table:
434 nType = STYLE_TYPE_TABLE;
435 break;
436 case NS_ooxml::LN_Value_ST_StyleType_numbering:
437 nType = STYLE_TYPE_LIST;
438 break;
439 default:
440 SAL_WARN("writerfilter", "unknown LN_CT_Style_type " << nType);
441 //fall-through
442 case 0: // explicit unknown set by tokenizer
443 break;
446 if ( nType == STYLE_TYPE_TABLE )
448 StyleSheetEntryPtr pEntry = m_pImpl->m_pCurrentEntry;
449 TableStyleSheetEntryPtr pTableEntry( new TableStyleSheetEntry( *pEntry.get( ), this ) );
450 m_pImpl->m_pCurrentEntry = pTableEntry;
452 else
453 m_pImpl->m_pCurrentEntry->nStyleTypeCode = nType;
455 break;
456 case NS_ooxml::LN_CT_Style_default:
457 m_pImpl->m_pCurrentEntry->bIsDefaultStyle = (nIntValue != 0);
458 if (m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN)
460 beans::PropertyValue aValue;
461 aValue.Name = "default";
462 aValue.Value = uno::makeAny(m_pImpl->m_pCurrentEntry->bIsDefaultStyle);
463 m_pImpl->m_pCurrentEntry->AppendInteropGrabBag(aValue);
465 break;
466 case NS_ooxml::LN_CT_Style_customStyle:
467 if (m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN)
469 beans::PropertyValue aValue;
470 aValue.Name = "customStyle";
471 aValue.Value = uno::makeAny(nIntValue != 0);
472 m_pImpl->m_pCurrentEntry->AppendInteropGrabBag(aValue);
474 break;
475 case NS_ooxml::LN_CT_Style_styleId:
476 m_pImpl->m_pCurrentEntry->sStyleIdentifierI = sValue;
477 m_pImpl->m_pCurrentEntry->sStyleIdentifierD = sValue;
478 if(m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE)
480 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get());
481 beans::PropertyValue aValue;
482 aValue.Name = "styleId";
483 aValue.Value = uno::makeAny(sValue);
484 pTableEntry->AppendInteropGrabBag(aValue);
486 break;
487 case NS_ooxml::LN_CT_TblWidth_w:
488 if (StyleSheetPropertyMap* pMap = dynamic_cast< StyleSheetPropertyMap* >( m_pImpl->m_pCurrentEntry->pProperties.get() ))
489 pMap->SetCT_TblWidth_w( nIntValue );
490 break;
491 case NS_ooxml::LN_CT_TblWidth_type:
492 if (StyleSheetPropertyMap* pMap = dynamic_cast< StyleSheetPropertyMap* >( m_pImpl->m_pCurrentEntry->pProperties.get() ))
493 pMap->SetCT_TblWidth_type( nIntValue );
494 break;
495 case NS_ooxml::LN_CT_LatentStyles_defQFormat:
496 m_pImpl->AppendLatentStyleProperty("defQFormat", val);
497 break;
498 case NS_ooxml::LN_CT_LatentStyles_defUnhideWhenUsed:
499 m_pImpl->AppendLatentStyleProperty("defUnhideWhenUsed", val);
500 break;
501 case NS_ooxml::LN_CT_LatentStyles_defSemiHidden:
502 m_pImpl->AppendLatentStyleProperty("defSemiHidden", val);
503 break;
504 case NS_ooxml::LN_CT_LatentStyles_count:
505 m_pImpl->AppendLatentStyleProperty("count", val);
506 break;
507 case NS_ooxml::LN_CT_LatentStyles_defUIPriority:
508 m_pImpl->AppendLatentStyleProperty("defUIPriority", val);
509 break;
510 case NS_ooxml::LN_CT_LatentStyles_defLockedState:
511 m_pImpl->AppendLatentStyleProperty("defLockedState", val);
512 break;
513 default:
515 #ifdef DEBUG_WRITERFILTER
516 TagLogger::getInstance().element("unhandled");
517 #endif
519 break;
524 void StyleSheetTable::lcl_sprm(Sprm & rSprm)
526 sal_uInt32 nSprmId = rSprm.getId();
527 Value::Pointer_t pValue = rSprm.getValue();
528 sal_Int32 nIntValue = pValue.get() ? pValue->getInt() : 0;
529 OUString sStringValue = pValue.get() ? pValue->getString() : OUString();
531 switch(nSprmId)
533 case NS_ooxml::LN_CT_Style_name:
534 //this is only a UI name!
535 m_pImpl->m_pCurrentEntry->sStyleName = sStringValue;
536 m_pImpl->m_pCurrentEntry->sStyleName1 = sStringValue;
537 if(m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE)
539 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get());
540 beans::PropertyValue aValue;
541 aValue.Name = "name";
542 aValue.Value = uno::makeAny(sStringValue);
543 pTableEntry->AppendInteropGrabBag(aValue);
545 break;
546 case NS_ooxml::LN_CT_Style_basedOn:
547 m_pImpl->m_pCurrentEntry->sBaseStyleIdentifier = sStringValue;
548 if(m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE)
550 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get());
551 beans::PropertyValue aValue;
552 aValue.Name = "basedOn";
553 aValue.Value = uno::makeAny(sStringValue);
554 pTableEntry->AppendInteropGrabBag(aValue);
556 break;
557 case NS_ooxml::LN_CT_Style_next:
558 m_pImpl->m_pCurrentEntry->sNextStyleIdentifier = sStringValue;
559 break;
560 case NS_ooxml::LN_CT_Style_aliases:
561 case NS_ooxml::LN_CT_Style_hidden:
562 case NS_ooxml::LN_CT_Style_personal:
563 case NS_ooxml::LN_CT_Style_personalCompose:
564 case NS_ooxml::LN_CT_Style_personalReply:
565 break;
566 case NS_ooxml::LN_CT_Style_autoRedefine:
567 m_pImpl->m_pCurrentEntry->bAutoRedefine = nIntValue;
568 break;
569 case NS_ooxml::LN_CT_Style_tcPr:
571 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
572 if( pProperties.get() && m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE)
574 TblStylePrHandlerPtr pTblStylePrHandler(new TblStylePrHandler(m_pImpl->m_rDMapper));
575 pProperties->resolve(*pTblStylePrHandler);
576 StyleSheetEntry* pEntry = m_pImpl->m_pCurrentEntry.get();
577 TableStyleSheetEntry& rTableEntry = dynamic_cast<TableStyleSheetEntry&>(*pEntry);
578 rTableEntry.AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tcPr"));
580 // This is a <w:tcPr> directly under <w:style>, so it affects the whole table.
581 rTableEntry.pProperties->InsertProps(pTblStylePrHandler->getProperties());
584 break;
585 case NS_ooxml::LN_CT_Style_trPr:
586 break;
587 case NS_ooxml::LN_CT_Style_rsid:
588 case NS_ooxml::LN_CT_Style_qFormat:
589 case NS_ooxml::LN_CT_Style_semiHidden:
590 case NS_ooxml::LN_CT_Style_unhideWhenUsed:
591 case NS_ooxml::LN_CT_Style_uiPriority:
592 case NS_ooxml::LN_CT_Style_link:
593 case NS_ooxml::LN_CT_Style_locked:
594 if (m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN)
596 StyleSheetEntryPtr pEntry = m_pImpl->m_pCurrentEntry;
597 beans::PropertyValue aValue;
598 switch (nSprmId)
600 case NS_ooxml::LN_CT_Style_rsid:
602 // We want the rsid as a hex string, but always with the length of 8.
603 OUStringBuffer aBuf = OUString::number(nIntValue, 16);
604 OUStringBuffer aStr;
605 comphelper::string::padToLength(aStr, 8 - aBuf.getLength(), '0');
606 aStr.append(aBuf.getStr());
608 aValue.Name = "rsid";
609 aValue.Value = uno::makeAny(aStr.makeStringAndClear());
611 break;
612 case NS_ooxml::LN_CT_Style_qFormat:
613 aValue.Name = "qFormat";
614 break;
615 case NS_ooxml::LN_CT_Style_semiHidden:
616 aValue.Name = "semiHidden";
617 break;
618 case NS_ooxml::LN_CT_Style_unhideWhenUsed:
619 aValue.Name = "unhideWhenUsed";
620 break;
621 case NS_ooxml::LN_CT_Style_uiPriority:
623 aValue.Name = "uiPriority";
624 aValue.Value = uno::makeAny(OUString::number(nIntValue));
626 break;
627 case NS_ooxml::LN_CT_Style_link:
629 aValue.Name = "link";
630 aValue.Value = uno::makeAny(sStringValue);
632 break;
633 case NS_ooxml::LN_CT_Style_locked:
634 aValue.Name = "locked";
635 break;
637 pEntry->AppendInteropGrabBag(aValue);
639 break;
640 case NS_ooxml::LN_CT_Style_tblPr: //contains table properties
641 case NS_ooxml::LN_CT_Style_tblStylePr: //contains to table properties
642 case NS_ooxml::LN_CT_TblPrBase_tblInd: //table properties - at least width value and type
643 case NS_ooxml::LN_EG_RPrBase_rFonts: //table fonts
645 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
646 if( pProperties.get())
648 TblStylePrHandlerPtr pTblStylePrHandler( new TblStylePrHandler( m_pImpl->m_rDMapper ) );
649 pProperties->resolve( *pTblStylePrHandler );
651 // Add the properties to the table style
652 TblStyleType nType = pTblStylePrHandler->getType( );
653 PropertyMapPtr pProps = pTblStylePrHandler->getProperties( );
654 StyleSheetEntry * pEntry = m_pImpl->m_pCurrentEntry.get();
656 TableStyleSheetEntry * pTableEntry = dynamic_cast<TableStyleSheetEntry*>( pEntry );
657 if (nType == TBL_STYLE_UNKNOWN)
659 pEntry->pProperties->InsertProps(pProps);
661 else
663 if (pTableEntry != nullptr)
664 pTableEntry->AddTblStylePr( nType, pProps );
667 if (nSprmId == NS_ooxml::LN_CT_Style_tblPr)
669 if (pTableEntry != nullptr)
670 pTableEntry->AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tblPr"));
672 else if (nSprmId == NS_ooxml::LN_CT_Style_tblStylePr)
674 pTblStylePrHandler->appendInteropGrabBag("type", pTblStylePrHandler->getTypeString());
675 if (pTableEntry != nullptr)
676 pTableEntry->AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tblStylePr"));
679 break;
681 case NS_ooxml::LN_CT_PPrDefault_pPr:
682 case NS_ooxml::LN_CT_DocDefaults_pPrDefault:
683 m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pDefaultParaProps );
684 resolveSprmProps( m_pImpl->m_rDMapper, rSprm );
685 m_pImpl->m_rDMapper.PopStyleSheetProperties();
686 applyDefaults( true );
687 break;
688 case NS_ooxml::LN_CT_RPrDefault_rPr:
689 case NS_ooxml::LN_CT_DocDefaults_rPrDefault:
690 m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pDefaultCharProps );
691 resolveSprmProps( m_pImpl->m_rDMapper, rSprm );
692 m_pImpl->m_rDMapper.PopStyleSheetProperties();
693 applyDefaults( false );
694 break;
695 case NS_ooxml::LN_CT_TblPrBase_jc: //table alignment - row properties!
696 m_pImpl->m_pCurrentEntry->pProperties->Insert( PROP_HORI_ORIENT,
697 uno::makeAny( ConversionHelper::convertTableJustification( nIntValue )));
698 break;
699 case NS_ooxml::LN_CT_TrPrBase_jc: //table alignment - row properties!
700 if (StyleSheetPropertyMap* pMap = dynamic_cast< StyleSheetPropertyMap* >( m_pImpl->m_pCurrentEntry->pProperties.get() ))
701 pMap->SetCT_TrPrBase_jc(nIntValue);
702 break;
703 case NS_ooxml::LN_CT_TblPrBase_tblBorders: //table borders, might be defined in table style
705 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
706 if( pProperties.get())
708 BorderHandlerPtr pBorderHandler( new BorderHandler(m_pImpl->m_rDMapper.IsOOXMLImport()) );
709 pProperties->resolve(*pBorderHandler);
710 m_pImpl->m_pCurrentEntry->pProperties->InsertProps(
711 pBorderHandler->getProperties());
714 break;
715 case NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize:
716 case NS_ooxml::LN_CT_TblPrBase_tblStyleColBandSize:
718 StyleSheetEntry* pEntry = m_pImpl->m_pCurrentEntry.get( );
719 TableStyleSheetEntry *pTEntry = static_cast<TableStyleSheetEntry*>( pEntry );
720 if ( pTEntry )
722 if ( nSprmId == NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize )
723 pTEntry->m_nRowBandSize = nIntValue;
724 else
725 pTEntry->m_nColBandSize = nIntValue;
728 break;
729 case NS_ooxml::LN_CT_TblPrBase_tblCellMar:
730 //no cell margins in styles
731 break;
732 case NS_ooxml::LN_CT_LatentStyles_lsdException:
734 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
735 if (pProperties.get())
737 LatentStyleHandlerPtr pLatentStyleHandler(new LatentStyleHandler());
738 pProperties->resolve(*pLatentStyleHandler);
739 beans::PropertyValue aValue;
740 aValue.Name = "lsdException";
741 aValue.Value = uno::makeAny(pLatentStyleHandler->getAttributes());
742 m_pImpl->m_pCurrentEntry->aLsdExceptions.push_back(aValue);
745 break;
746 case NS_ooxml::LN_CT_Style_pPr:
747 // no break
748 case NS_ooxml::LN_CT_Style_rPr:
749 // no break
750 default:
752 if (!m_pImpl->m_pCurrentEntry)
753 break;
755 TablePropertiesHandlerPtr pTblHandler(new TablePropertiesHandler());
756 pTblHandler->SetProperties( m_pImpl->m_pCurrentEntry->pProperties );
757 if ( !pTblHandler->sprm( rSprm ) )
759 m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pCurrentEntry->pProperties );
761 PropertyMapPtr pProps(new PropertyMap());
762 bool bTableStyleRunProps = m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE && nSprmId == NS_ooxml::LN_CT_Style_rPr;
763 if (bTableStyleRunProps)
764 m_pImpl->m_rDMapper.setInTableStyleRunProps(true);
765 if (m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE)
767 if (nSprmId == NS_ooxml::LN_CT_Style_pPr)
768 m_pImpl->m_rDMapper.enableInteropGrabBag("pPr");
769 else if (nSprmId == NS_ooxml::LN_CT_Style_rPr)
770 m_pImpl->m_rDMapper.enableInteropGrabBag("rPr");
772 m_pImpl->m_rDMapper.sprmWithProps( rSprm, pProps );
773 if (m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE)
775 if (nSprmId == NS_ooxml::LN_CT_Style_pPr || nSprmId == NS_ooxml::LN_CT_Style_rPr)
777 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get());
778 pTableEntry->AppendInteropGrabBag(m_pImpl->m_rDMapper.getInteropGrabBag());
781 if (bTableStyleRunProps)
782 m_pImpl->m_rDMapper.setInTableStyleRunProps(false);
784 m_pImpl->m_pCurrentEntry->pProperties->InsertProps(pProps);
786 m_pImpl->m_rDMapper.PopStyleSheetProperties( );
788 if (m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_PARA && m_pImpl->m_pCurrentEntry->bIsDefaultStyle)
790 // The current style is the default paragraph style.
791 PropertyMapPtr pProperties = m_pImpl->m_pCurrentEntry->pProperties;
792 if (pProperties->isSet(PROP_CHAR_HEIGHT) && !m_pImpl->m_pDefaultParaProps->isSet(PROP_CHAR_HEIGHT))
794 // We provide a character height value, but a document-level default wasn't set.
795 if (m_pImpl->m_xTextDefaults.is())
797 m_pImpl->m_xTextDefaults->setPropertyValue("CharHeight", pProperties->getProperty(PROP_CHAR_HEIGHT)->second);
803 break;
808 void StyleSheetTable::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t ref)
810 //create a new style entry
811 OSL_ENSURE( !m_pImpl->m_pCurrentEntry, "current entry has to be NULL here");
812 StyleSheetEntryPtr pNewEntry( new StyleSheetEntry );
813 m_pImpl->m_pCurrentEntry = pNewEntry;
814 m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pCurrentEntry->pProperties );
815 ref->resolve(*this);
816 //append it to the table
817 m_pImpl->m_rDMapper.PopStyleSheetProperties();
818 if( !m_pImpl->m_rDMapper.IsOOXMLImport() || !m_pImpl->m_pCurrentEntry->sStyleName.isEmpty())
820 m_pImpl->m_pCurrentEntry->sConvertedStyleName = ConvertStyleName( m_pImpl->m_pCurrentEntry->sStyleName );
821 m_pImpl->m_aStyleSheetEntries.push_back( m_pImpl->m_pCurrentEntry );
823 else
825 //TODO: this entry contains the default settings - they have to be added to the settings
828 if (!m_pImpl->m_pCurrentEntry->aLatentStyles.empty())
830 // We have latent styles for this entry, then process them.
831 std::vector<beans::PropertyValue>& rLatentStyles = m_pImpl->m_pCurrentEntry->aLatentStyles;
833 if (!m_pImpl->m_pCurrentEntry->aLsdExceptions.empty())
835 std::vector<beans::PropertyValue>& rLsdExceptions = m_pImpl->m_pCurrentEntry->aLsdExceptions;
836 uno::Sequence<beans::PropertyValue> aLsdExceptions(rLsdExceptions.size());
837 beans::PropertyValue* pLsdExceptions = aLsdExceptions.getArray();
838 for (std::vector<beans::PropertyValue>::iterator i = rLsdExceptions.begin(); i != rLsdExceptions.end(); ++i)
839 *pLsdExceptions++ = *i;
841 beans::PropertyValue aValue;
842 aValue.Name = "lsdExceptions";
843 aValue.Value = uno::makeAny(aLsdExceptions);
844 rLatentStyles.push_back(aValue);
847 uno::Sequence<beans::PropertyValue> aLatentStyles(rLatentStyles.size());
848 beans::PropertyValue* pLatentStyles = aLatentStyles.getArray();
849 for (std::vector<beans::PropertyValue>::iterator i = rLatentStyles.begin(); i != rLatentStyles.end(); ++i)
850 *pLatentStyles++ = *i;
852 // We can put all latent style info directly to the document interop
853 // grab bag, as we can be sure that only a single style entry has
854 // latent style info.
855 uno::Reference<beans::XPropertySet> xPropertySet(m_pImpl->m_xTextDocument, uno::UNO_QUERY);
856 auto aGrabBag = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(xPropertySet->getPropertyValue("InteropGrabBag").get< uno::Sequence<beans::PropertyValue> >());
857 beans::PropertyValue aValue;
858 aValue.Name = "latentStyles";
859 aValue.Value = uno::makeAny(aLatentStyles);
860 aGrabBag.push_back(aValue);
861 xPropertySet->setPropertyValue("InteropGrabBag", uno::makeAny(comphelper::containerToSequence(aGrabBag)));
864 StyleSheetEntryPtr pEmptyEntry;
865 m_pImpl->m_pCurrentEntry = pEmptyEntry;
867 /*-------------------------------------------------------------------------
868 sorting helper
869 -----------------------------------------------------------------------*/
870 typedef std::vector< beans::PropertyValue > _PropValVector;
871 class PropValVector : public _PropValVector
873 public:
874 PropValVector(){}
876 void Insert(const beans::PropertyValue& rVal);
877 uno::Sequence< uno::Any > getValues();
878 uno::Sequence< OUString > getNames();
881 void PropValVector::Insert(const beans::PropertyValue& rVal)
883 _PropValVector::iterator aIt = begin();
884 while(aIt != end())
886 if(aIt->Name > rVal.Name)
888 insert( aIt, rVal );
889 return;
891 ++aIt;
893 push_back(rVal);
895 uno::Sequence< uno::Any > PropValVector::getValues()
897 uno::Sequence< uno::Any > aRet( size() );
898 uno::Any* pValues = aRet.getArray();
899 sal_Int32 nVal = 0;
900 _PropValVector::iterator aIt = begin();
901 while(aIt != end())
903 pValues[nVal++] = aIt->Value;
904 ++aIt;
906 return aRet;
908 uno::Sequence< OUString > PropValVector::getNames()
910 uno::Sequence< OUString > aRet( size() );
911 OUString* pNames = aRet.getArray();
912 sal_Int32 nVal = 0;
913 _PropValVector::iterator aIt = begin();
914 while(aIt != end())
916 pNames[nVal++] = aIt->Name;
917 ++aIt;
919 return aRet;
923 void StyleSheetTable::ApplyStyleSheets( FontTablePtr rFontTable )
927 uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
928 uno::Reference< lang::XMultiServiceFactory > xDocFactory( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
929 uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
930 uno::Reference<container::XNameContainer> xCharStyles;
931 uno::Reference<container::XNameContainer> xParaStyles;
932 uno::Reference<container::XNameContainer> xNumberingStyles;
934 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
935 xStyleFamilies->getByName(rPropNameSupplier.GetName( PROP_CHARACTER_STYLES )) >>= xCharStyles;
936 xStyleFamilies->getByName(rPropNameSupplier.GetName( PROP_PARAGRAPH_STYLES )) >>= xParaStyles;
937 xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles;
938 if(xCharStyles.is() && xParaStyles.is())
940 std::vector<beans::PropertyValue> aTableStylesVec;
941 std::vector< StyleSheetEntryPtr >::iterator aIt = m_pImpl->m_aStyleSheetEntries.begin();
942 while( aIt != m_pImpl->m_aStyleSheetEntries.end() )
944 StyleSheetEntryPtr pEntry = *aIt;
945 if( pEntry->nStyleTypeCode == STYLE_TYPE_CHAR || pEntry->nStyleTypeCode == STYLE_TYPE_PARA || pEntry->nStyleTypeCode == STYLE_TYPE_LIST )
947 bool bParaStyle = pEntry->nStyleTypeCode == STYLE_TYPE_PARA;
948 bool bListStyle = pEntry->nStyleTypeCode == STYLE_TYPE_LIST;
949 bool bInsert = false;
950 uno::Reference< container::XNameContainer > xStyles = bParaStyle ? xParaStyles : (bListStyle ? xNumberingStyles : xCharStyles);
951 uno::Reference< style::XStyle > xStyle;
952 OUString sConvertedStyleName = ConvertStyleName( pEntry->sStyleName );
954 if(xStyles->hasByName( sConvertedStyleName ))
956 // When pasting, don't update existing styles.
957 if (!m_pImpl->m_bIsNewDoc)
959 ++aIt;
960 continue;
962 xStyles->getByName( sConvertedStyleName ) >>= xStyle;
964 // See if the existing style has any non-default properties. If so, reset them back to default.
965 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY);
966 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
967 uno::Sequence<beans::Property> aProperties = xPropertySetInfo->getProperties();
968 std::vector<OUString> aPropertyNames;
969 for (sal_Int32 i = 0; i < aProperties.getLength(); ++i)
971 aPropertyNames.push_back(aProperties[i].Name);
974 uno::Reference<beans::XPropertyState> xPropertyState(xStyle, uno::UNO_QUERY);
975 uno::Sequence<beans::PropertyState> aStates = xPropertyState->getPropertyStates(comphelper::containerToSequence(aPropertyNames));
976 for (sal_Int32 i = 0; i < aStates.getLength(); ++i)
978 if (aStates[i] == beans::PropertyState_DIRECT_VALUE)
982 xPropertyState->setPropertyToDefault(aPropertyNames[i]);
984 catch(const uno::Exception& rException)
986 SAL_INFO("writerfilter", "setPropertyToDefault(" << aPropertyNames[i] << ") failed: " << rException.Message);
991 else
993 bInsert = true;
994 xStyle = uno::Reference< style::XStyle >(xDocFactory->createInstance(
995 bParaStyle ?
996 rPropNameSupplier.GetName( PROP_SERVICE_PARA_STYLE ) :
997 (bListStyle ? OUString("com.sun.star.style.NumberingStyle") : rPropNameSupplier.GetName( PROP_SERVICE_CHAR_STYLE ))),
998 uno::UNO_QUERY_THROW);
1000 // Numbering styles have to be inserted early, as e.g. the NumberingRules property is only available after insertion.
1001 if (bListStyle)
1003 xStyles->insertByName( sConvertedStyleName, uno::makeAny( xStyle ) );
1004 xStyle.set(xStyles->getByName(sConvertedStyleName), uno::UNO_QUERY_THROW);
1006 StyleSheetPropertyMap* pPropertyMap = dynamic_cast<StyleSheetPropertyMap*>(pEntry->pProperties.get());
1007 if (pPropertyMap && pPropertyMap->GetListId() == -1)
1009 // No properties? Word default is 'none', Writer one is 'arabic', handle this.
1010 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY_THROW);
1011 uno::Reference<container::XIndexReplace> xNumberingRules;
1012 xPropertySet->getPropertyValue("NumberingRules") >>= xNumberingRules;
1013 uno::Reference<container::XIndexAccess> xIndexAccess(xNumberingRules, uno::UNO_QUERY_THROW);
1014 for (sal_Int32 i = 0; i < xIndexAccess->getCount(); ++i)
1016 uno::Sequence< beans::PropertyValue > aLvlProps(1);
1017 aLvlProps[0].Name = "NumberingType";
1018 aLvlProps[0].Value <<= style::NumberingType::NUMBER_NONE;
1019 xNumberingRules->replaceByIndex(i, uno::makeAny(aLvlProps));
1020 xPropertySet->setPropertyValue("NumberingRules", uno::makeAny(xNumberingRules));
1025 if( !pEntry->sBaseStyleIdentifier.isEmpty() )
1029 //TODO: Handle cases where a paragraph <> character style relation is needed
1030 StyleSheetEntryPtr pParent = FindStyleSheetByISTD( pEntry->sBaseStyleIdentifier );
1031 // Writer core doesn't support numbering styles having a parent style, it seems
1032 if (pParent.get() != nullptr && !bListStyle)
1033 xStyle->setParentStyle(ConvertStyleName( pParent->sStyleName ));
1035 catch( const uno::RuntimeException& )
1037 OSL_FAIL( "Styles parent could not be set");
1040 else if( bParaStyle )
1042 //now it's time to set the default parameters - for paragraph styles
1043 //Fonts: Western first entry in font table
1044 //CJK: second entry
1045 //CTL: third entry, if it exists
1047 sal_uInt32 nFontCount = rFontTable->size();
1048 if( !m_pImpl->m_rDMapper.IsOOXMLImport() && nFontCount > 2 )
1050 uno::Any aTwoHundredFortyTwip = uno::makeAny(12.);
1052 // font size to 240 twip (12 pts) for all if not set
1053 pEntry->pProperties->Insert(PROP_CHAR_HEIGHT, aTwoHundredFortyTwip, false);
1055 // western font not already set -> apply first font
1056 const FontEntry::Pointer_t pWesternFontEntry(rFontTable->getFontEntry( 0 ));
1057 OUString sWesternFontName = pWesternFontEntry->sFontName;
1058 pEntry->pProperties->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( sWesternFontName ), false);
1060 // CJK ... apply second font
1061 const FontEntry::Pointer_t pCJKFontEntry(rFontTable->getFontEntry( 2 ));
1062 pEntry->pProperties->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::makeAny( pCJKFontEntry->sFontName ), false);
1063 pEntry->pProperties->Insert(PROP_CHAR_HEIGHT_ASIAN, aTwoHundredFortyTwip, false);
1065 // CTL ... apply third font, if available
1066 if( nFontCount > 3 )
1068 const FontEntry::Pointer_t pCTLFontEntry(rFontTable->getFontEntry( 3 ));
1069 pEntry->pProperties->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::makeAny( pCTLFontEntry->sFontName ), false);
1070 pEntry->pProperties->Insert(PROP_CHAR_HEIGHT_COMPLEX, aTwoHundredFortyTwip, false);
1074 // Widow/Orphan -> set both to two if not already set
1075 uno::Any aTwo = uno::makeAny(sal_Int8(2));
1076 pEntry->pProperties->Insert(PROP_PARA_WIDOWS, aTwo, false);
1077 pEntry->pProperties->Insert(PROP_PARA_ORPHANS, aTwo, false);
1079 // Left-to-right direction if not already set
1080 pEntry->pProperties->Insert(PROP_WRITING_MODE, uno::makeAny( sal_Int16(text::WritingMode_LR_TB) ), false);
1081 // Left alignment if not already set
1082 pEntry->pProperties->Insert(PROP_PARA_ADJUST, uno::makeAny( sal_Int16(style::ParagraphAdjust_LEFT) ), false);
1085 auto aPropValues = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(pEntry->pProperties->GetPropertyValues());
1086 bool bAddFollowStyle = false;
1087 if(bParaStyle && !pEntry->sNextStyleIdentifier.isEmpty() )
1089 bAddFollowStyle = true;
1092 // remove Left/RightMargin values from TOX heading styles
1093 if( bParaStyle )
1095 // Set the outline levels
1096 const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : nullptr);
1097 if ( pStyleSheetProperties )
1099 beans::PropertyValue aLvlVal( rPropNameSupplier.GetName( PROP_OUTLINE_LEVEL ), 0,
1100 uno::makeAny( sal_Int16( pStyleSheetProperties->GetOutlineLevel( ) + 1 ) ),
1101 beans::PropertyState_DIRECT_VALUE );
1102 aPropValues.push_back(aLvlVal);
1105 uno::Reference< beans::XPropertyState >xState( xStyle, uno::UNO_QUERY_THROW );
1106 if( sConvertedStyleName == "Contents Heading" ||
1107 sConvertedStyleName == "User Index Heading" ||
1108 sConvertedStyleName == "Index Heading" )
1110 //left margin is set to NULL by default
1111 uno::Reference< beans::XPropertyState >xState1( xStyle, uno::UNO_QUERY_THROW );
1112 xState1->setPropertyToDefault(rPropNameSupplier.GetName( PROP_PARA_LEFT_MARGIN ));
1114 else if ( sConvertedStyleName == "Text body" )
1115 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_PARA_BOTTOM_MARGIN ));
1116 else if( sConvertedStyleName == "Heading 1" ||
1117 sConvertedStyleName == "Heading 2" ||
1118 sConvertedStyleName == "Heading 3" ||
1119 sConvertedStyleName == "Heading 4" ||
1120 sConvertedStyleName == "Heading 5" ||
1121 sConvertedStyleName == "Heading 6" ||
1122 sConvertedStyleName == "Heading 7" ||
1123 sConvertedStyleName == "Heading 8" ||
1124 sConvertedStyleName == "Heading 9" )
1126 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_WEIGHT ));
1127 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_WEIGHT_ASIAN ));
1128 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_WEIGHT_COMPLEX ));
1129 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_POSTURE ));
1130 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_POSTURE_ASIAN ));
1131 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_POSTURE_COMPLEX ));
1132 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_PROP_HEIGHT ));
1133 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_PROP_HEIGHT_ASIAN ));
1134 xState->setPropertyToDefault(rPropNameSupplier.GetName( PROP_CHAR_PROP_HEIGHT_COMPLEX));
1139 if(bAddFollowStyle || !aPropValues.empty())
1141 PropValVector aSortedPropVals;
1142 for (const beans::PropertyValue& rValue : aPropValues)
1144 // Don't add the style name properties
1145 bool bIsParaStyleName = rValue.Name == "ParaStyleName";
1146 bool bIsCharStyleName = rValue.Name == "CharStyleName";
1147 if ( !bIsParaStyleName && !bIsCharStyleName )
1149 aSortedPropVals.Insert(rValue);
1152 if(bAddFollowStyle)
1154 //find the name of the Next style
1155 std::vector< StyleSheetEntryPtr >::iterator it = m_pImpl->m_aStyleSheetEntries.begin();
1156 for (; it != m_pImpl->m_aStyleSheetEntries.end(); ++it)
1158 if (!(*it)->sStyleName.isEmpty() && (*it)->sStyleIdentifierD == pEntry->sNextStyleIdentifier)
1160 beans::PropertyValue aNew;
1161 aNew.Name = "FollowStyle";
1162 aNew.Value = uno::makeAny(ConvertStyleName((*it)->sStyleIdentifierD));
1163 aSortedPropVals.Insert(aNew);
1164 break;
1171 uno::Reference< beans::XMultiPropertySet > xMultiPropertySet( xStyle, uno::UNO_QUERY_THROW);
1172 xMultiPropertySet->setPropertyValues( aSortedPropVals.getNames(), aSortedPropVals.getValues() );
1174 catch( const lang::WrappedTargetException& rWrapped)
1176 (void) rWrapped;
1177 #ifdef DEBUG_WRITERFILTER
1178 OUString aMessage("StyleSheetTable::ApplyStyleSheets: Some style properties could not be set");
1179 beans::UnknownPropertyException aUnknownPropertyException;
1181 if (rWrapped.TargetException >>= aUnknownPropertyException)
1182 aMessage += ": " + aUnknownPropertyException.Message;
1184 SAL_WARN("writerfilter", aMessage);
1185 #endif
1187 catch( const uno::Exception& )
1189 OSL_FAIL( "Some style properties could not be set");
1192 // Numbering style got inserted earlier.
1193 if(bInsert && !bListStyle)
1195 xStyles->insertByName( sConvertedStyleName, uno::makeAny( xStyle) );
1198 beans::PropertyValues aGrabBag = pEntry->GetInteropGrabBagSeq();
1199 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY);
1200 if (aGrabBag.hasElements())
1202 xPropertySet->setPropertyValue("StyleInteropGrabBag", uno::makeAny(aGrabBag));
1205 // List styles don't support automatic update.
1206 if (pEntry->bAutoRedefine && !bListStyle)
1207 xPropertySet->setPropertyValue("IsAutoUpdate", uno::makeAny(sal_True));
1209 else if(pEntry->nStyleTypeCode == STYLE_TYPE_TABLE)
1211 // If this is a table style, save its contents as-is for roundtrip purposes.
1212 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(pEntry.get());
1213 aTableStylesVec.push_back(pTableEntry->GetInteropGrabBag());
1215 ++aIt;
1218 if (!aTableStylesVec.empty())
1220 // If we had any table styles, add a new document-level InteropGrabBag entry for them.
1221 uno::Reference<beans::XPropertySet> xPropertySet(m_pImpl->m_xTextDocument, uno::UNO_QUERY);
1222 uno::Any aAny = xPropertySet->getPropertyValue("InteropGrabBag");
1223 auto aGrabBag = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aAny.get< uno::Sequence<beans::PropertyValue> >());
1224 beans::PropertyValue aValue;
1225 aValue.Name = "tableStyles";
1226 aValue.Value = uno::makeAny(comphelper::containerToSequence(aTableStylesVec));
1227 aGrabBag.push_back(aValue);
1228 xPropertySet->setPropertyValue("InteropGrabBag", uno::makeAny(comphelper::containerToSequence(aGrabBag)));
1232 catch( const uno::Exception& rException )
1234 SAL_WARN("writerfilter", "Styles could not be imported completely: " << rException.Message);
1239 const StyleSheetEntryPtr StyleSheetTable::FindStyleSheetByISTD(const OUString& sIndex)
1241 StyleSheetEntryPtr pRet;
1242 for( sal_uInt32 nPos = 0; nPos < m_pImpl->m_aStyleSheetEntries.size(); ++nPos )
1244 if( m_pImpl->m_aStyleSheetEntries[nPos]->sStyleIdentifierD == sIndex)
1246 pRet = m_pImpl->m_aStyleSheetEntries[nPos];
1247 break;
1250 return pRet;
1254 const StyleSheetEntryPtr StyleSheetTable::FindStyleSheetByStyleName(const OUString& sIndex)
1256 StyleSheetEntryPtr pRet;
1257 for( sal_uInt32 nPos = 0; nPos < m_pImpl->m_aStyleSheetEntries.size(); ++nPos )
1259 if( m_pImpl->m_aStyleSheetEntries[nPos]->sStyleName == sIndex)
1261 pRet = m_pImpl->m_aStyleSheetEntries[nPos];
1262 break;
1265 return pRet;
1269 const StyleSheetEntryPtr StyleSheetTable::FindStyleSheetByConvertedStyleName(const OUString& sIndex)
1271 StyleSheetEntryPtr pRet;
1272 for( sal_uInt32 nPos = 0; nPos < m_pImpl->m_aStyleSheetEntries.size(); ++nPos )
1274 if( m_pImpl->m_aStyleSheetEntries[nPos]->sConvertedStyleName == sIndex)
1276 pRet = m_pImpl->m_aStyleSheetEntries[nPos];
1277 break;
1280 return pRet;
1284 const StyleSheetEntryPtr StyleSheetTable::FindDefaultParaStyle()
1286 StyleSheetEntryPtr pRet;
1287 for (size_t i = 0; i < m_pImpl->m_aStyleSheetEntries.size(); ++i)
1289 StyleSheetEntryPtr pEntry = m_pImpl->m_aStyleSheetEntries[i];
1290 if (pEntry->bIsDefaultStyle && pEntry->nStyleTypeCode == STYLE_TYPE_PARA)
1292 pRet = pEntry;
1293 break;
1296 return pRet;
1299 const StyleSheetEntryPtr StyleSheetTable::FindParentStyleSheet(const OUString& _sBaseStyle)
1301 if( _sBaseStyle.isEmpty() )
1303 StyleSheetEntryPtr pEmptyPtr;
1304 return pEmptyPtr;
1306 OUString sBaseStyle = _sBaseStyle;
1307 if( m_pImpl->m_pCurrentEntry)
1308 sBaseStyle = m_pImpl->m_pCurrentEntry->sBaseStyleIdentifier;
1310 return FindStyleSheetByISTD( sBaseStyle );
1314 static const sal_Char* const aStyleNamePairs[] =
1316 "Normal", "Standard",
1317 "heading 1", "Heading 1",
1318 "heading 2", "Heading 2",
1319 "heading 3", "Heading 3",
1320 "heading 4", "Heading 4",
1321 "heading 5", "Heading 5",
1322 "heading 6", "Heading 6",
1323 "heading 7", "Heading 7",
1324 "heading 8", "Heading 8",
1325 "heading 9", "Heading 9",
1326 "Heading1", "Heading 1",
1327 "Heading2", "Heading 2",
1328 "Heading3", "Heading 3",
1329 "Heading4", "Heading 4",
1330 "Heading5", "Heading 5",
1331 "Heading6", "Heading 6",
1332 "Heading7", "Heading 7",
1333 "Heading8", "Heading 8",
1334 "Heading9", "Heading 9",
1335 "Heading 1", "Heading 1",
1336 "Heading 2", "Heading 2",
1337 "Heading 3", "Heading 3",
1338 "Heading 4", "Heading 4",
1339 "Heading 5", "Heading 5",
1340 "Heading 6", "Heading 6",
1341 "Heading 7", "Heading 7",
1342 "Heading 8", "Heading 8",
1343 "Heading 9", "Heading 9",
1344 "Index 1", "Index 1",
1345 "Index 2", "Index 2",
1346 "Index 3", "Index 3",
1347 "Index 4", "",
1348 "Index 5", "",
1349 "Index 6", "",
1350 "Index 7", "",
1351 "Index 8", "",
1352 "Index 9", "",
1353 "TOC 1", "Contents 1",
1354 "TOC 2", "Contents 2",
1355 "TOC 3", "Contents 3",
1356 "TOC 4", "Contents 4",
1357 "TOC 5", "Contents 5",
1358 "TOC 6", "Contents 6",
1359 "TOC 7", "Contents 7",
1360 "TOC 8", "Contents 8",
1361 "TOC 9", "Contents 9",
1362 "TOCHeading", "Contents Heading",
1363 "toc 1", "Contents 1",
1364 "toc 2", "Contents 2",
1365 "toc 3", "Contents 3",
1366 "toc 4", "Contents 4",
1367 "toc 5", "Contents 5",
1368 "toc 6", "Contents 6",
1369 "toc 7", "Contents 7",
1370 "toc 8", "Contents 8",
1371 "toc 9", "Contents 9",
1372 "TOC1", "Contents 1",
1373 "TOC2", "Contents 2",
1374 "TOC3", "Contents 3",
1375 "TOC4", "Contents 4",
1376 "TOC5", "Contents 5",
1377 "TOC6", "Contents 6",
1378 "TOC7", "Contents 7",
1379 "TOC8", "Contents 8",
1380 "TOC9", "Contents 9",
1381 "Normal Indent", "",
1382 "Footnote Text", "Footnote",
1383 "Annotation Text", "",
1384 "Header", "Header",
1385 "header", "Header",
1386 "Footer", "Footer",
1387 "footer", "Footer",
1388 "Index Heading", "Index Heading",
1389 "Caption", "",
1390 "Table of Figures", "",
1391 "Envelope Address", "Addressee",
1392 "Envelope Return", "Sender",
1393 "Footnote Reference", "Footnote anchor",
1394 "Annotation Reference", "",
1395 "Line Number", "Line numbering",
1396 "Page Number", "Page Number",
1397 "Endnote Reference", "Endnote anchor",
1398 "Endnote Text", "Endnote Symbol",
1399 "Table of Authorities", "",
1400 "Macro Text", "",
1401 "TOA Heading", "",
1402 "List", "List",
1403 "List 2", "",
1404 "List 3", "",
1405 "List 4", "",
1406 "List 5", "",
1407 "List Bullet", "",
1408 "List Bullet 2", "",
1409 "List Bullet 3", "",
1410 "List Bullet 4", "",
1411 "List Bullet 5", "",
1412 "List Number", "",
1413 "List Number 2", "",
1414 "List Number 3", "",
1415 "List Number 4", "",
1416 "List Number 5", "",
1417 "Title", "Title",
1418 "Closing", "",
1419 "Signature", "Signature",
1420 "Default Paragraph Font", "",
1421 "DefaultParagraphFont", "Default Paragraph Font",
1422 "Body Text", "Text body",
1423 "BodyText", "Text body",
1424 "BodyTextIndentItalic", "Text body indent italic",
1425 "Body Text Indent", "Text body indent",
1426 "BodyTextIndent", "Text body indent",
1427 "BodyTextIndent2", "Text body indent2",
1428 "List Continue", "",
1429 "List Continue 2", "",
1430 "List Continue 3", "",
1431 "List Continue 4", "",
1432 "List Continue 5", "",
1433 "Message Header", "",
1434 "Subtitle", "Subtitle",
1435 "Salutation", "",
1436 "Date", "",
1437 "Body Text First Indent", "Body Text Indent",
1438 "Body Text First Indent 2", "",
1439 "Note Heading", "",
1440 "Body Text 2", "",
1441 "Body Text 3", "",
1442 "Body Text Indent 2", "",
1443 "Body Text Indent 3", "",
1444 "Block Text", "",
1445 "Hyperlink", "Internet link",
1446 "Followed Hyperlink", "Visited Internet Link",
1447 "Emphasis", "Emphasis",
1448 "Document Map", "",
1449 "Plain Text", "",
1450 "NoList", "No List",
1451 "AbstractHeading", "Abstract Heading",
1452 "AbstractBody", "Abstract Body",
1453 "PageNumber", "page number"
1454 "TableNormal", "Normal Table",
1455 "DocumentMap", "Document Map"
1459 OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExtendedSearch)
1461 OUString sRet( rWWName );
1462 if( bExtendedSearch )
1464 //search for the rWWName in the IdentifierD of the existing styles and convert the sStyleName member
1465 std::vector< StyleSheetEntryPtr >::iterator aIt = m_pImpl->m_aStyleSheetEntries.begin();
1466 //TODO: performance issue - put styles list into a map sorted by it's sStyleIdentifierD members
1467 while( aIt != m_pImpl->m_aStyleSheetEntries.end() )
1469 if( rWWName == ( *aIt )->sStyleIdentifierD )
1470 sRet = ( *aIt )->sStyleName;
1471 ++aIt;
1474 if(!m_pImpl->m_aStyleNameMap.size())
1476 for( sal_uInt32 nPair = 0; nPair < sizeof(aStyleNamePairs) / sizeof( sal_Char*) / 2; ++nPair)
1478 OUString aFrom = OUString::createFromAscii(aStyleNamePairs[2 * nPair]);
1479 OUString aTo = OUString::createFromAscii(aStyleNamePairs[2 * nPair + 1]);
1480 if (!aTo.isEmpty())
1482 m_pImpl->m_aStyleNameMap.insert( StringPairMap_t::value_type(aFrom, aTo));
1483 m_pImpl->m_aReservedStyleNames.insert(aTo);
1487 StringPairMap_t::iterator aIt = m_pImpl->m_aStyleNameMap.find( sRet );
1488 bool bConverted = false;
1489 if (aIt != m_pImpl->m_aStyleNameMap.end())
1491 bConverted = true;
1492 sRet = aIt->second;
1495 if (!bConverted)
1497 // SwStyleNameMapper doc says: If the UI style name equals a
1498 // programmatic name, then it must append " (user)" to the end.
1499 std::set<OUString>::iterator aReservedIt = m_pImpl->m_aReservedStyleNames.find(sRet);
1500 if (aReservedIt != m_pImpl->m_aReservedStyleNames.end())
1501 sRet += " (user)";
1503 return sRet;
1506 void StyleSheetTable::applyDefaults(bool bParaProperties)
1508 try{
1509 if(!m_pImpl->m_xTextDefaults.is())
1511 m_pImpl->m_xTextDefaults = uno::Reference< beans::XPropertySet>(
1512 m_pImpl->m_rDMapper.GetTextFactory()->createInstance("com.sun.star.text.Defaults"),
1513 uno::UNO_QUERY_THROW );
1515 if( bParaProperties && m_pImpl->m_pDefaultParaProps.get())
1517 uno::Sequence< beans::PropertyValue > aPropValues = m_pImpl->m_pDefaultParaProps->GetPropertyValues();
1518 for( sal_Int32 i = 0; i < aPropValues.getLength(); ++i )
1522 m_pImpl->m_xTextDefaults->setPropertyValue( aPropValues[i].Name, aPropValues[i].Value );
1524 catch( const uno::Exception& )
1526 OSL_FAIL( "setPropertyValue exception");
1530 if( !bParaProperties && m_pImpl->m_pDefaultCharProps.get())
1532 uno::Sequence< beans::PropertyValue > aPropValues = m_pImpl->m_pDefaultCharProps->GetPropertyValues();
1533 for( sal_Int32 i = 0; i < aPropValues.getLength(); ++i )
1537 m_pImpl->m_xTextDefaults->setPropertyValue( aPropValues[i].Name, aPropValues[i].Value );
1539 catch( const uno::Exception& )
1541 OSL_FAIL( "setPropertyValue exception");
1546 catch( const uno::Exception& )
1552 OUString StyleSheetTable::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties )
1554 //find out if any of the styles already has the required properties then return its name
1555 OUString sListLabel = m_pImpl->HasListCharStyle(rCharProperties);
1556 if( !sListLabel.isEmpty() )
1557 return sListLabel;
1558 const char cListLabel[] = "ListLabel ";
1559 uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
1560 uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
1561 uno::Reference<container::XNameContainer> xCharStyles;
1562 xStyleFamilies->getByName("CharacterStyles") >>= xCharStyles;
1563 //search for all character styles with the name sListLabel + <index>
1564 sal_Int32 nStyleFound = 0;
1565 uno::Sequence< OUString > aStyleNames = xCharStyles->getElementNames();
1566 const OUString* pStyleNames = aStyleNames.getConstArray();
1567 for( sal_Int32 nStyle = 0; nStyle < aStyleNames.getLength(); ++nStyle )
1569 OUString sSuffix;
1570 if( pStyleNames[nStyle].startsWith( cListLabel, &sSuffix ) )
1572 sal_Int32 nSuffix = sSuffix.toInt32();
1573 if( nSuffix > 0 )
1575 if( nSuffix > nStyleFound )
1576 nStyleFound = nSuffix;
1580 sListLabel = cListLabel + OUString::number( ++nStyleFound );
1581 //create a new one otherwise
1582 uno::Reference< lang::XMultiServiceFactory > xDocFactory( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
1583 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1586 uno::Reference< style::XStyle > xStyle( xDocFactory->createInstance(
1587 rPropNameSupplier.GetName( PROP_SERVICE_CHAR_STYLE )), uno::UNO_QUERY_THROW);
1588 uno::Reference< beans::XPropertySet > xStyleProps(xStyle, uno::UNO_QUERY_THROW );
1589 PropertyValueVector_t::const_iterator aCharPropIter = rCharProperties.begin();
1590 while( aCharPropIter != rCharProperties.end())
1594 xStyleProps->setPropertyValue( aCharPropIter->Name, aCharPropIter->Value );
1596 catch( const uno::Exception& )
1598 OSL_FAIL( "Exception in StyleSheetTable::getOrCreateCharStyle - Style::setPropertyValue");
1600 ++aCharPropIter;
1602 xCharStyles->insertByName( sListLabel, uno::makeAny( xStyle) );
1603 m_pImpl->m_aListCharStylePropertyVector.push_back( ListCharStylePropertyMap_t( sListLabel, rCharProperties ));
1605 catch( const uno::Exception& )
1607 OSL_FAIL( "Exception in StyleSheetTable::getOrCreateCharStyle");
1610 return sListLabel;
1613 }//namespace dmapper
1614 }//namespace writerfilter
1616 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */