1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
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>
29 #include <com/sun/star/beans/XMultiPropertySet.hpp>
30 #include <com/sun/star/beans/XPropertyState.hpp>
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #include <com/sun/star/container/XNameContainer.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>
41 #include <osl/diagnose.h>
42 #include <rtl/ustrbuf.hxx>
43 #include <sal/log.hxx>
44 #include <comphelper/string.hxx>
45 #include <comphelper/sequence.hxx>
46 #include <tools/diagnose_ex.h>
48 using namespace ::com::sun::star
;
50 namespace writerfilter
{
54 typedef ::std::map
< OUString
, OUString
> StringPairMap_t
;
57 StyleSheetEntry::StyleSheetEntry() :
59 ,bIsDefaultStyle(false)
60 ,bInvalidHeight(false)
62 ,nStyleTypeCode(STYLE_TYPE_UNKNOWN
)
63 ,sBaseStyleIdentifier()
64 ,sNextStyleIdentifier()
65 ,pProperties(new StyleSheetPropertyMap
)
70 StyleSheetEntry::~StyleSheetEntry()
74 TableStyleSheetEntry::TableStyleSheetEntry( StyleSheetEntry
const & rEntry
):
77 bIsDefaultStyle
= rEntry
.bIsDefaultStyle
;
78 bInvalidHeight
= rEntry
.bInvalidHeight
;
79 bHasUPE
= rEntry
.bHasUPE
;
80 nStyleTypeCode
= STYLE_TYPE_TABLE
;
81 sBaseStyleIdentifier
= rEntry
.sBaseStyleIdentifier
;
82 sNextStyleIdentifier
= rEntry
.sNextStyleIdentifier
;
83 sStyleName
= rEntry
.sStyleName
;
84 sStyleIdentifierD
= rEntry
.sStyleIdentifierD
;
87 TableStyleSheetEntry::~TableStyleSheetEntry( )
91 void TableStyleSheetEntry::AddTblStylePr( TblStyleType nType
, const PropertyMapPtr
& pProps
)
93 static const int nTypesProps
= 4;
94 static const TblStyleType pTypesToFix
[nTypesProps
] =
102 static const PropertyIds pPropsToCheck
[nTypesProps
] =
110 for (int i
=0; i
< nTypesProps
; ++i
)
112 if ( nType
== pTypesToFix
[i
] )
114 PropertyIds nChecked
= pPropsToCheck
[i
];
115 boost::optional
<PropertyMap::Property
> pChecked
= pProps
->getProperty(nChecked
);
117 PropertyIds nInsideProp
= ( i
< 2 ) ? META_PROP_HORIZONTAL_BORDER
: META_PROP_VERTICAL_BORDER
;
118 boost::optional
<PropertyMap::Property
> pInside
= pProps
->getProperty(nInsideProp
);
120 if ( pChecked
&& pProps
)
122 // In this case, remove the inside border
123 pProps
->Erase( nInsideProp
);
130 // Append the tblStylePr
131 m_aStyles
[nType
] = pProps
;
134 PropertyMapPtr
TableStyleSheetEntry::GetProperties( sal_Int32 nMask
)
136 PropertyMapPtr
pProps( new PropertyMap
);
138 // And finally get the mask ones
139 pProps
->InsertProps(GetLocalPropertiesFromMask(nMask
));
144 beans::PropertyValues
StyleSheetEntry::GetInteropGrabBagSeq()
146 return comphelper::containerToSequence(m_aInteropGrabBag
);
149 beans::PropertyValue
StyleSheetEntry::GetInteropGrabBag()
151 beans::PropertyValue aRet
;
152 aRet
.Name
= sStyleIdentifierD
;
154 beans::PropertyValues aSeq
= GetInteropGrabBagSeq();
159 void StyleSheetEntry::AppendInteropGrabBag(const beans::PropertyValue
& rValue
)
161 m_aInteropGrabBag
.push_back(rValue
);
164 PropertyMapPtr
StyleSheetEntry::GetMergedInheritedProperties(const StyleSheetTablePtr
& pStyleSheetTable
)
167 if ( pStyleSheetTable
&& !sBaseStyleIdentifier
.isEmpty() && sBaseStyleIdentifier
!= sStyleIdentifierD
)
169 const StyleSheetEntryPtr pParentStyleSheet
= pStyleSheetTable
->FindStyleSheetByISTD(sBaseStyleIdentifier
);
170 if ( pParentStyleSheet
)
171 pRet
= pParentStyleSheet
->GetMergedInheritedProperties(pStyleSheetTable
);
175 pRet
= new PropertyMap
;
177 pRet
->InsertProps(pProperties
);
182 static void lcl_mergeProps( const PropertyMapPtr
& pToFill
, const PropertyMapPtr
& pToAdd
, TblStyleType nStyleId
)
184 static const PropertyIds pPropsToCheck
[] =
192 bool pRemoveInside
[] =
194 ( nStyleId
== TBL_STYLE_FIRSTROW
),
195 ( nStyleId
== TBL_STYLE_LASTROW
),
196 ( nStyleId
== TBL_STYLE_LASTCOL
),
197 ( nStyleId
== TBL_STYLE_FIRSTCOL
)
200 for ( unsigned i
= 0 ; i
!= SAL_N_ELEMENTS(pPropsToCheck
); i
++ )
202 PropertyIds nId
= pPropsToCheck
[i
];
203 boost::optional
<PropertyMap::Property
> pProp
= pToAdd
->getProperty(nId
);
207 if ( pRemoveInside
[i
] )
209 // Remove the insideH and insideV depending on the cell pos
210 PropertyIds nInsideProp
= ( i
< 2 ) ? META_PROP_HORIZONTAL_BORDER
: META_PROP_VERTICAL_BORDER
;
211 pToFill
->Erase(nInsideProp
);
216 pToFill
->InsertProps(pToAdd
);
219 PropertyMapPtr
TableStyleSheetEntry::GetLocalPropertiesFromMask( sal_Int32 nMask
)
221 // Order from right to left
222 struct TblStyleTypeAndMask
{
223 sal_Int32
const mask
;
224 TblStyleType
const type
;
227 static const TblStyleTypeAndMask aOrderedStyleTable
[] =
229 { 0x010, TBL_STYLE_BAND2HORZ
},
230 { 0x020, TBL_STYLE_BAND1HORZ
},
231 { 0x040, TBL_STYLE_BAND2VERT
},
232 { 0x080, TBL_STYLE_BAND1VERT
},
233 { 0x100, TBL_STYLE_LASTCOL
},
234 { 0x200, TBL_STYLE_FIRSTCOL
},
235 { 0x400, TBL_STYLE_LASTROW
},
236 { 0x800, TBL_STYLE_FIRSTROW
},
237 { 0x001, TBL_STYLE_SWCELL
},
238 { 0x002, TBL_STYLE_SECELL
},
239 { 0x004, TBL_STYLE_NWCELL
},
240 { 0x008, TBL_STYLE_NECELL
}
243 // Get the properties applying according to the mask
244 PropertyMapPtr
pProps( new PropertyMap( ) );
245 for (const TblStyleTypeAndMask
& i
: aOrderedStyleTable
)
247 TblStylePrs::iterator pIt
= m_aStyles
.find( i
.type
);
248 if ( ( nMask
& i
.mask
) && ( pIt
!= m_aStyles
.end( ) ) )
249 lcl_mergeProps( pProps
, pIt
->second
, i
.type
);
255 struct ListCharStylePropertyMap_t
257 OUString
const sCharStyleName
;
258 PropertyValueVector_t
const aPropertyValues
;
260 ListCharStylePropertyMap_t(const OUString
& rCharStyleName
, const PropertyValueVector_t
& rPropertyValues
):
261 sCharStyleName( rCharStyleName
),
262 aPropertyValues( rPropertyValues
)
265 typedef std::vector
< ListCharStylePropertyMap_t
> ListCharStylePropertyVector_t
;
268 struct StyleSheetTable_Impl
270 DomainMapper
& m_rDMapper
;
271 uno::Reference
< text::XTextDocument
> m_xTextDocument
;
272 uno::Reference
< beans::XPropertySet
> m_xTextDefaults
;
273 std::vector
< StyleSheetEntryPtr
> m_aStyleSheetEntries
;
274 StyleSheetEntryPtr m_pCurrentEntry
;
275 PropertyMapPtr m_pDefaultParaProps
, m_pDefaultCharProps
;
276 StringPairMap_t m_aStyleNameMap
;
277 /// Style names which should not be used without a " (user)" suffix.
278 std::set
<OUString
> m_aReservedStyleNames
;
279 OUString m_sDefaultParaStyleName
; //WW8 name
280 ListCharStylePropertyVector_t m_aListCharStylePropertyVector
;
281 bool m_bHasImportedDefaultParaProps
;
282 bool const m_bIsNewDoc
;
284 StyleSheetTable_Impl(DomainMapper
& rDMapper
, uno::Reference
< text::XTextDocument
> const& xTextDocument
, bool bIsNewDoc
);
286 OUString
HasListCharStyle( const PropertyValueVector_t
& rCharProperties
);
288 /// Appends the given key-value pair to the list of latent style properties of the current entry.
289 void AppendLatentStyleProperty(const OUString
& aName
, Value
const & rValue
);
290 /// Sets all properties of xStyle back to default.
291 static void SetPropertiesToDefault(const uno::Reference
<style::XStyle
>& xStyle
);
295 StyleSheetTable_Impl::StyleSheetTable_Impl(DomainMapper
& rDMapper
,
296 uno::Reference
< text::XTextDocument
> const& xTextDocument
,
297 bool const bIsNewDoc
)
299 m_rDMapper( rDMapper
),
300 m_xTextDocument( xTextDocument
),
302 m_pDefaultParaProps(new PropertyMap
),
303 m_pDefaultCharProps(new PropertyMap
),
304 m_sDefaultParaStyleName("Normal"),
305 m_bHasImportedDefaultParaProps(false),
306 m_bIsNewDoc(bIsNewDoc
)
308 //set font height default to 10pt
309 uno::Any aVal
= uno::makeAny( 10.0 );
310 m_pDefaultCharProps
->Insert( PROP_CHAR_HEIGHT
, aVal
);
311 m_pDefaultCharProps
->Insert( PROP_CHAR_HEIGHT_ASIAN
, aVal
);
312 m_pDefaultCharProps
->Insert( PROP_CHAR_HEIGHT_COMPLEX
, aVal
);
314 // See SwDoc::RemoveAllFormatLanguageDependencies(), internal filters
315 // disable kerning by default, do the same here.
316 m_pDefaultCharProps
->Insert(PROP_CHAR_AUTO_KERNING
, uno::Any(false));
320 OUString
StyleSheetTable_Impl::HasListCharStyle( const PropertyValueVector_t
& rPropValues
)
322 for( const auto& rListVector
: m_aListCharStylePropertyVector
)
324 const auto& rPropertyValues
= rListVector
.aPropertyValues
;
325 //if size is identical
326 if( rPropertyValues
.size() == rPropValues
.size() )
329 //then search for all contained properties
330 for( const auto& rPropVal1
: rPropValues
)
333 auto aListIter
= std::find_if(rPropertyValues
.begin(), rPropertyValues
.end(),
334 [&rPropVal1
](const css::beans::PropertyValue
& rPropVal2
) { return rPropVal2
.Name
== rPropVal1
.Name
; });
335 //set break flag if property hasn't been found
336 bBreak
= (aListIter
== rPropertyValues
.end()) || (aListIter
->Value
!= rPropVal1
.Value
);
341 return rListVector
.sCharStyleName
;
347 void StyleSheetTable_Impl::AppendLatentStyleProperty(const OUString
& aName
, Value
const & rValue
)
349 beans::PropertyValue aValue
;
351 aValue
.Value
<<= rValue
.getString();
352 m_pCurrentEntry
->aLatentStyles
.push_back(aValue
);
355 void StyleSheetTable_Impl::SetPropertiesToDefault(const uno::Reference
<style::XStyle
>& xStyle
)
357 // See if the existing style has any non-default properties. If so, reset them back to default.
358 uno::Reference
<beans::XPropertySet
> xPropertySet(xStyle
, uno::UNO_QUERY
);
359 uno::Reference
<beans::XPropertySetInfo
> xPropertySetInfo
= xPropertySet
->getPropertySetInfo();
360 uno::Sequence
<beans::Property
> aProperties
= xPropertySetInfo
->getProperties();
361 std::vector
<OUString
> aPropertyNames
;
362 aPropertyNames
.reserve(aProperties
.getLength());
363 for (sal_Int32 i
= 0; i
< aProperties
.getLength(); ++i
)
365 aPropertyNames
.push_back(aProperties
[i
].Name
);
368 uno::Reference
<beans::XPropertyState
> xPropertyState(xStyle
, uno::UNO_QUERY
);
369 uno::Sequence
<beans::PropertyState
> aStates
= xPropertyState
->getPropertyStates(comphelper::containerToSequence(aPropertyNames
));
370 for (sal_Int32 i
= 0; i
< aStates
.getLength(); ++i
)
372 if (aStates
[i
] == beans::PropertyState_DIRECT_VALUE
)
376 xPropertyState
->setPropertyToDefault(aPropertyNames
[i
]);
378 catch(const uno::Exception
& rException
)
380 SAL_INFO("writerfilter", "setPropertyToDefault(" << aPropertyNames
[i
] << ") failed: " << rException
);
386 StyleSheetTable::StyleSheetTable(DomainMapper
& rDMapper
,
387 uno::Reference
< text::XTextDocument
> const& xTextDocument
,
388 bool const bIsNewDoc
)
389 : LoggedProperties("StyleSheetTable")
390 , LoggedTable("StyleSheetTable")
391 , m_pImpl( new StyleSheetTable_Impl(rDMapper
, xTextDocument
, bIsNewDoc
) )
396 StyleSheetTable::~StyleSheetTable()
400 PropertyMapPtr
const & StyleSheetTable::GetDefaultParaProps()
402 return m_pImpl
->m_pDefaultParaProps
;
405 PropertyMapPtr
const & StyleSheetTable::GetDefaultCharProps()
407 return m_pImpl
->m_pDefaultCharProps
;
410 void StyleSheetTable::lcl_attribute(Id Name
, Value
& val
)
412 OSL_ENSURE( m_pImpl
->m_pCurrentEntry
, "current entry has to be set here");
413 if(!m_pImpl
->m_pCurrentEntry
)
415 int nIntValue
= val
.getInt();
416 OUString sValue
= val
.getString();
418 // The default type is paragraph, and it needs to be processed first,
419 // because the NS_ooxml::LN_CT_Style_type handling may set m_pImpl->m_pCurrentEntry
420 // to point to a different object.
421 if( m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_UNKNOWN
)
423 if( Name
!= NS_ooxml::LN_CT_Style_type
)
424 m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
= STYLE_TYPE_PARA
;
428 case NS_ooxml::LN_CT_Style_type
:
430 SAL_WARN_IF( m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
!= STYLE_TYPE_UNKNOWN
,
431 "writerfilter", "Style type needs to be processed first" );
432 StyleType
nType(STYLE_TYPE_UNKNOWN
);
435 case NS_ooxml::LN_Value_ST_StyleType_paragraph
:
436 nType
= STYLE_TYPE_PARA
;
438 case NS_ooxml::LN_Value_ST_StyleType_character
:
439 nType
= STYLE_TYPE_CHAR
;
441 case NS_ooxml::LN_Value_ST_StyleType_table
:
442 nType
= STYLE_TYPE_TABLE
;
444 case NS_ooxml::LN_Value_ST_StyleType_numbering
:
445 nType
= STYLE_TYPE_LIST
;
448 SAL_WARN("writerfilter", "unknown LN_CT_Style_type " << nType
);
450 case 0: // explicit unknown set by tokenizer
454 if ( nType
== STYLE_TYPE_TABLE
)
456 StyleSheetEntryPtr pEntry
= m_pImpl
->m_pCurrentEntry
;
457 tools::SvRef
<TableStyleSheetEntry
> pTableEntry( new TableStyleSheetEntry( *pEntry
.get( ) ) );
458 m_pImpl
->m_pCurrentEntry
= pTableEntry
.get();
461 m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
= nType
;
464 case NS_ooxml::LN_CT_Style_default
:
465 m_pImpl
->m_pCurrentEntry
->bIsDefaultStyle
= (nIntValue
!= 0);
467 if (m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
!= STYLE_TYPE_UNKNOWN
)
469 // "If this attribute is specified by multiple styles, then the last instance shall be used."
470 if ( m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_PARA
&& !m_pImpl
->m_pCurrentEntry
->sStyleIdentifierD
.isEmpty() )
471 m_pImpl
->m_sDefaultParaStyleName
= m_pImpl
->m_pCurrentEntry
->sStyleIdentifierD
;
473 beans::PropertyValue aValue
;
474 aValue
.Name
= "default";
475 aValue
.Value
<<= m_pImpl
->m_pCurrentEntry
->bIsDefaultStyle
;
476 m_pImpl
->m_pCurrentEntry
->AppendInteropGrabBag(aValue
);
479 case NS_ooxml::LN_CT_Style_customStyle
:
480 if (m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
!= STYLE_TYPE_UNKNOWN
)
482 beans::PropertyValue aValue
;
483 aValue
.Name
= "customStyle";
484 aValue
.Value
<<= (nIntValue
!= 0);
485 m_pImpl
->m_pCurrentEntry
->AppendInteropGrabBag(aValue
);
488 case NS_ooxml::LN_CT_Style_styleId
:
489 m_pImpl
->m_pCurrentEntry
->sStyleIdentifierD
= sValue
;
490 if(m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_TABLE
)
492 TableStyleSheetEntry
* pTableEntry
= static_cast<TableStyleSheetEntry
*>(m_pImpl
->m_pCurrentEntry
.get());
493 beans::PropertyValue aValue
;
494 aValue
.Name
= "styleId";
495 aValue
.Value
<<= sValue
;
496 pTableEntry
->AppendInteropGrabBag(aValue
);
499 case NS_ooxml::LN_CT_TblWidth_w
:
501 case NS_ooxml::LN_CT_TblWidth_type
:
503 case NS_ooxml::LN_CT_LatentStyles_defQFormat
:
504 m_pImpl
->AppendLatentStyleProperty("defQFormat", val
);
506 case NS_ooxml::LN_CT_LatentStyles_defUnhideWhenUsed
:
507 m_pImpl
->AppendLatentStyleProperty("defUnhideWhenUsed", val
);
509 case NS_ooxml::LN_CT_LatentStyles_defSemiHidden
:
510 m_pImpl
->AppendLatentStyleProperty("defSemiHidden", val
);
512 case NS_ooxml::LN_CT_LatentStyles_count
:
513 m_pImpl
->AppendLatentStyleProperty("count", val
);
515 case NS_ooxml::LN_CT_LatentStyles_defUIPriority
:
516 m_pImpl
->AppendLatentStyleProperty("defUIPriority", val
);
518 case NS_ooxml::LN_CT_LatentStyles_defLockedState
:
519 m_pImpl
->AppendLatentStyleProperty("defLockedState", val
);
523 #ifdef DEBUG_WRITERFILTER
524 TagLogger::getInstance().element("unhandled");
532 void StyleSheetTable::lcl_sprm(Sprm
& rSprm
)
534 sal_uInt32 nSprmId
= rSprm
.getId();
535 Value::Pointer_t pValue
= rSprm
.getValue();
536 sal_Int32 nIntValue
= pValue
.get() ? pValue
->getInt() : 0;
537 OUString sStringValue
= pValue
.get() ? pValue
->getString() : OUString();
541 case NS_ooxml::LN_CT_Style_name
:
542 //this is only a UI name!
543 m_pImpl
->m_pCurrentEntry
->sStyleName
= sStringValue
;
544 if(m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_TABLE
)
546 TableStyleSheetEntry
* pTableEntry
= static_cast<TableStyleSheetEntry
*>(m_pImpl
->m_pCurrentEntry
.get());
547 beans::PropertyValue aValue
;
548 aValue
.Name
= "name";
549 aValue
.Value
<<= sStringValue
;
550 pTableEntry
->AppendInteropGrabBag(aValue
);
553 case NS_ooxml::LN_CT_Style_basedOn
:
554 m_pImpl
->m_pCurrentEntry
->sBaseStyleIdentifier
= sStringValue
;
555 if(m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_TABLE
)
557 TableStyleSheetEntry
* pTableEntry
= static_cast<TableStyleSheetEntry
*>(m_pImpl
->m_pCurrentEntry
.get());
558 beans::PropertyValue aValue
;
559 aValue
.Name
= "basedOn";
560 aValue
.Value
<<= sStringValue
;
561 pTableEntry
->AppendInteropGrabBag(aValue
);
564 case NS_ooxml::LN_CT_Style_next
:
565 m_pImpl
->m_pCurrentEntry
->sNextStyleIdentifier
= sStringValue
;
567 case NS_ooxml::LN_CT_Style_aliases
:
568 case NS_ooxml::LN_CT_Style_hidden
:
569 case NS_ooxml::LN_CT_Style_personal
:
570 case NS_ooxml::LN_CT_Style_personalCompose
:
571 case NS_ooxml::LN_CT_Style_personalReply
:
573 case NS_ooxml::LN_CT_Style_autoRedefine
:
574 m_pImpl
->m_pCurrentEntry
->bAutoRedefine
= nIntValue
;
576 case NS_ooxml::LN_CT_Style_tcPr
:
578 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
579 if( pProperties
.get() && m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_TABLE
)
581 std::shared_ptr
<TblStylePrHandler
> pTblStylePrHandler(new TblStylePrHandler(m_pImpl
->m_rDMapper
));
582 pProperties
->resolve(*pTblStylePrHandler
);
583 StyleSheetEntry
* pEntry
= m_pImpl
->m_pCurrentEntry
.get();
584 TableStyleSheetEntry
& rTableEntry
= dynamic_cast<TableStyleSheetEntry
&>(*pEntry
);
585 rTableEntry
.AppendInteropGrabBag(pTblStylePrHandler
->getInteropGrabBag("tcPr"));
587 // This is a <w:tcPr> directly under <w:style>, so it affects the whole table.
588 rTableEntry
.pProperties
->InsertProps(pTblStylePrHandler
->getProperties());
592 case NS_ooxml::LN_CT_Style_trPr
:
594 case NS_ooxml::LN_CT_Style_rsid
:
595 case NS_ooxml::LN_CT_Style_qFormat
:
596 case NS_ooxml::LN_CT_Style_semiHidden
:
597 case NS_ooxml::LN_CT_Style_unhideWhenUsed
:
598 case NS_ooxml::LN_CT_Style_uiPriority
:
599 case NS_ooxml::LN_CT_Style_link
:
600 case NS_ooxml::LN_CT_Style_locked
:
601 if (m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
!= STYLE_TYPE_UNKNOWN
)
603 StyleSheetEntryPtr pEntry
= m_pImpl
->m_pCurrentEntry
;
604 beans::PropertyValue aValue
;
607 case NS_ooxml::LN_CT_Style_rsid
:
609 // We want the rsid as a hex string, but always with the length of 8.
610 OUStringBuffer aBuf
= OUString::number(nIntValue
, 16);
612 comphelper::string::padToLength(aStr
, 8 - aBuf
.getLength(), '0');
613 aStr
.append(aBuf
.getStr());
615 aValue
.Name
= "rsid";
616 aValue
.Value
<<= aStr
.makeStringAndClear();
619 case NS_ooxml::LN_CT_Style_qFormat
:
620 aValue
.Name
= "qFormat";
622 case NS_ooxml::LN_CT_Style_semiHidden
:
623 aValue
.Name
= "semiHidden";
625 case NS_ooxml::LN_CT_Style_unhideWhenUsed
:
626 aValue
.Name
= "unhideWhenUsed";
628 case NS_ooxml::LN_CT_Style_uiPriority
:
630 aValue
.Name
= "uiPriority";
631 aValue
.Value
<<= OUString::number(nIntValue
);
634 case NS_ooxml::LN_CT_Style_link
:
636 aValue
.Name
= "link";
637 aValue
.Value
<<= sStringValue
;
640 case NS_ooxml::LN_CT_Style_locked
:
641 aValue
.Name
= "locked";
644 pEntry
->AppendInteropGrabBag(aValue
);
647 case NS_ooxml::LN_CT_Style_tblPr
: //contains table properties
648 case NS_ooxml::LN_CT_Style_tblStylePr
: //contains to table properties
649 case NS_ooxml::LN_CT_TblPrBase_tblInd
: //table properties - at least width value and type
650 case NS_ooxml::LN_EG_RPrBase_rFonts
: //table fonts
652 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
653 if( pProperties
.get())
655 std::shared_ptr
<TblStylePrHandler
> pTblStylePrHandler( new TblStylePrHandler( m_pImpl
->m_rDMapper
) );
656 pProperties
->resolve( *pTblStylePrHandler
);
658 // Add the properties to the table style
659 TblStyleType nType
= pTblStylePrHandler
->getType( );
660 PropertyMapPtr pProps
= pTblStylePrHandler
->getProperties( );
661 StyleSheetEntry
* pEntry
= m_pImpl
->m_pCurrentEntry
.get();
663 TableStyleSheetEntry
* pTableEntry
= dynamic_cast<TableStyleSheetEntry
*>( pEntry
);
664 if (nType
== TBL_STYLE_UNKNOWN
)
666 pEntry
->pProperties
->InsertProps(pProps
);
670 if (pTableEntry
!= nullptr)
671 pTableEntry
->AddTblStylePr( nType
, pProps
);
674 if (nSprmId
== NS_ooxml::LN_CT_Style_tblPr
)
676 if (pTableEntry
!= nullptr)
677 pTableEntry
->AppendInteropGrabBag(pTblStylePrHandler
->getInteropGrabBag("tblPr"));
679 else if (nSprmId
== NS_ooxml::LN_CT_Style_tblStylePr
)
681 pTblStylePrHandler
->appendInteropGrabBag("type", pTblStylePrHandler
->getTypeString());
682 if (pTableEntry
!= nullptr)
683 pTableEntry
->AppendInteropGrabBag(pTblStylePrHandler
->getInteropGrabBag("tblStylePr"));
688 case NS_ooxml::LN_CT_PPrDefault_pPr
:
689 case NS_ooxml::LN_CT_DocDefaults_pPrDefault
:
690 m_pImpl
->m_rDMapper
.PushStyleSheetProperties( m_pImpl
->m_pDefaultParaProps
);
691 resolveSprmProps( m_pImpl
->m_rDMapper
, rSprm
);
692 m_pImpl
->m_rDMapper
.PopStyleSheetProperties();
693 applyDefaults( true );
694 m_pImpl
->m_bHasImportedDefaultParaProps
= true;
696 case NS_ooxml::LN_CT_RPrDefault_rPr
:
697 case NS_ooxml::LN_CT_DocDefaults_rPrDefault
:
698 m_pImpl
->m_rDMapper
.PushStyleSheetProperties( m_pImpl
->m_pDefaultCharProps
);
699 resolveSprmProps( m_pImpl
->m_rDMapper
, rSprm
);
700 m_pImpl
->m_rDMapper
.PopStyleSheetProperties();
701 applyDefaults( false );
703 case NS_ooxml::LN_CT_TblPrBase_jc
: //table alignment - row properties!
704 m_pImpl
->m_pCurrentEntry
->pProperties
->Insert( PROP_HORI_ORIENT
,
705 uno::makeAny( ConversionHelper::convertTableJustification( nIntValue
)));
707 case NS_ooxml::LN_CT_TrPrBase_jc
: //table alignment - row properties!
709 case NS_ooxml::LN_CT_TblPrBase_tblBorders
: //table borders, might be defined in table style
711 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
712 if( pProperties
.get())
714 std::shared_ptr
<BorderHandler
> pBorderHandler( new BorderHandler(m_pImpl
->m_rDMapper
.IsOOXMLImport()) );
715 pProperties
->resolve(*pBorderHandler
);
716 m_pImpl
->m_pCurrentEntry
->pProperties
->InsertProps(
717 pBorderHandler
->getProperties());
721 case NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize
:
722 case NS_ooxml::LN_CT_TblPrBase_tblStyleColBandSize
:
724 case NS_ooxml::LN_CT_TblPrBase_tblCellMar
:
725 //no cell margins in styles
727 case NS_ooxml::LN_CT_LatentStyles_lsdException
:
729 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
730 if (pProperties
.get())
732 tools::SvRef
<LatentStyleHandler
> pLatentStyleHandler(new LatentStyleHandler());
733 pProperties
->resolve(*pLatentStyleHandler
);
734 beans::PropertyValue aValue
;
735 aValue
.Name
= "lsdException";
736 aValue
.Value
<<= comphelper::containerToSequence(pLatentStyleHandler
->getAttributes());
737 m_pImpl
->m_pCurrentEntry
->aLsdExceptions
.push_back(aValue
);
741 case NS_ooxml::LN_CT_Style_pPr
:
743 case NS_ooxml::LN_CT_Style_rPr
:
747 if (!m_pImpl
->m_pCurrentEntry
)
750 tools::SvRef
<TablePropertiesHandler
> pTblHandler(new TablePropertiesHandler());
751 pTblHandler
->SetProperties( m_pImpl
->m_pCurrentEntry
->pProperties
);
752 if ( !pTblHandler
->sprm( rSprm
) )
754 m_pImpl
->m_rDMapper
.PushStyleSheetProperties( m_pImpl
->m_pCurrentEntry
->pProperties
);
756 PropertyMapPtr
pProps(new PropertyMap());
757 bool bTableStyleRunProps
= m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_TABLE
&& nSprmId
== NS_ooxml::LN_CT_Style_rPr
;
758 if (bTableStyleRunProps
)
759 m_pImpl
->m_rDMapper
.setInTableStyleRunProps(true);
760 if (m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_TABLE
)
762 if (nSprmId
== NS_ooxml::LN_CT_Style_pPr
)
763 m_pImpl
->m_rDMapper
.enableInteropGrabBag("pPr");
764 else if (nSprmId
== NS_ooxml::LN_CT_Style_rPr
)
765 m_pImpl
->m_rDMapper
.enableInteropGrabBag("rPr");
767 m_pImpl
->m_rDMapper
.sprmWithProps( rSprm
, pProps
);
768 if (m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_TABLE
)
770 if (nSprmId
== NS_ooxml::LN_CT_Style_pPr
|| nSprmId
== NS_ooxml::LN_CT_Style_rPr
)
772 TableStyleSheetEntry
* pTableEntry
= static_cast<TableStyleSheetEntry
*>(m_pImpl
->m_pCurrentEntry
.get());
773 pTableEntry
->AppendInteropGrabBag(m_pImpl
->m_rDMapper
.getInteropGrabBag());
776 if (bTableStyleRunProps
)
777 m_pImpl
->m_rDMapper
.setInTableStyleRunProps(false);
779 m_pImpl
->m_pCurrentEntry
->pProperties
->InsertProps(pProps
);
781 m_pImpl
->m_rDMapper
.PopStyleSheetProperties( );
783 if (m_pImpl
->m_pCurrentEntry
->nStyleTypeCode
== STYLE_TYPE_PARA
&& m_pImpl
->m_pCurrentEntry
->bIsDefaultStyle
)
785 // The current style is the default paragraph style.
786 PropertyMapPtr pProperties
= m_pImpl
->m_pCurrentEntry
->pProperties
;
787 if (pProperties
->isSet(PROP_CHAR_HEIGHT
) && !m_pImpl
->m_pDefaultParaProps
->isSet(PROP_CHAR_HEIGHT
))
789 // We provide a character height value, but a document-level default wasn't set.
790 if (m_pImpl
->m_xTextDefaults
.is())
792 m_pImpl
->m_xTextDefaults
->setPropertyValue("CharHeight", pProperties
->getProperty(PROP_CHAR_HEIGHT
)->second
);
803 void StyleSheetTable::lcl_entry(int /*pos*/, writerfilter::Reference
<Properties
>::Pointer_t ref
)
805 //create a new style entry
806 OSL_ENSURE( !m_pImpl
->m_pCurrentEntry
, "current entry has to be NULL here");
807 StyleSheetEntryPtr
pNewEntry( new StyleSheetEntry
);
808 m_pImpl
->m_pCurrentEntry
= pNewEntry
;
809 m_pImpl
->m_rDMapper
.PushStyleSheetProperties( m_pImpl
->m_pCurrentEntry
->pProperties
);
811 //append it to the table
812 m_pImpl
->m_rDMapper
.PopStyleSheetProperties();
813 if( !m_pImpl
->m_rDMapper
.IsOOXMLImport() || !m_pImpl
->m_pCurrentEntry
->sStyleName
.isEmpty())
815 m_pImpl
->m_pCurrentEntry
->sConvertedStyleName
= ConvertStyleName( m_pImpl
->m_pCurrentEntry
->sStyleName
);
816 m_pImpl
->m_aStyleSheetEntries
.push_back( m_pImpl
->m_pCurrentEntry
);
820 //TODO: this entry contains the default settings - they have to be added to the settings
823 if (!m_pImpl
->m_pCurrentEntry
->aLatentStyles
.empty())
825 // We have latent styles for this entry, then process them.
826 std::vector
<beans::PropertyValue
>& rLatentStyles
= m_pImpl
->m_pCurrentEntry
->aLatentStyles
;
828 if (!m_pImpl
->m_pCurrentEntry
->aLsdExceptions
.empty())
830 std::vector
<beans::PropertyValue
>& rLsdExceptions
= m_pImpl
->m_pCurrentEntry
->aLsdExceptions
;
831 beans::PropertyValue aValue
;
832 aValue
.Name
= "lsdExceptions";
833 aValue
.Value
<<= comphelper::containerToSequence(rLsdExceptions
);
834 rLatentStyles
.push_back(aValue
);
837 uno::Sequence
<beans::PropertyValue
> aLatentStyles( comphelper::containerToSequence(rLatentStyles
) );
839 // We can put all latent style info directly to the document interop
840 // grab bag, as we can be sure that only a single style entry has
841 // latent style info.
842 uno::Reference
<beans::XPropertySet
> xPropertySet(m_pImpl
->m_xTextDocument
, uno::UNO_QUERY
);
843 auto aGrabBag
= comphelper::sequenceToContainer
< std::vector
<beans::PropertyValue
> >(xPropertySet
->getPropertyValue("InteropGrabBag").get
< uno::Sequence
<beans::PropertyValue
> >());
844 beans::PropertyValue aValue
;
845 aValue
.Name
= "latentStyles";
846 aValue
.Value
<<= aLatentStyles
;
847 aGrabBag
.push_back(aValue
);
848 xPropertySet
->setPropertyValue("InteropGrabBag", uno::makeAny(comphelper::containerToSequence(aGrabBag
)));
851 StyleSheetEntryPtr pEmptyEntry
;
852 m_pImpl
->m_pCurrentEntry
= pEmptyEntry
;
854 /*-------------------------------------------------------------------------
856 -----------------------------------------------------------------------*/
859 std::vector
<beans::PropertyValue
> m_aValues
;
863 void Insert(const beans::PropertyValue
& rVal
);
864 uno::Sequence
< uno::Any
> getValues();
865 uno::Sequence
< OUString
> getNames();
868 void PropValVector::Insert(const beans::PropertyValue
& rVal
)
870 auto aIt
= std::find_if(m_aValues
.begin(), m_aValues
.end(),
871 [&rVal
](beans::PropertyValue
& rPropVal
) { return rPropVal
.Name
> rVal
.Name
; });
872 if (aIt
!= m_aValues
.end())
874 m_aValues
.insert( aIt
, rVal
);
877 m_aValues
.push_back(rVal
);
880 uno::Sequence
< uno::Any
> PropValVector::getValues()
882 std::vector
<uno::Any
> aRet
;
883 std::transform(m_aValues
.begin(), m_aValues
.end(), std::back_inserter(aRet
), [](const beans::PropertyValue
& rValue
) { return rValue
.Value
; });
884 return comphelper::containerToSequence(aRet
);
887 uno::Sequence
< OUString
> PropValVector::getNames()
889 std::vector
<OUString
> aRet
;
890 std::transform(m_aValues
.begin(), m_aValues
.end(), std::back_inserter(aRet
), [](const beans::PropertyValue
& rValue
) { return rValue
.Name
; });
891 return comphelper::containerToSequence(aRet
);
894 void StyleSheetTable::ApplyStyleSheets( const FontTablePtr
& rFontTable
)
898 uno::Reference
< style::XStyleFamiliesSupplier
> xStylesSupplier( m_pImpl
->m_xTextDocument
, uno::UNO_QUERY_THROW
);
899 uno::Reference
< lang::XMultiServiceFactory
> xDocFactory( m_pImpl
->m_xTextDocument
, uno::UNO_QUERY_THROW
);
900 uno::Reference
< container::XNameAccess
> xStyleFamilies
= xStylesSupplier
->getStyleFamilies();
901 uno::Reference
<container::XNameContainer
> xCharStyles
;
902 uno::Reference
<container::XNameContainer
> xParaStyles
;
903 uno::Reference
<container::XNameContainer
> xNumberingStyles
;
905 xStyleFamilies
->getByName(getPropertyName( PROP_CHARACTER_STYLES
)) >>= xCharStyles
;
906 xStyleFamilies
->getByName(getPropertyName( PROP_PARAGRAPH_STYLES
)) >>= xParaStyles
;
907 xStyleFamilies
->getByName("NumberingStyles") >>= xNumberingStyles
;
908 if(xCharStyles
.is() && xParaStyles
.is())
910 std::vector
< ::std::pair
<OUString
, uno::Reference
<style::XStyle
>> > aMissingParent
;
911 std::vector
< ::std::pair
<OUString
, uno::Reference
<style::XStyle
>> > aMissingFollow
;
912 std::vector
<beans::PropertyValue
> aTableStylesVec
;
913 for( auto& pEntry
: m_pImpl
->m_aStyleSheetEntries
)
915 if( pEntry
->nStyleTypeCode
== STYLE_TYPE_CHAR
|| pEntry
->nStyleTypeCode
== STYLE_TYPE_PARA
|| pEntry
->nStyleTypeCode
== STYLE_TYPE_LIST
)
917 bool bParaStyle
= pEntry
->nStyleTypeCode
== STYLE_TYPE_PARA
;
918 bool bListStyle
= pEntry
->nStyleTypeCode
== STYLE_TYPE_LIST
;
919 bool bInsert
= false;
920 uno::Reference
< container::XNameContainer
> xStyles
= bParaStyle
? xParaStyles
: (bListStyle
? xNumberingStyles
: xCharStyles
);
921 uno::Reference
< style::XStyle
> xStyle
;
922 const OUString sConvertedStyleName
= ConvertStyleName( pEntry
->sStyleName
);
924 if(xStyles
->hasByName( sConvertedStyleName
))
926 // When pasting, don't update existing styles.
927 if (!m_pImpl
->m_bIsNewDoc
)
931 xStyles
->getByName( sConvertedStyleName
) >>= xStyle
;
934 StyleSheetTable_Impl::SetPropertiesToDefault(xStyle
);
936 // resolve import conflicts with built-in styles (only if defaults have been defined)
937 if ( m_pImpl
->m_bHasImportedDefaultParaProps
938 && pEntry
->sBaseStyleIdentifier
.isEmpty() //imported style has no inheritance
939 && !xStyle
->getParentStyle().isEmpty() ) //built-in style has a default inheritance
941 xStyle
->setParentStyle( "" );
948 xStyle
.set(xDocFactory
->createInstance(
950 getPropertyName( PROP_SERVICE_PARA_STYLE
) :
951 (bListStyle
? OUString("com.sun.star.style.NumberingStyle") : getPropertyName( PROP_SERVICE_CHAR_STYLE
))),
952 uno::UNO_QUERY_THROW
);
954 // Numbering styles have to be inserted early, as e.g. the NumberingRules property is only available after insertion.
957 xStyles
->insertByName( sConvertedStyleName
, uno::makeAny( xStyle
) );
958 xStyle
.set(xStyles
->getByName(sConvertedStyleName
), uno::UNO_QUERY_THROW
);
960 StyleSheetPropertyMap
* pPropertyMap
= dynamic_cast<StyleSheetPropertyMap
*>(pEntry
->pProperties
.get());
961 if (pPropertyMap
&& pPropertyMap
->GetListId() == -1)
963 // No properties? Word default is 'none', Writer one is 'arabic', handle this.
964 uno::Reference
<beans::XPropertySet
> xPropertySet(xStyle
, uno::UNO_QUERY_THROW
);
965 uno::Reference
<container::XIndexReplace
> xNumberingRules
;
966 xPropertySet
->getPropertyValue("NumberingRules") >>= xNumberingRules
;
967 uno::Reference
<container::XIndexAccess
> xIndexAccess(xNumberingRules
, uno::UNO_QUERY_THROW
);
968 for (sal_Int32 i
= 0; i
< xIndexAccess
->getCount(); ++i
)
970 uno::Sequence
< beans::PropertyValue
> aLvlProps(1);
971 aLvlProps
[0].Name
= "NumberingType";
972 aLvlProps
[0].Value
<<= style::NumberingType::NUMBER_NONE
;
973 xNumberingRules
->replaceByIndex(i
, uno::makeAny(aLvlProps
));
974 xPropertySet
->setPropertyValue("NumberingRules", uno::makeAny(xNumberingRules
));
979 if( !pEntry
->sBaseStyleIdentifier
.isEmpty() )
983 //TODO: Handle cases where a paragraph <> character style relation is needed
984 StyleSheetEntryPtr pParent
= FindStyleSheetByISTD( pEntry
->sBaseStyleIdentifier
);
985 // Writer core doesn't support numbering styles having a parent style, it seems
986 if (pParent
.get() != nullptr && !bListStyle
)
988 const OUString sParentStyleName
= ConvertStyleName( pParent
->sStyleName
);
989 if ( !sParentStyleName
.isEmpty() && !xStyles
->hasByName( sParentStyleName
) )
990 aMissingParent
.emplace_back( sParentStyleName
, xStyle
);
992 xStyle
->setParentStyle( sParentStyleName
);
995 catch( const uno::RuntimeException
& )
997 OSL_FAIL( "Styles parent could not be set");
1000 else if( bParaStyle
)
1002 // Paragraph styles that don't inherit from some parent need to apply the DocDefaults
1003 pEntry
->pProperties
->InsertProps( m_pImpl
->m_pDefaultParaProps
, /*bAllowOverwrite=*/false );
1005 //now it's time to set the default parameters - for paragraph styles
1006 //Fonts: Western first entry in font table
1008 //CTL: third entry, if it exists
1010 sal_uInt32 nFontCount
= rFontTable
->size();
1011 if( !m_pImpl
->m_rDMapper
.IsOOXMLImport() && nFontCount
> 2 )
1013 uno::Any aTwoHundredFortyTwip
= uno::makeAny(12.);
1015 // font size to 240 twip (12 pts) for all if not set
1016 pEntry
->pProperties
->Insert(PROP_CHAR_HEIGHT
, aTwoHundredFortyTwip
, false);
1018 // western font not already set -> apply first font
1019 const FontEntry::Pointer_t
pWesternFontEntry(rFontTable
->getFontEntry( 0 ));
1020 OUString sWesternFontName
= pWesternFontEntry
->sFontName
;
1021 pEntry
->pProperties
->Insert(PROP_CHAR_FONT_NAME
, uno::makeAny( sWesternFontName
), false);
1023 // CJK ... apply second font
1024 const FontEntry::Pointer_t
pCJKFontEntry(rFontTable
->getFontEntry( 2 ));
1025 pEntry
->pProperties
->Insert(PROP_CHAR_FONT_NAME_ASIAN
, uno::makeAny( pCJKFontEntry
->sFontName
), false);
1026 pEntry
->pProperties
->Insert(PROP_CHAR_HEIGHT_ASIAN
, aTwoHundredFortyTwip
, false);
1028 // CTL ... apply third font, if available
1029 if( nFontCount
> 3 )
1031 const FontEntry::Pointer_t
pCTLFontEntry(rFontTable
->getFontEntry( 3 ));
1032 pEntry
->pProperties
->Insert(PROP_CHAR_FONT_NAME_COMPLEX
, uno::makeAny( pCTLFontEntry
->sFontName
), false);
1033 pEntry
->pProperties
->Insert(PROP_CHAR_HEIGHT_COMPLEX
, aTwoHundredFortyTwip
, false);
1038 auto aPropValues
= comphelper::sequenceToContainer
< std::vector
<beans::PropertyValue
> >(pEntry
->pProperties
->GetPropertyValues());
1040 // remove Left/RightMargin values from TOX heading styles
1043 // delay adding FollowStyle property: all styles need to be created first
1044 if ( !pEntry
->sNextStyleIdentifier
.isEmpty() )
1046 StyleSheetEntryPtr pFollowStyle
= FindStyleSheetByISTD( pEntry
->sNextStyleIdentifier
);
1047 if ( pFollowStyle
&& !pFollowStyle
->sStyleName
.isEmpty() )
1048 aMissingFollow
.emplace_back( ConvertStyleName( pFollowStyle
->sStyleName
), xStyle
);
1051 // Set the outline levels
1052 const StyleSheetPropertyMap
* pStyleSheetProperties
= dynamic_cast<const StyleSheetPropertyMap
*>(pEntry
? pEntry
->pProperties
.get() : nullptr);
1053 if ( pStyleSheetProperties
)
1055 beans::PropertyValue
aLvlVal( getPropertyName( PROP_OUTLINE_LEVEL
), 0,
1056 uno::makeAny( sal_Int16( pStyleSheetProperties
->GetOutlineLevel( ) + 1 ) ),
1057 beans::PropertyState_DIRECT_VALUE
);
1058 aPropValues
.push_back(aLvlVal
);
1061 uno::Reference
< beans::XPropertyState
>xState( xStyle
, uno::UNO_QUERY_THROW
);
1062 if( sConvertedStyleName
== "Contents Heading" ||
1063 sConvertedStyleName
== "User Index Heading" ||
1064 sConvertedStyleName
== "Index Heading" )
1066 //left margin is set to NULL by default
1067 uno::Reference
< beans::XPropertyState
>xState1( xStyle
, uno::UNO_QUERY_THROW
);
1068 xState1
->setPropertyToDefault(getPropertyName( PROP_PARA_LEFT_MARGIN
));
1070 else if ( sConvertedStyleName
== "Text body" )
1071 xState
->setPropertyToDefault(getPropertyName( PROP_PARA_BOTTOM_MARGIN
));
1072 else if( sConvertedStyleName
== "Heading 1" ||
1073 sConvertedStyleName
== "Heading 2" ||
1074 sConvertedStyleName
== "Heading 3" ||
1075 sConvertedStyleName
== "Heading 4" ||
1076 sConvertedStyleName
== "Heading 5" ||
1077 sConvertedStyleName
== "Heading 6" ||
1078 sConvertedStyleName
== "Heading 7" ||
1079 sConvertedStyleName
== "Heading 8" ||
1080 sConvertedStyleName
== "Heading 9" )
1082 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT
));
1083 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT_ASIAN
));
1084 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT_COMPLEX
));
1085 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE
));
1086 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE_ASIAN
));
1087 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE_COMPLEX
));
1088 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT
));
1089 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT_ASIAN
));
1090 xState
->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT_COMPLEX
));
1095 if ( !aPropValues
.empty() )
1097 PropValVector aSortedPropVals
;
1098 for (const beans::PropertyValue
& rValue
: aPropValues
)
1100 // Don't add the style name properties
1101 bool bIsParaStyleName
= rValue
.Name
== "ParaStyleName";
1102 bool bIsCharStyleName
= rValue
.Name
== "CharStyleName";
1103 if ( !bIsParaStyleName
&& !bIsCharStyleName
)
1105 aSortedPropVals
.Insert(rValue
);
1111 uno::Reference
< beans::XMultiPropertySet
> xMultiPropertySet( xStyle
, uno::UNO_QUERY_THROW
);
1112 xMultiPropertySet
->setPropertyValues( aSortedPropVals
.getNames(), aSortedPropVals
.getValues() );
1114 // Duplicate MSWord's single footnote reference into Footnote Characters and Footnote anchor
1115 if( pEntry
->sStyleName
.equalsIgnoreAsciiCase("footnote reference")
1116 || pEntry
->sStyleName
.equalsIgnoreAsciiCase("endnote reference") )
1118 uno::Reference
< style::XStyle
> xCopyStyle
;
1119 if( pEntry
->sStyleName
.equalsIgnoreAsciiCase("footnote reference") )
1120 xStyles
->getByName( "Footnote anchor" ) >>= xCopyStyle
;
1122 xStyles
->getByName( "Endnote anchor" ) >>= xCopyStyle
;
1124 xMultiPropertySet
.set( xCopyStyle
, uno::UNO_QUERY_THROW
);
1125 xMultiPropertySet
->setPropertyValues( aSortedPropVals
.getNames(), aSortedPropVals
.getValues() );
1128 catch( const lang::WrappedTargetException
& rWrapped
)
1130 #ifdef DEBUG_WRITERFILTER
1131 OUString
aMessage("StyleSheetTable::ApplyStyleSheets: Some style properties could not be set");
1132 beans::UnknownPropertyException aUnknownPropertyException
;
1134 if (rWrapped
.TargetException
>>= aUnknownPropertyException
)
1135 aMessage
+= ": " + aUnknownPropertyException
.Message
;
1137 SAL_WARN("writerfilter", aMessage
);
1142 catch( const uno::Exception
& )
1144 OSL_FAIL( "Some style properties could not be set");
1147 // Numbering style got inserted earlier.
1148 if(bInsert
&& !bListStyle
)
1150 const OUString sParentStyle
= xStyle
->getParentStyle();
1151 if( !sParentStyle
.isEmpty() && !xStyles
->hasByName( sParentStyle
) )
1152 aMissingParent
.emplace_back( sParentStyle
, xStyle
);
1154 xStyles
->insertByName( sConvertedStyleName
, uno::makeAny( xStyle
) );
1157 beans::PropertyValues aGrabBag
= pEntry
->GetInteropGrabBagSeq();
1158 uno::Reference
<beans::XPropertySet
> xPropertySet(xStyle
, uno::UNO_QUERY
);
1159 if (aGrabBag
.hasElements())
1161 xPropertySet
->setPropertyValue("StyleInteropGrabBag", uno::makeAny(aGrabBag
));
1164 // Only paragraph styles support automatic updates.
1165 if (pEntry
->bAutoRedefine
&& bParaStyle
)
1166 xPropertySet
->setPropertyValue("IsAutoUpdate", uno::makeAny(true));
1168 else if(pEntry
->nStyleTypeCode
== STYLE_TYPE_TABLE
)
1170 // If this is a table style, save its contents as-is for roundtrip purposes.
1171 TableStyleSheetEntry
* pTableEntry
= static_cast<TableStyleSheetEntry
*>(pEntry
.get());
1172 aTableStylesVec
.push_back(pTableEntry
->GetInteropGrabBag());
1176 // Update the styles that were created before their parents or next-styles
1177 for( auto const & iter
: aMissingParent
)
1179 iter
.second
->setParentStyle( iter
.first
);
1182 for( auto const & iter
: aMissingFollow
)
1186 uno::Reference
<beans::XPropertySet
> xPropertySet(iter
.second
, uno::UNO_QUERY
);
1187 xPropertySet
->setPropertyValue( "FollowStyle", uno::makeAny(iter
.first
) );
1189 catch( uno::Exception
& ) {}
1192 if (!aTableStylesVec
.empty())
1194 // If we had any table styles, add a new document-level InteropGrabBag entry for them.
1195 uno::Reference
<beans::XPropertySet
> xPropertySet(m_pImpl
->m_xTextDocument
, uno::UNO_QUERY
);
1196 uno::Any aAny
= xPropertySet
->getPropertyValue("InteropGrabBag");
1197 auto aGrabBag
= comphelper::sequenceToContainer
< std::vector
<beans::PropertyValue
> >(aAny
.get
< uno::Sequence
<beans::PropertyValue
> >());
1198 beans::PropertyValue aValue
;
1199 aValue
.Name
= "tableStyles";
1200 aValue
.Value
<<= comphelper::containerToSequence(aTableStylesVec
);
1201 aGrabBag
.push_back(aValue
);
1202 xPropertySet
->setPropertyValue("InteropGrabBag", uno::makeAny(comphelper::containerToSequence(aGrabBag
)));
1206 catch( const uno::Exception
& )
1208 DBG_UNHANDLED_EXCEPTION("writerfilter", "Styles could not be imported completely");
1213 const StyleSheetEntryPtr
StyleSheetTable::FindStyleSheetByISTD(const OUString
& sIndex
)
1215 StyleSheetEntryPtr pRet
;
1216 for(StyleSheetEntryPtr
& rpEntry
: m_pImpl
->m_aStyleSheetEntries
)
1218 if( rpEntry
->sStyleIdentifierD
== sIndex
)
1228 const StyleSheetEntryPtr
StyleSheetTable::FindStyleSheetByConvertedStyleName(const OUString
& sIndex
)
1230 StyleSheetEntryPtr pRet
;
1231 for(StyleSheetEntryPtr
& rpEntry
: m_pImpl
->m_aStyleSheetEntries
)
1233 if( rpEntry
->sConvertedStyleName
== sIndex
)
1243 const StyleSheetEntryPtr
StyleSheetTable::FindDefaultParaStyle()
1245 return FindStyleSheetByISTD( m_pImpl
->m_sDefaultParaStyleName
);
1248 const StyleSheetEntryPtr
StyleSheetTable::GetCurrentEntry()
1250 return m_pImpl
->m_pCurrentEntry
;
1254 static const sal_Char
* const aStyleNamePairs
[] =
1256 "Normal", "Standard",
1257 "heading 1", "Heading 1",
1258 "heading 2", "Heading 2",
1259 "heading 3", "Heading 3",
1260 "heading 4", "Heading 4",
1261 "heading 5", "Heading 5",
1262 "heading 6", "Heading 6",
1263 "heading 7", "Heading 7",
1264 "heading 8", "Heading 8",
1265 "heading 9", "Heading 9",
1266 "Heading1", "Heading 1",
1267 "Heading2", "Heading 2",
1268 "Heading3", "Heading 3",
1269 "Heading4", "Heading 4",
1270 "Heading5", "Heading 5",
1271 "Heading6", "Heading 6",
1272 "Heading7", "Heading 7",
1273 "Heading8", "Heading 8",
1274 "Heading9", "Heading 9",
1275 "Heading 1", "Heading 1",
1276 "Heading 2", "Heading 2",
1277 "Heading 3", "Heading 3",
1278 "Heading 4", "Heading 4",
1279 "Heading 5", "Heading 5",
1280 "Heading 6", "Heading 6",
1281 "Heading 7", "Heading 7",
1282 "Heading 8", "Heading 8",
1283 "Heading 9", "Heading 9",
1284 "Index 1", "Index 1",
1285 "Index 2", "Index 2",
1286 "Index 3", "Index 3",
1293 "TOC 1", "Contents 1",
1294 "TOC 2", "Contents 2",
1295 "TOC 3", "Contents 3",
1296 "TOC 4", "Contents 4",
1297 "TOC 5", "Contents 5",
1298 "TOC 6", "Contents 6",
1299 "TOC 7", "Contents 7",
1300 "TOC 8", "Contents 8",
1301 "TOC 9", "Contents 9",
1302 "TOCHeading", "Contents Heading",
1303 "toc 1", "Contents 1",
1304 "toc 2", "Contents 2",
1305 "toc 3", "Contents 3",
1306 "toc 4", "Contents 4",
1307 "toc 5", "Contents 5",
1308 "toc 6", "Contents 6",
1309 "toc 7", "Contents 7",
1310 "toc 8", "Contents 8",
1311 "toc 9", "Contents 9",
1312 "TOC1", "Contents 1",
1313 "TOC2", "Contents 2",
1314 "TOC3", "Contents 3",
1315 "TOC4", "Contents 4",
1316 "TOC5", "Contents 5",
1317 "TOC6", "Contents 6",
1318 "TOC7", "Contents 7",
1319 "TOC8", "Contents 8",
1320 "TOC9", "Contents 9",
1321 "Normal Indent", "",
1322 "footnote text", "Footnote",
1323 "Footnote Text", "Footnote",
1324 "Annotation Text", "",
1329 "Index Heading", "Index Heading",
1331 "Table of Figures", "",
1332 "Envelope Address", "Addressee",
1333 "Envelope Return", "Sender",
1334 "footnote reference", "Footnote Characters",
1335 "Footnote Reference", "Footnote Characters",
1336 "Annotation Reference", "",
1337 "Line Number", "Line numbering",
1338 "Page Number", "Page Number",
1339 "endnote reference", "Endnote Characters",
1340 "Endnote Reference", "Endnote Characters",
1341 "endnote text", "Endnote",
1342 "Endnote Text", "Endnote",
1343 "Table of Authorities", "",
1352 "List Bullet 2", "",
1353 "List Bullet 3", "",
1354 "List Bullet 4", "",
1355 "List Bullet 5", "",
1357 "List Number 2", "",
1358 "List Number 3", "",
1359 "List Number 4", "",
1360 "List Number 5", "",
1363 "Signature", "Signature",
1364 "Default Paragraph Font", "",
1365 "DefaultParagraphFont", "Default Paragraph Font",
1366 "Body Text", "Text body",
1367 "BodyText", "Text body",
1368 "BodyTextIndentItalic", "Text body indent italic",
1369 "Body Text Indent", "Text body indent",
1370 "BodyTextIndent", "Text body indent",
1371 "BodyTextIndent2", "Text body indent2",
1372 "List Continue", "",
1373 "List Continue 2", "",
1374 "List Continue 3", "",
1375 "List Continue 4", "",
1376 "List Continue 5", "",
1377 "Message Header", "",
1378 "Subtitle", "Subtitle",
1381 "Body Text First Indent", "Body Text Indent",
1382 "Body Text First Indent 2", "",
1386 "Body Text Indent 2", "",
1387 "Body Text Indent 3", "",
1389 "Hyperlink", "Internet link",
1390 "Followed Hyperlink", "Visited Internet Link",
1391 "Emphasis", "Emphasis",
1394 "NoList", "No List",
1395 "AbstractHeading", "Abstract Heading",
1396 "AbstractBody", "Abstract Body",
1397 "PageNumber", "page number"
1398 "TableNormal", "Normal Table",
1399 "DocumentMap", "Document Map"
1403 OUString
StyleSheetTable::ConvertStyleName( const OUString
& rWWName
, bool bExtendedSearch
)
1405 OUString
sRet( rWWName
);
1406 if( bExtendedSearch
)
1408 //search for the rWWName in the IdentifierD of the existing styles and convert the sStyleName member
1409 //TODO: performance issue - put styles list into a map sorted by its sStyleIdentifierD members
1410 for( const auto& rStyleSheetEntryPtr
: m_pImpl
->m_aStyleSheetEntries
)
1412 if( rWWName
== rStyleSheetEntryPtr
->sStyleIdentifierD
)
1413 sRet
= rStyleSheetEntryPtr
->sStyleName
;
1417 // create a map only once
1418 if(m_pImpl
->m_aStyleNameMap
.empty())
1420 for( size_t nPair
= 0; nPair
< SAL_N_ELEMENTS(aStyleNamePairs
)/2; ++nPair
)
1422 OUString aFrom
= OUString::createFromAscii(aStyleNamePairs
[2 * nPair
]);
1423 OUString aTo
= OUString::createFromAscii(aStyleNamePairs
[2 * nPair
+ 1]);
1426 m_pImpl
->m_aStyleNameMap
.emplace(aFrom
, aTo
);
1427 m_pImpl
->m_aReservedStyleNames
.insert(aTo
);
1432 // find style-name using map
1433 StringPairMap_t::iterator aIt
= m_pImpl
->m_aStyleNameMap
.find( sRet
);
1435 if (aIt
!= m_pImpl
->m_aStyleNameMap
.end())
1441 // SwStyleNameMapper doc says: If the UI style name equals a
1442 // programmatic name, then it must append " (user)" to the end.
1443 std::set
<OUString
>::iterator aReservedIt
= m_pImpl
->m_aReservedStyleNames
.find(sRet
);
1444 if (aReservedIt
!= m_pImpl
->m_aReservedStyleNames
.end())
1451 void StyleSheetTable::applyDefaults(bool bParaProperties
)
1455 if (!m_pImpl
->m_bIsNewDoc
)
1457 // tdf#72942: do not corrupts original styles in master document
1458 // during inserting of text from second document
1462 if(!m_pImpl
->m_xTextDefaults
.is())
1464 m_pImpl
->m_xTextDefaults
.set(
1465 m_pImpl
->m_rDMapper
.GetTextFactory()->createInstance("com.sun.star.text.Defaults"),
1466 uno::UNO_QUERY_THROW
);
1468 if( bParaProperties
&& m_pImpl
->m_pDefaultParaProps
.get())
1470 // tdf#87533 LO will have different defaults here, depending on the locale. Import with documented defaults
1471 m_pImpl
->m_pDefaultParaProps
->Insert(PROP_WRITING_MODE
, uno::makeAny(sal_Int16(text::WritingMode_LR_TB
)), /*bOverwrite=*/false);
1472 m_pImpl
->m_pDefaultParaProps
->Insert(PROP_PARA_ADJUST
, uno::makeAny(sal_Int16(style::ParagraphAdjust_LEFT
)), false);
1474 // Widow/Orphan -> set both to two if not already set
1475 uno::Any aTwo
= uno::makeAny(sal_Int8(2));
1476 m_pImpl
->m_pDefaultParaProps
->Insert(PROP_PARA_WIDOWS
, aTwo
, /*bOverwrite=*/false);
1477 m_pImpl
->m_pDefaultParaProps
->Insert(PROP_PARA_ORPHANS
, aTwo
, false);
1479 uno::Reference
<style::XStyleFamiliesSupplier
> xStylesSupplier(m_pImpl
->m_xTextDocument
, uno::UNO_QUERY
);
1480 uno::Reference
<container::XNameAccess
> xStyleFamilies
= xStylesSupplier
->getStyleFamilies();
1481 uno::Reference
<container::XNameAccess
> xParagraphStyles
;
1482 xStyleFamilies
->getByName("ParagraphStyles") >>= xParagraphStyles
;
1483 uno::Reference
<beans::XPropertySet
> xDefault
;
1484 // This is the built-in default style that every style inherits from
1485 xParagraphStyles
->getByName("Paragraph style") >>= xDefault
;
1487 uno::Sequence
< beans::PropertyValue
> aPropValues
= m_pImpl
->m_pDefaultParaProps
->GetPropertyValues();
1488 for( sal_Int32 i
= 0; i
< aPropValues
.getLength(); ++i
)
1492 xDefault
->setPropertyValue(aPropValues
[i
].Name
, aPropValues
[i
].Value
);
1494 catch( const uno::Exception
& )
1496 OSL_FAIL( "setPropertyValue exception");
1500 if( !bParaProperties
&& m_pImpl
->m_pDefaultCharProps
.get())
1502 uno::Sequence
< beans::PropertyValue
> aPropValues
= m_pImpl
->m_pDefaultCharProps
->GetPropertyValues();
1503 for( sal_Int32 i
= 0; i
< aPropValues
.getLength(); ++i
)
1507 m_pImpl
->m_xTextDefaults
->setPropertyValue( aPropValues
[i
].Name
, aPropValues
[i
].Value
);
1509 catch( const uno::Exception
& )
1511 OSL_FAIL( "setPropertyValue exception");
1516 catch( const uno::Exception
& )
1522 OUString
StyleSheetTable::getOrCreateCharStyle( PropertyValueVector_t
& rCharProperties
, bool bAlwaysCreate
)
1524 //find out if any of the styles already has the required properties then return its name
1525 OUString sListLabel
= m_pImpl
->HasListCharStyle(rCharProperties
);
1526 // Don't try to reuse an existing character style if requested.
1527 if( !sListLabel
.isEmpty() && !bAlwaysCreate
)
1529 const char cListLabel
[] = "ListLabel ";
1530 uno::Reference
< style::XStyleFamiliesSupplier
> xStylesSupplier( m_pImpl
->m_xTextDocument
, uno::UNO_QUERY_THROW
);
1531 uno::Reference
< container::XNameAccess
> xStyleFamilies
= xStylesSupplier
->getStyleFamilies();
1532 uno::Reference
<container::XNameContainer
> xCharStyles
;
1533 xStyleFamilies
->getByName("CharacterStyles") >>= xCharStyles
;
1534 //search for all character styles with the name sListLabel + <index>
1535 sal_Int32 nStyleFound
= 0;
1536 uno::Sequence
< OUString
> aStyleNames
= xCharStyles
->getElementNames();
1537 const OUString
* pStyleNames
= aStyleNames
.getConstArray();
1538 for( sal_Int32 nStyle
= 0; nStyle
< aStyleNames
.getLength(); ++nStyle
)
1541 if( pStyleNames
[nStyle
].startsWith( cListLabel
, &sSuffix
) )
1543 sal_Int32 nSuffix
= sSuffix
.toInt32();
1544 if( nSuffix
> 0 && nSuffix
> nStyleFound
)
1545 nStyleFound
= nSuffix
;
1548 sListLabel
= cListLabel
+ OUString::number( ++nStyleFound
);
1549 //create a new one otherwise
1550 uno::Reference
< lang::XMultiServiceFactory
> xDocFactory( m_pImpl
->m_xTextDocument
, uno::UNO_QUERY_THROW
);
1553 uno::Reference
< style::XStyle
> xStyle( xDocFactory
->createInstance(
1554 getPropertyName( PROP_SERVICE_CHAR_STYLE
)), uno::UNO_QUERY_THROW
);
1555 uno::Reference
< beans::XPropertySet
> xStyleProps(xStyle
, uno::UNO_QUERY_THROW
);
1556 for( const auto& rCharProp
: rCharProperties
)
1560 xStyleProps
->setPropertyValue( rCharProp
.Name
, rCharProp
.Value
);
1562 catch( const uno::Exception
& )
1564 OSL_FAIL( "Exception in StyleSheetTable::getOrCreateCharStyle - Style::setPropertyValue");
1567 xCharStyles
->insertByName( sListLabel
, uno::makeAny( xStyle
) );
1568 m_pImpl
->m_aListCharStylePropertyVector
.emplace_back( sListLabel
, rCharProperties
);
1570 catch( const uno::Exception
& )
1572 OSL_FAIL( "Exception in StyleSheetTable::getOrCreateCharStyle");
1578 }//namespace dmapper
1579 }//namespace writerfilter
1581 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */