LibreOffice Module writerfilter (master) 1
StyleSheetTable.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#include "StyleSheetTable.hxx"
20#include "util.hxx"
21#include "ConversionHelper.hxx"
22#include "TblStylePrHandler.hxx"
23#include "TagLogger.hxx"
24#include "BorderHandler.hxx"
26#include <ooxml/resourceids.hxx>
27#include <utility>
28#include <vector>
29#include <iterator>
30#include <com/sun/star/beans/XMultiPropertySet.hpp>
31#include <com/sun/star/beans/XPropertyState.hpp>
32#include <com/sun/star/beans/PropertyValue.hpp>
33#include <com/sun/star/container/XEnumerationAccess.hpp>
34#include <com/sun/star/container/XNameContainer.hpp>
35#include <com/sun/star/container/XIndexReplace.hpp>
36#include <com/sun/star/lang/XServiceInfo.hpp>
37#include <com/sun/star/text/XTextDocument.hpp>
38#include <com/sun/star/text/XTextFramesSupplier.hpp>
39#include <com/sun/star/text/XTextTable.hpp>
40#include <com/sun/star/style/NumberingType.hpp>
41#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
42#include <com/sun/star/style/XStyle.hpp>
43#include <com/sun/star/style/ParagraphAdjust.hpp>
44#include <com/sun/star/text/WritingMode.hpp>
45#include <com/sun/star/lang/XMultiServiceFactory.hpp>
46#include <map>
47#include <osl/diagnose.h>
48#include <rtl/ustrbuf.hxx>
49#include <sal/log.hxx>
51#include <comphelper/string.hxx>
55
56using namespace ::com::sun::star;
57
59{
60
62 m_bIsDefaultStyle(false)
63 ,m_bAssignedAsChapterNumbering(false)
64 ,m_bInvalidHeight(false)
65 ,m_bHasUPE(false)
66 ,m_nStyleTypeCode(STYLE_TYPE_UNKNOWN)
67 ,m_pProperties(new StyleSheetPropertyMap)
68 ,m_bAutoRedefine(false)
69{
70}
71
73{
74}
75
77{
80 m_bHasUPE = rEntry.m_bHasUPE;
87}
88
90{
91}
92
94{
95 static const int nTypesProps = 4;
96 static const TblStyleType pTypesToFix[nTypesProps] =
97 {
102 };
103
104 static const PropertyIds pPropsToCheck[nTypesProps] =
105 {
110 };
111
112 for (int i=0; i < nTypesProps; ++i )
113 {
114 if ( nType == pTypesToFix[i] )
115 {
116 PropertyIds nChecked = pPropsToCheck[i];
117 std::optional<PropertyMap::Property> pChecked = pProps->getProperty(nChecked);
118
120 std::optional<PropertyMap::Property> pInside = pProps->getProperty(nInsideProp);
121
122 if ( pChecked && pInside )
123 {
124 // In this case, remove the inside border
125 pProps->Erase( nInsideProp );
126 }
127
128 break;
129 }
130 }
131
132 // Append the tblStylePr
133 m_aStyles[nType] = pProps;
134}
135
137{
138 PropertyMapPtr pProps( new PropertyMap );
139
140 // And finally get the mask ones
141 pProps->InsertProps(GetLocalPropertiesFromMask(nMask));
142
143 return pProps;
144}
145
146beans::PropertyValues StyleSheetEntry::GetInteropGrabBagSeq() const
147{
149}
150
152{
153 beans::PropertyValue aRet;
154 aRet.Name = m_sStyleIdentifierD;
155
156 beans::PropertyValues aSeq = GetInteropGrabBagSeq();
157 aRet.Value <<= aSeq;
158 return aRet;
159}
160
161void StyleSheetEntry::AppendInteropGrabBag(const beans::PropertyValue& rValue)
162{
163 m_aInteropGrabBag.push_back(rValue);
164}
165
167{
168 PropertyMapPtr pRet;
169 if ( pStyleSheetTable && !m_sBaseStyleIdentifier.isEmpty() && m_sBaseStyleIdentifier != m_sStyleIdentifierD )
170 {
171 const StyleSheetEntryPtr pParentStyleSheet = pStyleSheetTable->FindStyleSheetByISTD(m_sBaseStyleIdentifier);
172 if ( pParentStyleSheet )
173 pRet = pParentStyleSheet->GetMergedInheritedProperties(pStyleSheetTable);
174 }
175
176 if ( !pRet )
177 pRet = new PropertyMap;
178
179 pRet->InsertProps(m_pProperties.get());
180
181 return pRet;
182}
183
184static void lcl_mergeProps( const PropertyMapPtr& pToFill, const PropertyMapPtr& pToAdd, TblStyleType nStyleId )
185{
186 static const PropertyIds pPropsToCheck[] =
187 {
192 };
193
194 bool pRemoveInside[] =
195 {
196 ( nStyleId == TBL_STYLE_FIRSTROW ),
197 ( nStyleId == TBL_STYLE_LASTROW ),
198 ( nStyleId == TBL_STYLE_LASTCOL ),
199 ( nStyleId == TBL_STYLE_FIRSTCOL )
200 };
201
202 for ( unsigned i = 0 ; i != SAL_N_ELEMENTS(pPropsToCheck); i++ )
203 {
204 PropertyIds nId = pPropsToCheck[i];
205 std::optional<PropertyMap::Property> pProp = pToAdd->getProperty(nId);
206
207 if ( pProp )
208 {
209 if ( pRemoveInside[i] )
210 {
211 // Remove the insideH and insideV depending on the cell pos
213 pToFill->Erase(nInsideProp);
214 }
215 }
216 }
217
218 pToFill->InsertProps(pToAdd);
219}
220
222{
223 // Order from right to left
224 struct TblStyleTypeAndMask {
225 sal_Int32 mask;
227 };
228
229 static const TblStyleTypeAndMask aOrderedStyleTable[] =
230 {
231 { 0x010, TBL_STYLE_BAND2HORZ },
232 { 0x020, TBL_STYLE_BAND1HORZ },
233 { 0x040, TBL_STYLE_BAND2VERT },
234 { 0x080, TBL_STYLE_BAND1VERT },
235 { 0x100, TBL_STYLE_LASTCOL },
236 { 0x200, TBL_STYLE_FIRSTCOL },
237 { 0x400, TBL_STYLE_LASTROW },
238 { 0x800, TBL_STYLE_FIRSTROW },
239 { 0x001, TBL_STYLE_SWCELL },
240 { 0x002, TBL_STYLE_SECELL },
241 { 0x004, TBL_STYLE_NWCELL },
242 { 0x008, TBL_STYLE_NECELL }
243 };
244
245 // Get the properties applying according to the mask
246 PropertyMapPtr pProps( new PropertyMap( ) );
247 for (const TblStyleTypeAndMask & i : aOrderedStyleTable)
248 {
249 TblStylePrs::iterator pIt = m_aStyles.find( i.type );
250 if ( ( nMask & i.mask ) && ( pIt != m_aStyles.end( ) ) )
251 lcl_mergeProps( pProps, pIt->second, i.type );
252 }
253 return pProps;
254}
255
256namespace {
257
258struct ListCharStylePropertyMap_t
259{
262
263 ListCharStylePropertyMap_t(OUString _sCharStyleName, PropertyValueVector_t&& rPropertyValues):
264 sCharStyleName(std::move( _sCharStyleName )),
265 aPropertyValues( std::move(rPropertyValues) )
266 {}
267};
268
269}
270
272{
276 std::vector< StyleSheetEntryPtr > m_aStyleSheetEntries;
277 std::map< OUString, StyleSheetEntryPtr > m_aStyleSheetEntriesMap;
278 std::map<OUString, OUString> m_ClonedTOCStylesMap;
281 OUString m_sDefaultParaStyleName; //WW8 name
282 std::vector< ListCharStylePropertyMap_t > m_aListCharStylePropertyVector;
285
286 StyleSheetTable_Impl(DomainMapper& rDMapper, uno::Reference< text::XTextDocument> xTextDocument, bool bIsNewDoc);
287
288 OUString HasListCharStyle( const PropertyValueVector_t& rCharProperties );
289
291 void AppendLatentStyleProperty(const OUString& aName, Value const & rValue);
293 static void SetPropertiesToDefault(const uno::Reference<style::XStyle>& xStyle);
295};
296
297
300 bool const bIsNewDoc)
301 : m_rDMapper( rDMapper ),
302 m_xTextDocument(std::move( xTextDocument )),
303 m_pDefaultParaProps(new PropertyMap),
304 m_pDefaultCharProps(new PropertyMap),
305 m_sDefaultParaStyleName("Normal"),
306 m_bHasImportedDefaultParaProps(false),
307 m_bIsNewDoc(bIsNewDoc)
308{
309 //set font height default to 10pt
310 uno::Any aVal( 10.0 );
311 m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT, aVal );
314
315 // See SwDoc::RemoveAllFormatLanguageDependencies(), internal filters
316 // disable kerning by default, do the same here.
318}
319
320
322{
323 for( const auto& rListVector : m_aListCharStylePropertyVector )
324 {
325 const auto& rPropertyValues = rListVector.aPropertyValues;
326 //if size is identical
327 if( rPropertyValues.size() == rPropValues.size() )
328 {
329 bool bBreak = false;
330 //then search for all contained properties
331 for( const auto& rPropVal1 : rPropValues)
332 {
333 //find the property
334 auto aListIter = std::find_if(rPropertyValues.begin(), rPropertyValues.end(),
335 [&rPropVal1](const css::beans::PropertyValue& rPropVal2) { return rPropVal2.Name == rPropVal1.Name; });
336 //set break flag if property hasn't been found
337 bBreak = (aListIter == rPropertyValues.end()) || (aListIter->Value != rPropVal1.Value);
338 if( bBreak )
339 break;
340 }
341 if( !bBreak )
342 return rListVector.sCharStyleName;
343 }
344 }
345 return OUString();
346}
347
348void StyleSheetTable_Impl::AppendLatentStyleProperty(const OUString& aName, Value const & rValue)
349{
350 beans::PropertyValue aValue;
351 aValue.Name = aName;
352 aValue.Value <<= rValue.getString();
353 m_pCurrentEntry->m_aLatentStyles.push_back(aValue);
354}
355
357{
358 // See if the existing style has any non-default properties. If so, reset them back to default.
359 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY);
360 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
361 const uno::Sequence<beans::Property> aProperties = xPropertySetInfo->getProperties();
362 std::vector<OUString> aPropertyNames;
363 aPropertyNames.reserve(aProperties.getLength());
364 std::transform(aProperties.begin(), aProperties.end(), std::back_inserter(aPropertyNames),
365 [](const beans::Property& rProp) { return rProp.Name; });
366
367 uno::Reference<beans::XPropertyState> xPropertyState(xStyle, uno::UNO_QUERY);
368 uno::Sequence<beans::PropertyState> aStates = xPropertyState->getPropertyStates(comphelper::containerToSequence(aPropertyNames));
369 for (sal_Int32 i = 0; i < aStates.getLength(); ++i)
370 {
371 if (aStates[i] == beans::PropertyState_DIRECT_VALUE)
372 {
373 try
374 {
375 xPropertyState->setPropertyToDefault(aPropertyNames[i]);
376 }
377 catch(const uno::Exception&)
378 {
379 TOOLS_INFO_EXCEPTION("writerfilter", "setPropertyToDefault(" << aPropertyNames[i] << ") failed");
380 }
381 }
382 }
383}
384
386 uno::Reference< text::XTextDocument> const& xTextDocument,
387 bool const bIsNewDoc)
388: LoggedProperties("StyleSheetTable")
389, LoggedTable("StyleSheetTable")
390, m_pImpl( new StyleSheetTable_Impl(rDMapper, xTextDocument, bIsNewDoc) )
391{
392}
393
394
396{
397}
398
399void StyleSheetTable::SetDefaultParaProps(PropertyIds eId, const css::uno::Any& rAny)
400{
401 m_pImpl->m_pDefaultParaProps->Insert(eId, rAny, /*bOverwrite=*/false, NO_GRAB_BAG, /*bDocDefault=*/true);
402}
403
405{
406 return m_pImpl->m_pDefaultParaProps;
407}
408
410{
411 return m_pImpl->m_pDefaultCharProps;
412}
413
415{
416 OSL_ENSURE( m_pImpl->m_pCurrentEntry, "current entry has to be set here");
417 if(!m_pImpl->m_pCurrentEntry)
418 return ;
419 int nIntValue = val.getInt();
420 OUString sValue = val.getString();
421
422 // The default type is paragraph, and it needs to be processed first,
423 // because the NS_ooxml::LN_CT_Style_type handling may set m_pImpl->m_pCurrentEntry
424 // to point to a different object.
425 if( m_pImpl->m_pCurrentEntry->m_nStyleTypeCode == STYLE_TYPE_UNKNOWN )
426 {
427 if( Name != NS_ooxml::LN_CT_Style_type )
428 m_pImpl->m_pCurrentEntry->m_nStyleTypeCode = STYLE_TYPE_PARA;
429 }
430 switch(Name)
431 {
432 case NS_ooxml::LN_CT_Style_type:
433 {
434 SAL_WARN_IF( m_pImpl->m_pCurrentEntry->m_nStyleTypeCode != STYLE_TYPE_UNKNOWN,
435 "writerfilter", "Style type needs to be processed first" );
437 switch (nIntValue)
438 {
439 case NS_ooxml::LN_Value_ST_StyleType_paragraph:
441 break;
442 case NS_ooxml::LN_Value_ST_StyleType_character:
444 break;
445 case NS_ooxml::LN_Value_ST_StyleType_table:
447 break;
448 case NS_ooxml::LN_Value_ST_StyleType_numbering:
450 break;
451 default:
452 SAL_WARN("writerfilter", "unknown LN_CT_Style_type " << nType);
453 [[fallthrough]];
454 case 0: // explicit unknown set by tokenizer
455 break;
456
457 }
458 if ( nType == STYLE_TYPE_TABLE )
459 {
460 StyleSheetEntryPtr pEntry = m_pImpl->m_pCurrentEntry;
461 tools::SvRef<TableStyleSheetEntry> pTableEntry( new TableStyleSheetEntry( *pEntry ) );
462 m_pImpl->m_pCurrentEntry = pTableEntry.get();
463 }
464 else
465 m_pImpl->m_pCurrentEntry->m_nStyleTypeCode = nType;
466 }
467 break;
468 case NS_ooxml::LN_CT_Style_default:
469 m_pImpl->m_pCurrentEntry->m_bIsDefaultStyle = (nIntValue != 0);
470
471 if (m_pImpl->m_pCurrentEntry->m_nStyleTypeCode != STYLE_TYPE_UNKNOWN)
472 {
473 // "If this attribute is specified by multiple styles, then the last instance shall be used."
474 if (m_pImpl->m_pCurrentEntry->m_bIsDefaultStyle
475 && m_pImpl->m_pCurrentEntry->m_nStyleTypeCode == STYLE_TYPE_PARA
476 && !m_pImpl->m_pCurrentEntry->m_sStyleIdentifierD.isEmpty())
477 {
478 m_pImpl->m_sDefaultParaStyleName = m_pImpl->m_pCurrentEntry->m_sStyleIdentifierD;
479 }
480
481 beans::PropertyValue aValue;
482 aValue.Name = "default";
483 aValue.Value <<= m_pImpl->m_pCurrentEntry->m_bIsDefaultStyle;
484 m_pImpl->m_pCurrentEntry->AppendInteropGrabBag(aValue);
485 }
486 break;
487 case NS_ooxml::LN_CT_Style_customStyle:
488 if (m_pImpl->m_pCurrentEntry->m_nStyleTypeCode != STYLE_TYPE_UNKNOWN)
489 {
490 beans::PropertyValue aValue;
491 aValue.Name = "customStyle";
492 aValue.Value <<= (nIntValue != 0);
493 m_pImpl->m_pCurrentEntry->AppendInteropGrabBag(aValue);
494 }
495 break;
496 case NS_ooxml::LN_CT_Style_styleId:
497 m_pImpl->m_pCurrentEntry->m_sStyleIdentifierD = sValue;
498 if(m_pImpl->m_pCurrentEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
499 {
500 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get());
501 beans::PropertyValue aValue;
502 aValue.Name = "styleId";
503 aValue.Value <<= sValue;
504 pTableEntry->AppendInteropGrabBag(aValue);
505 }
506 break;
507 case NS_ooxml::LN_CT_TblWidth_w:
508 break;
509 case NS_ooxml::LN_CT_TblWidth_type:
510 break;
511 case NS_ooxml::LN_CT_LatentStyles_defQFormat:
512 m_pImpl->AppendLatentStyleProperty("defQFormat", val);
513 break;
514 case NS_ooxml::LN_CT_LatentStyles_defUnhideWhenUsed:
515 m_pImpl->AppendLatentStyleProperty("defUnhideWhenUsed", val);
516 break;
517 case NS_ooxml::LN_CT_LatentStyles_defSemiHidden:
518 m_pImpl->AppendLatentStyleProperty("defSemiHidden", val);
519 break;
520 case NS_ooxml::LN_CT_LatentStyles_count:
521 m_pImpl->AppendLatentStyleProperty("count", val);
522 break;
523 case NS_ooxml::LN_CT_LatentStyles_defUIPriority:
524 m_pImpl->AppendLatentStyleProperty("defUIPriority", val);
525 break;
526 case NS_ooxml::LN_CT_LatentStyles_defLockedState:
527 m_pImpl->AppendLatentStyleProperty("defLockedState", val);
528 break;
529 default:
530 {
531#ifdef DBG_UTIL
532 TagLogger::getInstance().element("unhandled");
533#endif
534 }
535 break;
536 }
537}
538
539
541{
542 sal_uInt32 nSprmId = rSprm.getId();
543 Value::Pointer_t pValue = rSprm.getValue();
544 sal_Int32 nIntValue = pValue ? pValue->getInt() : 0;
545 OUString sStringValue = pValue ? pValue->getString() : OUString();
546
547 switch(nSprmId)
548 {
549 case NS_ooxml::LN_CT_Style_name:
550 //this is only a UI name!
551 m_pImpl->m_pCurrentEntry->m_sStyleName = sStringValue;
552 if(m_pImpl->m_pCurrentEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
553 {
554 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get());
555 beans::PropertyValue aValue;
556 aValue.Name = "name";
557 aValue.Value <<= sStringValue;
558 pTableEntry->AppendInteropGrabBag(aValue);
559 }
560 break;
561 case NS_ooxml::LN_CT_Style_basedOn:
562 m_pImpl->m_pCurrentEntry->m_sBaseStyleIdentifier = sStringValue;
563 if(m_pImpl->m_pCurrentEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
564 {
565 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get());
566 beans::PropertyValue aValue;
567 aValue.Name = "basedOn";
568 aValue.Value <<= sStringValue;
569 pTableEntry->AppendInteropGrabBag(aValue);
570 }
571 break;
572 case NS_ooxml::LN_CT_Style_link:
573 m_pImpl->m_pCurrentEntry->m_sLinkStyleIdentifier = sStringValue;
574 break;
575 case NS_ooxml::LN_CT_Style_next:
576 m_pImpl->m_pCurrentEntry->m_sNextStyleIdentifier = sStringValue;
577 break;
578 case NS_ooxml::LN_CT_Style_aliases:
579 case NS_ooxml::LN_CT_Style_hidden:
580 case NS_ooxml::LN_CT_Style_personal:
581 case NS_ooxml::LN_CT_Style_personalCompose:
582 case NS_ooxml::LN_CT_Style_personalReply:
583 break;
584 case NS_ooxml::LN_CT_Style_autoRedefine:
585 m_pImpl->m_pCurrentEntry->m_bAutoRedefine = nIntValue;
586 break;
587 case NS_ooxml::LN_CT_Style_tcPr:
588 {
590 if( pProperties && m_pImpl->m_pCurrentEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
591 {
592 auto pTblStylePrHandler = std::make_shared<TblStylePrHandler>(m_pImpl->m_rDMapper);
593 pProperties->resolve(*pTblStylePrHandler);
594 StyleSheetEntry* pEntry = m_pImpl->m_pCurrentEntry.get();
595 TableStyleSheetEntry& rTableEntry = dynamic_cast<TableStyleSheetEntry&>(*pEntry);
596 rTableEntry.AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tcPr"));
597
598 // This is a <w:tcPr> directly under <w:style>, so it affects the whole table.
599 rTableEntry.m_pProperties->InsertProps(pTblStylePrHandler->getProperties());
600 }
601 }
602 break;
603 case NS_ooxml::LN_CT_Style_trPr:
604 break;
605 case NS_ooxml::LN_CT_Style_rsid:
606 case NS_ooxml::LN_CT_Style_qFormat:
607 case NS_ooxml::LN_CT_Style_semiHidden:
608 case NS_ooxml::LN_CT_Style_unhideWhenUsed:
609 case NS_ooxml::LN_CT_Style_uiPriority:
610 case NS_ooxml::LN_CT_Style_locked:
611 if (m_pImpl->m_pCurrentEntry->m_nStyleTypeCode != STYLE_TYPE_UNKNOWN)
612 {
613 StyleSheetEntryPtr pEntry = m_pImpl->m_pCurrentEntry;
614 beans::PropertyValue aValue;
615 switch (nSprmId)
616 {
617 case NS_ooxml::LN_CT_Style_rsid:
618 {
619 // We want the rsid as a hex string, but always with the length of 8.
620 OUStringBuffer aBuf = OUString::number(nIntValue, 16);
621 OUStringBuffer aStr;
622 comphelper::string::padToLength(aStr, 8 - aBuf.getLength(), '0');
623 aStr.append(aBuf.getStr());
624
625 aValue.Name = "rsid";
626 aValue.Value <<= aStr.makeStringAndClear();
627 }
628 break;
629 case NS_ooxml::LN_CT_Style_qFormat:
630 aValue.Name = "qFormat";
631 break;
632 case NS_ooxml::LN_CT_Style_semiHidden:
633 aValue.Name = "semiHidden";
634 break;
635 case NS_ooxml::LN_CT_Style_unhideWhenUsed:
636 aValue.Name = "unhideWhenUsed";
637 break;
638 case NS_ooxml::LN_CT_Style_uiPriority:
639 {
640 aValue.Name = "uiPriority";
641 aValue.Value <<= OUString::number(nIntValue);
642 }
643 break;
644 case NS_ooxml::LN_CT_Style_locked:
645 aValue.Name = "locked";
646 break;
647 }
648 pEntry->AppendInteropGrabBag(aValue);
649 }
650 break;
651 case NS_ooxml::LN_CT_Style_tblPr: //contains table properties
652 case NS_ooxml::LN_CT_Style_tblStylePr: //contains to table properties
653 case NS_ooxml::LN_CT_TblPrBase_tblInd: //table properties - at least width value and type
654 case NS_ooxml::LN_EG_RPrBase_rFonts: //table fonts
655 {
657 if( pProperties )
658 {
659 auto pTblStylePrHandler = std::make_shared<TblStylePrHandler>( m_pImpl->m_rDMapper );
660 pProperties->resolve( *pTblStylePrHandler );
661
662 // Add the properties to the table style
663 TblStyleType nType = pTblStylePrHandler->getType( );
664 PropertyMapPtr pProps = pTblStylePrHandler->getProperties( );
665 StyleSheetEntry * pEntry = m_pImpl->m_pCurrentEntry.get();
666
667 TableStyleSheetEntry * pTableEntry = dynamic_cast<TableStyleSheetEntry*>( pEntry );
669 {
670 pEntry->m_pProperties->InsertProps(pProps);
671 }
672 else
673 {
674 if (pTableEntry != nullptr)
675 pTableEntry->AddTblStylePr( nType, pProps );
676 }
677
678 if (nSprmId == NS_ooxml::LN_CT_Style_tblPr)
679 {
680 if (pTableEntry != nullptr)
681 pTableEntry->AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tblPr"));
682 }
683 else if (nSprmId == NS_ooxml::LN_CT_Style_tblStylePr)
684 {
685 pTblStylePrHandler->appendInteropGrabBag("type", pTblStylePrHandler->getTypeString());
686 if (pTableEntry != nullptr)
687 pTableEntry->AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tblStylePr"));
688 }
689 }
690 break;
691 }
692 case NS_ooxml::LN_CT_PPrDefault_pPr:
693 case NS_ooxml::LN_CT_DocDefaults_pPrDefault:
694 if (nSprmId == NS_ooxml::LN_CT_DocDefaults_pPrDefault)
695 m_pImpl->m_rDMapper.SetDocDefaultsImport(true);
696
697 m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pDefaultParaProps );
698 resolveSprmProps( m_pImpl->m_rDMapper, rSprm );
699 if ( nSprmId == NS_ooxml::LN_CT_DocDefaults_pPrDefault && m_pImpl->m_pDefaultParaProps &&
700 !m_pImpl->m_pDefaultParaProps->isSet( PROP_PARA_TOP_MARGIN ) )
701 {
703 }
704 m_pImpl->m_rDMapper.PopStyleSheetProperties();
705 applyDefaults( true );
706 m_pImpl->m_bHasImportedDefaultParaProps = true;
707 if (nSprmId == NS_ooxml::LN_CT_DocDefaults_pPrDefault)
708 m_pImpl->m_rDMapper.SetDocDefaultsImport(false);
709 break;
710 case NS_ooxml::LN_CT_RPrDefault_rPr:
711 case NS_ooxml::LN_CT_DocDefaults_rPrDefault:
712 if (nSprmId == NS_ooxml::LN_CT_DocDefaults_rPrDefault)
713 m_pImpl->m_rDMapper.SetDocDefaultsImport(true);
714
715 m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pDefaultCharProps );
716 resolveSprmProps( m_pImpl->m_rDMapper, rSprm );
717 m_pImpl->m_rDMapper.PopStyleSheetProperties();
718 applyDefaults( false );
719 if (nSprmId == NS_ooxml::LN_CT_DocDefaults_rPrDefault)
720 m_pImpl->m_rDMapper.SetDocDefaultsImport(false);
721 break;
722 case NS_ooxml::LN_CT_TblPrBase_jc: //table alignment - row properties!
723 m_pImpl->m_pCurrentEntry->m_pProperties->Insert( PROP_HORI_ORIENT,
725 break;
726 case NS_ooxml::LN_CT_TrPrBase_jc: //table alignment - row properties!
727 break;
728 case NS_ooxml::LN_CT_TblPrBase_tblBorders: //table borders, might be defined in table style
729 {
731 if( pProperties )
732 {
733 auto pBorderHandler = std::make_shared<BorderHandler>(m_pImpl->m_rDMapper.IsOOXMLImport());
734 pProperties->resolve(*pBorderHandler);
735 m_pImpl->m_pCurrentEntry->m_pProperties->InsertProps(
736 pBorderHandler->getProperties());
737 }
738 }
739 break;
740 case NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize:
741 case NS_ooxml::LN_CT_TblPrBase_tblStyleColBandSize:
742 break;
743 case NS_ooxml::LN_CT_TblPrBase_tblCellMar:
744 //no cell margins in styles
745 break;
746 case NS_ooxml::LN_CT_LatentStyles_lsdException:
747 {
749 if (pProperties)
750 {
751 tools::SvRef<LatentStyleHandler> pLatentStyleHandler(new LatentStyleHandler());
752 pProperties->resolve(*pLatentStyleHandler);
753 beans::PropertyValue aValue;
754 aValue.Name = "lsdException";
755 aValue.Value <<= comphelper::containerToSequence(pLatentStyleHandler->getAttributes());
756 m_pImpl->m_pCurrentEntry->m_aLsdExceptions.push_back(aValue);
757 }
758 }
759 break;
760 case NS_ooxml::LN_CT_Style_pPr:
761 // no break
762 case NS_ooxml::LN_CT_Style_rPr:
763 // no break
764 default:
765 {
766 if (!m_pImpl->m_pCurrentEntry)
767 break;
768
770 pTblHandler->SetProperties( m_pImpl->m_pCurrentEntry->m_pProperties.get() );
771 if ( !pTblHandler->sprm( rSprm ) )
772 {
773 m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pCurrentEntry->m_pProperties.get() );
774
775 PropertyMapPtr pProps(new PropertyMap());
776 if (m_pImpl->m_pCurrentEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
777 {
778 if (nSprmId == NS_ooxml::LN_CT_Style_pPr)
779 m_pImpl->m_rDMapper.enableInteropGrabBag("pPr");
780 else if (nSprmId == NS_ooxml::LN_CT_Style_rPr)
781 m_pImpl->m_rDMapper.enableInteropGrabBag("rPr");
782 }
783 m_pImpl->m_rDMapper.sprmWithProps( rSprm, pProps );
784 if (m_pImpl->m_pCurrentEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
785 {
786 if (nSprmId == NS_ooxml::LN_CT_Style_pPr || nSprmId == NS_ooxml::LN_CT_Style_rPr)
787 {
788 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get());
789 pTableEntry->AppendInteropGrabBag(m_pImpl->m_rDMapper.getInteropGrabBag());
790 }
791 }
792
793 m_pImpl->m_pCurrentEntry->m_pProperties->InsertProps(pProps);
794
795 m_pImpl->m_rDMapper.PopStyleSheetProperties( );
796 }
797 }
798 break;
799}
800}
801
802
804{
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->m_pProperties.get() );
810 ref->resolve(*this);
811 m_pImpl->m_rDMapper.ProcessDeferredStyleCharacterProperties();
812 //append it to the table
813 m_pImpl->m_rDMapper.PopStyleSheetProperties();
814 if( !m_pImpl->m_rDMapper.IsOOXMLImport() || !m_pImpl->m_pCurrentEntry->m_sStyleName.isEmpty())
815 {
816 m_pImpl->m_pCurrentEntry->m_sConvertedStyleName = ConvertStyleName( m_pImpl->m_pCurrentEntry->m_sStyleName );
817 m_pImpl->m_aStyleSheetEntries.push_back( m_pImpl->m_pCurrentEntry );
818 m_pImpl->m_aStyleSheetEntriesMap.emplace( m_pImpl->m_pCurrentEntry->m_sStyleIdentifierD, m_pImpl->m_pCurrentEntry );
819 }
820 else
821 {
822 //TODO: this entry contains the default settings - they have to be added to the settings
823 }
824
825 if (!m_pImpl->m_pCurrentEntry->m_aLatentStyles.empty())
826 {
827 // We have latent styles for this entry, then process them.
828 std::vector<beans::PropertyValue>& rLatentStyles = m_pImpl->m_pCurrentEntry->m_aLatentStyles;
829
830 if (!m_pImpl->m_pCurrentEntry->m_aLsdExceptions.empty())
831 {
832 std::vector<beans::PropertyValue>& rLsdExceptions = m_pImpl->m_pCurrentEntry->m_aLsdExceptions;
833 beans::PropertyValue aValue;
834 aValue.Name = "lsdExceptions";
835 aValue.Value <<= comphelper::containerToSequence(rLsdExceptions);
836 rLatentStyles.push_back(aValue);
837 }
838
840
841 // We can put all latent style info directly to the document interop
842 // grab bag, as we can be sure that only a single style entry has
843 // latent style info.
844 uno::Reference<beans::XPropertySet> xPropertySet(m_pImpl->m_xTextDocument, uno::UNO_QUERY);
845 auto aGrabBag = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(xPropertySet->getPropertyValue("InteropGrabBag").get< uno::Sequence<beans::PropertyValue> >());
846 beans::PropertyValue aValue;
847 aValue.Name = "latentStyles";
848 aValue.Value <<= aLatentStyles;
849 aGrabBag.push_back(aValue);
850 xPropertySet->setPropertyValue("InteropGrabBag", uno::Any(comphelper::containerToSequence(aGrabBag)));
851 }
852
853 StyleSheetEntryPtr pEmptyEntry;
854 m_pImpl->m_pCurrentEntry = pEmptyEntry;
855}
856/*-------------------------------------------------------------------------
857 sorting helper
858 -----------------------------------------------------------------------*/
859namespace {
860
861class PropValVector
862{
863 std::vector<beans::PropertyValue> m_aValues;
864public:
865 PropValVector(){}
866
867 void Insert(const beans::PropertyValue& rVal);
868 uno::Sequence< uno::Any > getValues();
869 uno::Sequence< OUString > getNames();
870 const std::vector<beans::PropertyValue>& getProperties() const { return m_aValues; };
871};
872
873}
874
875void PropValVector::Insert(const beans::PropertyValue& rVal)
876{
877 auto aIt = std::find_if(m_aValues.begin(), m_aValues.end(),
878 [&rVal](beans::PropertyValue& rPropVal) { return rPropVal.Name > rVal.Name; });
879 if (aIt != m_aValues.end())
880 {
881 m_aValues.insert( aIt, rVal );
882 return;
883 }
884 m_aValues.push_back(rVal);
885}
886
887uno::Sequence< uno::Any > PropValVector::getValues()
888{
889 std::vector<uno::Any> aRet;
890 std::transform(m_aValues.begin(), m_aValues.end(), std::back_inserter(aRet), [](const beans::PropertyValue& rValue) { return rValue.Value; });
892}
893
894uno::Sequence< OUString > PropValVector::getNames()
895{
896 std::vector<OUString> aRet;
897 std::transform(m_aValues.begin(), m_aValues.end(), std::back_inserter(aRet), [](const beans::PropertyValue& rValue) { return rValue.Name; });
899}
900
902{
903 try
904 {
905 uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
906 uno::Reference< lang::XMultiServiceFactory > xDocFactory( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
907 uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
909 xStyleFamilies->getByName(getPropertyName( PROP_PARAGRAPH_STYLES )) >>= xParaStyles;
910
911 if ( !xParaStyles.is() )
912 return;
913
914 for ( const auto& pEntry : m_pImpl->m_aStyleSheetEntries )
915 {
916 StyleSheetPropertyMap* pStyleSheetProperties = nullptr;
917 if ( pEntry->m_nStyleTypeCode == STYLE_TYPE_PARA && (pStyleSheetProperties = pEntry->m_pProperties.get()) )
918 {
919 // ListId 0 means turn off numbering - to cancel inheritance - so make sure that can be set.
920 if (pStyleSheetProperties->props().GetListId() > -1)
921 {
923 xParaStyles->getByName( ConvertStyleName(pEntry->m_sStyleName) ) >>= xStyle;
924
925 if ( !xStyle.is() )
926 break;
927
928 uno::Reference<beans::XPropertySet> xPropertySet( xStyle, uno::UNO_QUERY_THROW );
929 const OUString sNumberingStyleName = m_pImpl->m_rDMapper.GetListStyleName( pStyleSheetProperties->props().GetListId() );
930 if ( !sNumberingStyleName.isEmpty()
931 || !pStyleSheetProperties->props().GetListId() )
932 xPropertySet->setPropertyValue( getPropertyName(PROP_NUMBERING_STYLE_NAME), uno::Any(sNumberingStyleName) );
933
934 // Word 2010+ (not Word 2003, and Word 2007 is completely broken)
935 // does something rather strange. It does not allow two paragraph styles
936 // to share the same listLevel on a numbering rule.
937 // Consider this style to just be body level if already used previously.
938 m_pImpl->m_rDMapper.ValidateListLevel(pEntry->m_sStyleIdentifierD);
939 }
940 }
941 }
942 }
943 catch( const uno::Exception& )
944 {
945 DBG_UNHANDLED_EXCEPTION("writerfilter", "Failed applying numbering style name to Paragraph styles");
946 }
947}
948
949/* Counteract the destructive tendencies of LibreOffice's Chapter Numbering
950 *
951 * Any assignment to Chapter Numbering will erase the numbering-like properties of inherited styles.
952 * So go through the list of styles and any that inherit from a Chapter Numbering style
953 * should have the Outline Level reapplied.
954 */
956{
957 try
958 {
959 uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW);
960 uno::Reference< lang::XMultiServiceFactory > xDocFactory(m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW);
961 uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
963 xStyleFamilies->getByName(getPropertyName(PROP_PARAGRAPH_STYLES)) >>= xParaStyles;
964
965 if (!xParaStyles.is())
966 return;
967
968 for (const auto& pEntry : m_pImpl->m_aStyleSheetEntries)
969 {
970 if (pEntry->m_nStyleTypeCode != STYLE_TYPE_PARA || pEntry->m_sBaseStyleIdentifier.isEmpty())
971 continue;
972
973 StyleSheetEntryPtr pParent = FindStyleSheetByISTD(pEntry->m_sBaseStyleIdentifier);
974 if (!pParent || !pParent->m_bAssignedAsChapterNumbering)
975 continue;
976
978 xParaStyles->getByName(pEntry->m_sConvertedStyleName) >>= xStyle;
979 if (!xStyle.is())
980 continue;
981
982 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY_THROW);
983 const sal_Int16 nListId = pEntry->m_pProperties->props().GetListId();
984 const OUString& sParentNumberingStyleName
985 = m_pImpl->m_rDMapper.GetListStyleName(pParent->m_pProperties->props().GetListId());
986 if (nListId == -1 && !sParentNumberingStyleName.isEmpty())
987 {
988 xPropertySet->setPropertyValue(getPropertyName(PROP_NUMBERING_STYLE_NAME),
989 uno::Any(sParentNumberingStyleName));
990 }
991
992 sal_Int16 nOutlineLevel = pEntry->m_pProperties->GetOutlineLevel();
993 if (nOutlineLevel != -1)
994 continue;
995
996 nOutlineLevel = pParent->m_pProperties->GetOutlineLevel();
997 assert(nOutlineLevel >= WW_OUTLINE_MIN && nOutlineLevel < WW_OUTLINE_MAX);
998
999 // convert MS level to LO equivalent outline level
1000 ++nOutlineLevel;
1001
1002 xPropertySet->setPropertyValue(getPropertyName(PROP_OUTLINE_LEVEL), uno::Any(nOutlineLevel));
1003 }
1004 }
1005 catch( const uno::Exception& )
1006 {
1007 DBG_UNHANDLED_EXCEPTION("writerfilter", "Failed applying outlineLevel to Paragraph styles");
1008 }
1009}
1010
1012{
1013 uno::Reference<container::XEnumerationAccess> const xEA(xText, uno::UNO_QUERY_THROW);
1014 uno::Reference<container::XEnumeration> const xParaEnum(xEA->createEnumeration());
1015
1016 while (xParaEnum->hasMoreElements())
1017 {
1018 uno::Reference<lang::XServiceInfo> const xElem(xParaEnum->nextElement(), uno::UNO_QUERY_THROW);
1019 if (xElem->supportsService(u"com.sun.star.text.Paragraph"))
1020 {
1021 uno::Reference<beans::XPropertySet> const xPara(xElem, uno::UNO_QUERY_THROW);
1022 OUString styleName;
1023 if (xPara->getPropertyValue(u"ParaStyleName") >>= styleName)
1024 {
1025 auto const it(m_ClonedTOCStylesMap.find(styleName));
1026 if (it != m_ClonedTOCStylesMap.end())
1027 {
1028 xPara->setPropertyValue(u"ParaStyleName", uno::Any(it->second));
1029 }
1030 }
1031 }
1032 else if (xElem->supportsService(u"com.sun.star.text.TextTable"))
1033 {
1034 uno::Reference<text::XTextTable> const xTable(xElem, uno::UNO_QUERY_THROW);
1035 uno::Sequence<OUString> const cells(xTable->getCellNames());
1036 for (OUString const& rCell : cells)
1037 {
1038 uno::Reference<text::XText> const xCell(xTable->getCellByName(rCell), uno::UNO_QUERY_THROW);
1040 }
1041 }
1042 }
1043}
1044
1053{
1054 if (m_pImpl->m_ClonedTOCStylesMap.empty()
1055 || !m_pImpl->m_bIsNewDoc) // avoid modifying pre-existing content
1056 {
1057 return;
1058 }
1059 SAL_INFO("writerfilter.dmapper", "Applying cloned styles to make TOC work");
1060 // ignore header / footer, irrelevant for ToX
1061 // text frames
1062 uno::Reference<text::XTextFramesSupplier> const xDocTFS(m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW);
1063 uno::Reference<container::XEnumerationAccess> const xFrames(xDocTFS->getTextFrames(), uno::UNO_QUERY_THROW);
1064 uno::Reference<container::XEnumeration> const xFramesEnum(xFrames->createEnumeration());
1065 while (xFramesEnum->hasMoreElements())
1066 {
1067 uno::Reference<text::XText> const xFrame(xFramesEnum->nextElement(), uno::UNO_QUERY_THROW);
1068 m_pImpl->ApplyClonedTOCStylesToXText(xFrame);
1069 }
1070 // body
1071 uno::Reference<text::XText> const xBody(m_pImpl->m_xTextDocument->getText());
1072 m_pImpl->ApplyClonedTOCStylesToXText(xBody);
1073}
1074
1075OUString StyleSheetTable::CloneTOCStyle(FontTablePtr const& rFontTable, StyleSheetEntryPtr const pStyle, OUString const& rNewName)
1076{
1077 StyleSheetEntryPtr const pClone(new StyleSheetEntry(*pStyle));
1078 pClone->m_sStyleIdentifierD = rNewName;
1079 pClone->m_sStyleName = rNewName;
1080 pClone->m_sConvertedStyleName = ConvertStyleName(rNewName);
1081 m_pImpl->m_aStyleSheetEntries.push_back(pClone);
1082 // add it so it will be found if referenced from another TOC
1083 m_pImpl->m_aStyleSheetEntriesMap.emplace(rNewName, pClone);
1084 m_pImpl->m_ClonedTOCStylesMap.emplace(pStyle->m_sStyleName, pClone->m_sConvertedStyleName);
1085 std::vector<StyleSheetEntryPtr> const styles{ pClone };
1086 ApplyStyleSheetsImpl(rFontTable, styles);
1087 return pClone->m_sConvertedStyleName;
1088}
1089
1091{
1092 return ApplyStyleSheetsImpl(rFontTable, m_pImpl->m_aStyleSheetEntries);
1093}
1094
1095void StyleSheetTable::ApplyStyleSheetsImpl(const FontTablePtr& rFontTable, std::vector<StyleSheetEntryPtr> const& rEntries)
1096{
1097 try
1098 {
1099 uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
1100 uno::Reference< lang::XMultiServiceFactory > xDocFactory( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
1101 uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
1105
1106 xStyleFamilies->getByName(getPropertyName( PROP_CHARACTER_STYLES )) >>= xCharStyles;
1107 xStyleFamilies->getByName(getPropertyName( PROP_PARAGRAPH_STYLES )) >>= xParaStyles;
1108 xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles;
1109 if(xCharStyles.is() && xParaStyles.is())
1110 {
1111 std::vector< ::std::pair<OUString, uno::Reference<style::XStyle>> > aMissingParent;
1112 std::vector< ::std::pair<OUString, uno::Reference<style::XStyle>> > aMissingFollow;
1113 std::vector<std::pair<OUString, uno::Reference<style::XStyle>>> aMissingLink;
1114 std::vector<beans::PropertyValue> aTableStylesVec;
1115 for (auto& pEntry : rEntries)
1116 {
1117 if( pEntry->m_nStyleTypeCode == STYLE_TYPE_UNKNOWN && !pEntry->m_sStyleName.isEmpty() )
1118 pEntry->m_nStyleTypeCode = STYLE_TYPE_PARA; // unspecified style types are considered paragraph styles
1119
1120 if( pEntry->m_nStyleTypeCode == STYLE_TYPE_CHAR || pEntry->m_nStyleTypeCode == STYLE_TYPE_PARA || pEntry->m_nStyleTypeCode == STYLE_TYPE_LIST )
1121 {
1122 bool bParaStyle = pEntry->m_nStyleTypeCode == STYLE_TYPE_PARA;
1123 bool bCharStyle = pEntry->m_nStyleTypeCode == STYLE_TYPE_CHAR;
1124 bool bListStyle = pEntry->m_nStyleTypeCode == STYLE_TYPE_LIST;
1125 bool bInsert = false;
1126 uno::Reference< container::XNameContainer > xStyles = bParaStyle ? xParaStyles : (bListStyle ? xNumberingStyles : xCharStyles);
1128 const OUString sConvertedStyleName = ConvertStyleName( pEntry->m_sStyleName );
1129
1130 if(xStyles->hasByName( sConvertedStyleName ))
1131 {
1132 // When pasting, don't update existing styles.
1133 if (!m_pImpl->m_bIsNewDoc)
1134 {
1135 continue;
1136 }
1137 xStyles->getByName( sConvertedStyleName ) >>= xStyle;
1138
1139 {
1141
1142 // resolve import conflicts with built-in styles (only if defaults have been defined)
1143 if ( m_pImpl->m_bHasImportedDefaultParaProps
1144 && pEntry->m_sBaseStyleIdentifier.isEmpty() //imported style has no inheritance
1145 && !xStyle->getParentStyle().isEmpty() ) //built-in style has a default inheritance
1146 {
1147 xStyle->setParentStyle( "" );
1148 }
1149 }
1150 }
1151 else
1152 {
1153 bInsert = true;
1154 xStyle.set(xDocFactory->createInstance(
1155 bParaStyle ?
1157 (bListStyle ? OUString("com.sun.star.style.NumberingStyle") : getPropertyName( PROP_SERVICE_CHAR_STYLE ))),
1158 uno::UNO_QUERY_THROW);
1159
1160 // Numbering styles have to be inserted early, as e.g. the NumberingRules property is only available after insertion.
1161 if (bListStyle)
1162 {
1163 xStyles->insertByName( sConvertedStyleName, uno::Any( xStyle ) );
1164 xStyle.set(xStyles->getByName(sConvertedStyleName), uno::UNO_QUERY_THROW);
1165
1166 StyleSheetPropertyMap* pPropertyMap = pEntry->m_pProperties.get();
1167 if (pPropertyMap && pPropertyMap->props().GetListId() == -1)
1168 {
1169 // No properties? Word default is 'none', Writer one is 'arabic', handle this.
1170 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY_THROW);
1172 xPropertySet->getPropertyValue("NumberingRules") >>= xNumberingRules;
1173 uno::Reference<container::XIndexAccess> xIndexAccess(xNumberingRules, uno::UNO_QUERY_THROW);
1174 for (sal_Int32 i = 0; i < xIndexAccess->getCount(); ++i)
1175 {
1178 "NumberingType", style::NumberingType::NUMBER_NONE)
1179 };
1180 xNumberingRules->replaceByIndex(i, uno::Any(aLvlProps));
1181 xPropertySet->setPropertyValue("NumberingRules", uno::Any(xNumberingRules));
1182 }
1183 }
1184 }
1185 }
1186 if( !pEntry->m_sBaseStyleIdentifier.isEmpty() )
1187 {
1188 try
1189 {
1190 //TODO: Handle cases where a paragraph <> character style relation is needed
1191 StyleSheetEntryPtr pParent = FindStyleSheetByISTD( pEntry->m_sBaseStyleIdentifier );
1192 // Writer core doesn't support numbering styles having a parent style, it seems
1193 if (pParent && !bListStyle)
1194 {
1195 const OUString sParentStyleName = ConvertStyleName( pParent->m_sStyleName );
1196 if ( !sParentStyleName.isEmpty() && !xStyles->hasByName( sParentStyleName ) )
1197 aMissingParent.emplace_back( sParentStyleName, xStyle );
1198 else
1199 xStyle->setParentStyle( sParentStyleName );
1200 }
1201 }
1202 catch( const uno::RuntimeException& )
1203 {
1204 OSL_FAIL( "Styles parent could not be set");
1205 }
1206 }
1207 else if( bParaStyle )
1208 {
1209 // Paragraph styles that don't inherit from some parent need to apply the DocDefaults
1210 pEntry->m_pProperties->InsertProps( m_pImpl->m_pDefaultParaProps, /*bOverwrite=*/false );
1211
1212 //now it's time to set the default parameters - for paragraph styles
1213 //Fonts: Western first entry in font table
1214 //CJK: second entry
1215 //CTL: third entry, if it exists
1216
1217 sal_uInt32 nFontCount = rFontTable->size();
1218 if( !m_pImpl->m_rDMapper.IsOOXMLImport() && nFontCount > 2 )
1219 {
1220 uno::Any aTwoHundredFortyTwip(12.);
1221
1222 // font size to 240 twip (12 pts) for all if not set
1223 pEntry->m_pProperties->Insert(PROP_CHAR_HEIGHT, aTwoHundredFortyTwip, false);
1224
1225 // western font not already set -> apply first font
1226 const FontEntry::Pointer_t pWesternFontEntry(rFontTable->getFontEntry( 0 ));
1227 OUString sWesternFontName = pWesternFontEntry->sFontName;
1228 pEntry->m_pProperties->Insert(PROP_CHAR_FONT_NAME, uno::Any( sWesternFontName ), false);
1229
1230 // CJK ... apply second font
1231 const FontEntry::Pointer_t pCJKFontEntry(rFontTable->getFontEntry( 2 ));
1232 pEntry->m_pProperties->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::Any( pCJKFontEntry->sFontName ), false);
1233 pEntry->m_pProperties->Insert(PROP_CHAR_HEIGHT_ASIAN, aTwoHundredFortyTwip, false);
1234
1235 // CTL ... apply third font, if available
1236 if( nFontCount > 3 )
1237 {
1238 const FontEntry::Pointer_t pCTLFontEntry(rFontTable->getFontEntry( 3 ));
1239 pEntry->m_pProperties->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::Any( pCTLFontEntry->sFontName ), false);
1240 pEntry->m_pProperties->Insert(PROP_CHAR_HEIGHT_COMPLEX, aTwoHundredFortyTwip, false);
1241 }
1242 }
1243 }
1244
1245 auto aPropValues = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(pEntry->m_pProperties->GetPropertyValues());
1246
1247 if (bParaStyle || bCharStyle)
1248 {
1249 // delay adding LinkStyle property: all styles need to be created first
1250 if (!pEntry->m_sLinkStyleIdentifier.isEmpty())
1251 {
1252 StyleSheetEntryPtr pLinkStyle
1253 = FindStyleSheetByISTD(pEntry->m_sLinkStyleIdentifier);
1254 if (pLinkStyle && !pLinkStyle->m_sStyleName.isEmpty())
1255 aMissingLink.emplace_back(ConvertStyleName(pLinkStyle->m_sStyleName),
1256 xStyle);
1257 }
1258 }
1259
1260 if( bParaStyle )
1261 {
1262 // delay adding FollowStyle property: all styles need to be created first
1263 if ( !pEntry->m_sNextStyleIdentifier.isEmpty() )
1264 {
1265 StyleSheetEntryPtr pFollowStyle = FindStyleSheetByISTD( pEntry->m_sNextStyleIdentifier );
1266 if ( pFollowStyle && !pFollowStyle->m_sStyleName.isEmpty() )
1267 aMissingFollow.emplace_back( ConvertStyleName( pFollowStyle->m_sStyleName ), xStyle );
1268 }
1269
1270 // Set the outline levels
1271 StyleSheetPropertyMap* pStyleSheetProperties = pEntry ? pEntry->m_pProperties.get() : nullptr;
1272
1273 if ( pStyleSheetProperties )
1274 {
1275 sal_Int16 nLvl = pStyleSheetProperties->GetOutlineLevel();
1276 // convert MS body Level (9) to LO body level (0) and equivalent outline levels
1277 if (nLvl != -1)
1278 {
1279 if (nLvl == WW_OUTLINE_MAX)
1280 nLvl = 0;
1281 else
1282 ++nLvl;
1283
1284 beans::PropertyValue aLvlVal(getPropertyName(PROP_OUTLINE_LEVEL), 0,
1285 uno::Any(nLvl),
1286 beans::PropertyState_DIRECT_VALUE);
1287 aPropValues.push_back(aLvlVal);
1288 }
1289 }
1290
1291 uno::Reference< beans::XPropertyState >xState( xStyle, uno::UNO_QUERY_THROW );
1292 if( sConvertedStyleName == "Contents Heading" ||
1293 sConvertedStyleName == "User Index Heading" ||
1294 sConvertedStyleName == "Index Heading" )
1295 {
1296 // remove Left/RightMargin values from TOX heading styles
1297 //left margin is set to NULL by default
1298 xState->setPropertyToDefault(getPropertyName( PROP_PARA_LEFT_MARGIN ));
1299 }
1300 else if ( sConvertedStyleName == "Text body" )
1301 xState->setPropertyToDefault(getPropertyName( PROP_PARA_BOTTOM_MARGIN ));
1302 else if ( sConvertedStyleName == "Heading 1" ||
1303 sConvertedStyleName == "Heading 2" ||
1304 sConvertedStyleName == "Heading 3" ||
1305 sConvertedStyleName == "Heading 4" ||
1306 sConvertedStyleName == "Heading 5" ||
1307 sConvertedStyleName == "Heading 6" ||
1308 sConvertedStyleName == "Heading 7" ||
1309 sConvertedStyleName == "Heading 8" ||
1310 sConvertedStyleName == "Heading 9" )
1311 {
1312 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT ));
1313 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT_ASIAN ));
1314 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT_COMPLEX ));
1315 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE ));
1316 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE_ASIAN ));
1317 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE_COMPLEX ));
1318 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT ));
1319 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT_ASIAN ));
1320 xState->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT_COMPLEX));
1321
1322 }
1323 }
1324
1325 if ( !aPropValues.empty() )
1326 {
1327 PropValVector aSortedPropVals;
1328 for (const beans::PropertyValue& rValue : aPropValues)
1329 {
1330 // Don't add the style name properties
1331 bool bIsParaStyleName = rValue.Name == "ParaStyleName";
1332 bool bIsCharStyleName = rValue.Name == "CharStyleName";
1333 if ( !bIsParaStyleName && !bIsCharStyleName )
1334 {
1335 aSortedPropVals.Insert(rValue);
1336 }
1337 }
1338
1339 try
1340 {
1341 uno::Reference< beans::XMultiPropertySet > xMultiPropertySet( xStyle, uno::UNO_QUERY_THROW);
1342 try
1343 {
1344 xMultiPropertySet->setPropertyValues( aSortedPropVals.getNames(), aSortedPropVals.getValues() );
1345 }
1346 catch ( const uno::Exception& )
1347 {
1348 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY_THROW);
1349 for ( const beans::PropertyValue& rValue : aSortedPropVals.getProperties() )
1350 {
1351 try
1352 {
1353 xPropertySet->setPropertyValue( rValue.Name, rValue.Value );
1354 }
1355 catch ( const uno::Exception& )
1356 {
1357 SAL_WARN( "writerfilter", "StyleSheetTable::ApplyStyleSheets could not set property " << rValue.Name );
1358 }
1359 }
1360 }
1361 // Duplicate MSWord's single footnote reference into Footnote Characters and Footnote anchor
1362 if( pEntry->m_sStyleName.equalsIgnoreAsciiCase("footnote reference")
1363 || pEntry->m_sStyleName.equalsIgnoreAsciiCase("endnote reference") )
1364 {
1366 if( pEntry->m_sStyleName.equalsIgnoreAsciiCase("footnote reference") )
1367 xStyles->getByName( "Footnote anchor" ) >>= xCopyStyle;
1368 else
1369 xStyles->getByName( "Endnote anchor" ) >>= xCopyStyle;
1370
1371 xMultiPropertySet.set( xCopyStyle, uno::UNO_QUERY_THROW);
1372 xMultiPropertySet->setPropertyValues( aSortedPropVals.getNames(), aSortedPropVals.getValues() );
1373 }
1374 }
1375 catch( const lang::WrappedTargetException& rWrapped)
1376 {
1377#ifdef DBG_UTIL
1378 OUString aMessage("StyleSheetTable::ApplyStyleSheets: Some style properties could not be set");
1379 beans::UnknownPropertyException aUnknownPropertyException;
1380
1381 if (rWrapped.TargetException >>= aUnknownPropertyException)
1382 aMessage += ": " + aUnknownPropertyException.Message;
1383
1384 SAL_WARN("writerfilter", aMessage);
1385#else
1386 (void) rWrapped;
1387#endif
1388 }
1389 catch( const uno::Exception& )
1390 {
1391 OSL_FAIL( "Some style properties could not be set");
1392 }
1393 }
1394 // Numbering style got inserted earlier.
1395 if(bInsert && !bListStyle)
1396 {
1397 const OUString sParentStyle = xStyle->getParentStyle();
1398 if( !sParentStyle.isEmpty() && !xStyles->hasByName( sParentStyle ) )
1399 aMissingParent.emplace_back( sParentStyle, xStyle );
1400
1401 xStyles->insertByName( sConvertedStyleName, uno::Any( xStyle) );
1402 }
1403
1404 beans::PropertyValues aGrabBag = pEntry->GetInteropGrabBagSeq();
1405 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY);
1406 if (aGrabBag.hasElements())
1407 {
1408 xPropertySet->setPropertyValue("StyleInteropGrabBag", uno::Any(aGrabBag));
1409 }
1410
1411 // Only paragraph styles support automatic updates.
1412 if (pEntry->m_bAutoRedefine && bParaStyle)
1413 xPropertySet->setPropertyValue("IsAutoUpdate", uno::Any(true));
1414 }
1415 else if(pEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
1416 {
1417 // If this is a table style, save its contents as-is for roundtrip purposes.
1418 TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(pEntry.get());
1419 aTableStylesVec.push_back(pTableEntry->GetInteropGrabBag());
1420
1421 // if DocDefaults exist, MS Word includes these in the table style definition.
1422 pEntry->m_pProperties->InsertProps( m_pImpl->m_pDefaultCharProps, /*bOverwrite=*/false );
1423 pEntry->m_pProperties->InsertProps( m_pImpl->m_pDefaultParaProps, /*bOverwrite=*/false );
1424 }
1425 }
1426
1427 // Update the styles that were created before their parents or next-styles
1428 for( auto const & iter : aMissingParent )
1429 {
1430 iter.second->setParentStyle( iter.first );
1431 }
1432
1433 for( auto const & iter : aMissingFollow )
1434 {
1435 try
1436 {
1437 uno::Reference<beans::XPropertySet> xPropertySet(iter.second, uno::UNO_QUERY);
1438 xPropertySet->setPropertyValue( "FollowStyle", uno::Any(iter.first) );
1439 }
1440 catch( uno::Exception & ) {}
1441 }
1442
1443 // Update the styles that were created before their linked styles.
1444 for (auto const& rLinked : aMissingLink)
1445 {
1446 try
1447 {
1448 uno::Reference<beans::XPropertySet> xPropertySet(rLinked.second,
1449 uno::UNO_QUERY);
1450 xPropertySet->setPropertyValue("LinkStyle", uno::Any(rLinked.first));
1451 }
1452 catch (uno::Exception&)
1453 {
1455 "writerfilter",
1456 "StyleSheetTable::ApplyStyleSheets: failed to set LinkStyle");
1457 }
1458 }
1459
1460 if (!aTableStylesVec.empty())
1461 {
1462 // If we had any table styles, add a new document-level InteropGrabBag entry for them.
1463 uno::Reference<beans::XPropertySet> xPropertySet(m_pImpl->m_xTextDocument, uno::UNO_QUERY);
1464 uno::Any aAny = xPropertySet->getPropertyValue("InteropGrabBag");
1465 auto aGrabBag = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aAny.get< uno::Sequence<beans::PropertyValue> >());
1466 beans::PropertyValue aValue;
1467 aValue.Name = "tableStyles";
1468 aValue.Value <<= comphelper::containerToSequence(aTableStylesVec);
1469 aGrabBag.push_back(aValue);
1470 xPropertySet->setPropertyValue("InteropGrabBag", uno::Any(comphelper::containerToSequence(aGrabBag)));
1471 }
1472 }
1473 }
1474 catch( const uno::Exception& )
1475 {
1476 DBG_UNHANDLED_EXCEPTION("writerfilter", "Styles could not be imported completely");
1477 }
1478}
1479
1480
1482{
1483 auto findIt = m_pImpl->m_aStyleSheetEntriesMap.find(sIndex);
1484 if (findIt != m_pImpl->m_aStyleSheetEntriesMap.end())
1485 return findIt->second;
1486 return StyleSheetEntryPtr();
1487}
1488
1489
1491{
1492 StyleSheetEntryPtr pRet;
1493 for(const StyleSheetEntryPtr & rpEntry : m_pImpl->m_aStyleSheetEntries)
1494 {
1495 if( rpEntry->m_sConvertedStyleName == sIndex)
1496 {
1497 pRet = rpEntry;
1498 break;
1499 }
1500 }
1501 return pRet;
1502}
1503
1504
1506{
1507 return FindStyleSheetByISTD( m_pImpl->m_sDefaultParaStyleName );
1508}
1509
1511{
1512 return m_pImpl->m_pCurrentEntry;
1513}
1514
1515OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExtendedSearch)
1516{
1517 OUString sRet( rWWName );
1518 if( bExtendedSearch )
1519 {
1520 //search for the rWWName in the IdentifierD of the existing styles and convert the sStyleName member
1521 auto findIt = m_pImpl->m_aStyleSheetEntriesMap.find(rWWName);
1522 if (findIt != m_pImpl->m_aStyleSheetEntriesMap.end())
1523 {
1524 if (!findIt->second->m_sConvertedStyleName.isEmpty())
1525 return findIt->second->m_sConvertedStyleName;
1526 sRet = findIt->second->m_sStyleName;
1527 }
1528 }
1529
1530 // create a map only once
1531 // This maps Word's special style manes to Writer's (the opposite to what MSWordStyles::GetWWId
1532 // and ww::GetEnglishNameFromSti do on export). The mapping gives a Writer's style name, which
1533 // will point to a style with specific RES_POOL* in its m_nPoolFormatId. Then on export, the
1534 // pool format id will map to a ww::sti enum value, and finally to a Word style name. Keep this
1535 // part in sync with the export functions mentioned above!
1536 // In addition to "standard" names, some case variations are handled here; and also there are
1537 // a number of strange mappings like "BodyTextIndentItalic" -> "Text body indent italic", which
1538 // map something unused in Word to something unused in Writer :-/
1539 static const std::map< OUString, OUString> StyleNameMap {
1540 { "Normal", "Standard" }, // RES_POOLCOLL_STANDARD
1541 { "heading 1", "Heading 1" }, // RES_POOLCOLL_HEADLINE1
1542 { "heading 2", "Heading 2" }, // RES_POOLCOLL_HEADLINE2
1543 { "heading 3", "Heading 3" }, // RES_POOLCOLL_HEADLINE3
1544 { "heading 4", "Heading 4" }, // RES_POOLCOLL_HEADLINE4
1545 { "heading 5", "Heading 5" }, // RES_POOLCOLL_HEADLINE5
1546 { "heading 6", "Heading 6" }, // RES_POOLCOLL_HEADLINE6
1547 { "heading 7", "Heading 7" }, // RES_POOLCOLL_HEADLINE7
1548 { "heading 8", "Heading 8" }, // RES_POOLCOLL_HEADLINE8
1549 { "heading 9", "Heading 9" }, // RES_POOLCOLL_HEADLINE9
1550 { "Heading 1", "Heading 1" }, // RES_POOLCOLL_HEADLINE1
1551 { "Heading 2", "Heading 2" }, // RES_POOLCOLL_HEADLINE2
1552 { "Heading 3", "Heading 3" }, // RES_POOLCOLL_HEADLINE3
1553 { "Heading 4", "Heading 4" }, // RES_POOLCOLL_HEADLINE4
1554 { "Heading 5", "Heading 5" }, // RES_POOLCOLL_HEADLINE5
1555 { "Heading 6", "Heading 6" }, // RES_POOLCOLL_HEADLINE6
1556 { "Heading 7", "Heading 7" }, // RES_POOLCOLL_HEADLINE7
1557 { "Heading 8", "Heading 8" }, // RES_POOLCOLL_HEADLINE8
1558 { "Heading 9", "Heading 9" }, // RES_POOLCOLL_HEADLINE9
1559 { "Index 1", "Index 1" }, // RES_POOLCOLL_TOX_IDX1
1560 { "Index 2", "Index 2" }, // RES_POOLCOLL_TOX_IDX2
1561 { "Index 3", "Index 3" }, // RES_POOLCOLL_TOX_IDX3
1562// { "Index 4", "" },
1563// { "Index 5", "" },
1564// { "Index 6", "" },
1565// { "Index 7", "" },
1566// { "Index 8", "" },
1567// { "Index 9", "" },
1568 { "TOC 1", "Contents 1" }, // RES_POOLCOLL_TOX_CNTNT1
1569 { "TOC 2", "Contents 2" }, // RES_POOLCOLL_TOX_CNTNT2
1570 { "TOC 3", "Contents 3" }, // RES_POOLCOLL_TOX_CNTNT3
1571 { "TOC 4", "Contents 4" }, // RES_POOLCOLL_TOX_CNTNT4
1572 { "TOC 5", "Contents 5" }, // RES_POOLCOLL_TOX_CNTNT5
1573 { "TOC 6", "Contents 6" }, // RES_POOLCOLL_TOX_CNTNT6
1574 { "TOC 7", "Contents 7" }, // RES_POOLCOLL_TOX_CNTNT7
1575 { "TOC 8", "Contents 8" }, // RES_POOLCOLL_TOX_CNTNT8
1576 { "TOC 9", "Contents 9" }, // RES_POOLCOLL_TOX_CNTNT9
1577 { "TOC Heading", "Contents Heading" }, // RES_POOLCOLL_TOX_CNTNTH
1578 { "TOCHeading", "Contents Heading" }, // RES_POOLCOLL_TOX_CNTNTH
1579 { "toc 1", "Contents 1" }, // RES_POOLCOLL_TOX_CNTNT1
1580 { "toc 2", "Contents 2" }, // RES_POOLCOLL_TOX_CNTNT2
1581 { "toc 3", "Contents 3" }, // RES_POOLCOLL_TOX_CNTNT3
1582 { "toc 4", "Contents 4" }, // RES_POOLCOLL_TOX_CNTNT4
1583 { "toc 5", "Contents 5" }, // RES_POOLCOLL_TOX_CNTNT5
1584 { "toc 6", "Contents 6" }, // RES_POOLCOLL_TOX_CNTNT6
1585 { "toc 7", "Contents 7" }, // RES_POOLCOLL_TOX_CNTNT7
1586 { "toc 8", "Contents 8" }, // RES_POOLCOLL_TOX_CNTNT8
1587 { "toc 9", "Contents 9" }, // RES_POOLCOLL_TOX_CNTNT9
1588 { "TOC1", "Contents 1" }, // RES_POOLCOLL_TOX_CNTNT1
1589 { "TOC2", "Contents 2" }, // RES_POOLCOLL_TOX_CNTNT2
1590 { "TOC3", "Contents 3" }, // RES_POOLCOLL_TOX_CNTNT3
1591 { "TOC4", "Contents 4" }, // RES_POOLCOLL_TOX_CNTNT4
1592 { "TOC5", "Contents 5" }, // RES_POOLCOLL_TOX_CNTNT5
1593 { "TOC6", "Contents 6" }, // RES_POOLCOLL_TOX_CNTNT6
1594 { "TOC7", "Contents 7" }, // RES_POOLCOLL_TOX_CNTNT7
1595 { "TOC8", "Contents 8" }, // RES_POOLCOLL_TOX_CNTNT8
1596 { "TOC9", "Contents 9" }, // RES_POOLCOLL_TOX_CNTNT9
1597// { "Normal Indent", "" },
1598 { "footnote text", "Footnote" }, // RES_POOLCOLL_FOOTNOTE
1599 { "Footnote Text", "Footnote" }, // RES_POOLCOLL_FOOTNOTE
1600 { "Annotation Text", "Marginalia" }, // RES_POOLCOLL_MARGINAL
1601 { "Header", "Header" }, // RES_POOLCOLL_HEADER
1602 { "header", "Header" }, // RES_POOLCOLL_HEADER
1603 { "Footer", "Footer" }, // RES_POOLCOLL_FOOTER
1604 { "footer", "Footer" }, // RES_POOLCOLL_FOOTER
1605 { "Index Heading", "Index Heading" }, // RES_POOLCOLL_TOX_IDXH
1606 { "Caption", "Caption" }, // RES_POOLCOLL_LABEL
1607 { "table of figures", "Figure Index 1" }, // RES_POOLCOLL_TOX_ILLUS1
1608 { "Table of Figures", "Figure Index 1" }, // RES_POOLCOLL_TOX_ILLUS1
1609 { "Envelope Address", "Addressee" }, // RES_POOLCOLL_ENVELOPE_ADDRESS
1610 { "Envelope Return", "Sender" }, // RES_POOLCOLL_SEND_ADDRESS
1611 { "footnote reference", "Footnote Symbol" }, // RES_POOLCHR_FOOTNOTE; tdf#82173
1612 { "Footnote Reference", "Footnote Symbol" }, // RES_POOLCHR_FOOTNOTE; tdf#82173
1613// { "Annotation Reference", "" },
1614 { "Line Number", "Line numbering" }, // RES_POOLCHR_LINENUM
1615 { "Page Number", "Page Number" }, // RES_POOLCHR_PAGENO
1616 { "endnote reference", "Endnote Symbol" }, // RES_POOLCHR_ENDNOTE; tdf#82173
1617 { "Endnote Reference", "Endnote Symbol" }, // RES_POOLCHR_ENDNOTE; tdf#82173
1618 { "endnote text", "Endnote" }, // RES_POOLCOLL_ENDNOTE
1619 { "Endnote Text", "Endnote" }, // RES_POOLCOLL_ENDNOTE
1620 { "Table of Authorities", "Bibliography Heading" }, // RES_POOLCOLL_TOX_AUTHORITIESH
1621// { "Macro Text", "" },
1622// { "TOA Heading", "" },
1623 { "List", "List" }, // RES_POOLCOLL_NUMBER_BULLET_BASE
1624// { "List 2", "" },
1625// { "List 3", "" },
1626// { "List 4", "" },
1627// { "List 5", "" },
1628 { "List Bullet", "List 1" }, // RES_POOLCOLL_BULLET_LEVEL1
1629 { "List Bullet 2", "List 2" }, // RES_POOLCOLL_BULLET_LEVEL2
1630 { "List Bullet 3", "List 3" }, // RES_POOLCOLL_BULLET_LEVEL3
1631 { "List Bullet 4", "List 4" }, // RES_POOLCOLL_BULLET_LEVEL4
1632 { "List Bullet 5", "List 5" }, // RES_POOLCOLL_BULLET_LEVEL5
1633 { "List Number", "Numbering 1" }, // RES_POOLCOLL_NUM_LEVEL1
1634 { "List Number 2", "Numbering 2" }, // RES_POOLCOLL_NUM_LEVEL2
1635 { "List Number 3", "Numbering 3" }, // RES_POOLCOLL_NUM_LEVEL3
1636 { "List Number 4", "Numbering 4" }, // RES_POOLCOLL_NUM_LEVEL4
1637 { "List Number 5", "Numbering 5" }, // RES_POOLCOLL_NUM_LEVEL5
1638 { "Title", "Title" }, // RES_POOLCOLL_DOC_TITLE
1639 { "Closing", "Appendix" }, // RES_POOLCOLL_DOC_APPENDIX
1640 { "Signature", "Signature" }, // RES_POOLCOLL_SIGNATURE
1641// { "Default Paragraph Font", "" },
1642 { "DefaultParagraphFont", "Default Paragraph Font" },
1643 { "Body Text", "Text body" }, // RES_POOLCOLL_TEXT
1644 { "BodyText", "Text body" }, // RES_POOLCOLL_TEXT
1645 { "BodyTextIndentItalic", "Text body indent italic" },
1646 { "Body Text Indent", "Text body indent" }, // RES_POOLCOLL_TEXT_MOVE
1647 { "BodyTextIndent", "Text body indent" }, // RES_POOLCOLL_TEXT_MOVE
1648 { "BodyTextIndent2", "Text body indent2" },
1649 { "List Continue", "List 1 Cont." }, // RES_POOLCOLL_BULLET_NONUM1
1650 { "List Continue 2", "List 2 Cont." }, // RES_POOLCOLL_BULLET_NONUM2
1651 { "List Continue 3", "List 3 Cont." }, // RES_POOLCOLL_BULLET_NONUM3
1652 { "List Continue 4", "List 4 Cont." }, // RES_POOLCOLL_BULLET_NONUM4
1653 { "List Continue 5", "List 5 Cont." }, // RES_POOLCOLL_BULLET_NONUM5
1654// { "Message Header", "" },
1655 { "Subtitle", "Subtitle" }, // RES_POOLCOLL_DOC_SUBTITLE
1656 { "Salutation", "Salutation" }, // RES_POOLCOLL_GREETING
1657// { "Date", "" },
1658 { "Body Text First Indent", "First line indent" }, // RES_POOLCOLL_TEXT_IDENT
1659// { "Body Text First Indent 2", "" },
1660// { "Note Heading", "" },
1661// { "Body Text 2", "" },
1662// { "Body Text 3", "" },
1663// { "Body Text Indent 2", "" },
1664// { "Body Text Indent 3", "" },
1665// { "Block Text", "" },
1666 { "Hyperlink", "Internet link" }, // RES_POOLCHR_INET_NORMAL
1667 { "FollowedHyperlink", "Visited Internet Link" }, // RES_POOLCHR_INET_VISIT
1668 { "Strong", "Strong Emphasis" }, // RES_POOLCHR_HTML_STRONG
1669 { "Emphasis", "Emphasis" }, // RES_POOLCHR_HTML_EMPHASIS
1670// { "Document Map", "" },
1671// { "Plain Text", "" },
1672 { "NoList", "No List" },
1673 { "AbstractHeading", "Abstract Heading" },
1674 { "AbstractBody", "Abstract Body" },
1675 { "PageNumber", "Page Number" }, // RES_POOLCHR_PAGENO
1676 { "TableNormal", "Normal Table" },
1677 { "DocumentMap", "Document Map" },
1678 };
1679
1680 // find style-name using map
1681 if (const auto aIt = StyleNameMap.find(sRet); aIt != StyleNameMap.end())
1682 {
1683 sRet = aIt->second;
1684 }
1685 else
1686 {
1687 // Style names which should not be used without a " (user)" suffix
1688 static const o3tl::sorted_vector<OUString> ReservedStyleNames = [] {
1690 for (const auto& pair : StyleNameMap)
1691 set.insert(pair.second);
1692 return set;
1693 }();
1694 // Similar to SwStyleNameMapper convention (where a " (user)" suffix is used to
1695 // disambiguate user styles with reserved names in localization where respective
1696 // built-in styles have different UI names), we add a " (WW)" suffix here. Unlike
1697 // the " (user)" suffix, it is not hidden from the UI; it will be handled when
1698 // exported to Word formats - see MSWordStyles::BuildWwNames.
1699 // We can't use the " (user)" suffix, because that system is built upon the assumption
1700 // that UI names of respective built-in styles are different from the user style name.
1701 // That is not necessarily true here, since the current localization may not change
1702 // the UI names of built-in styles.
1703 if (ReservedStyleNames.find(sRet) != ReservedStyleNames.end() || sRet.endsWith(" (WW)"))
1704 sRet += " (WW)";
1705 }
1706
1707 return sRet;
1708}
1709
1710void StyleSheetTable::applyDefaults(bool bParaProperties)
1711{
1712 try{
1713
1714 if (!m_pImpl->m_bIsNewDoc)
1715 {
1716 // tdf#72942: do not corrupts original styles in master document
1717 // during inserting of text from second document
1718 return;
1719 }
1720
1721 if(!m_pImpl->m_xTextDefaults.is())
1722 {
1723 m_pImpl->m_xTextDefaults.set(
1724 m_pImpl->m_rDMapper.GetTextFactory()->createInstance("com.sun.star.text.Defaults"),
1725 uno::UNO_QUERY_THROW );
1726 }
1727
1728 // WARNING: these defaults only take effect IF there is a DocDefaults style section. Normally there is, but not always.
1729 if( bParaProperties && m_pImpl->m_pDefaultParaProps)
1730 {
1731 // tdf#87533 LO will have different defaults here, depending on the locale. Import with documented defaults
1732 SetDefaultParaProps(PROP_WRITING_MODE, uno::Any(sal_Int16(text::WritingMode_LR_TB)));
1733 SetDefaultParaProps(PROP_PARA_ADJUST, uno::Any(sal_Int16(style::ParagraphAdjust_LEFT)));
1734
1735 // Widow/Orphan -> set both to two if not already set
1736 uno::Any aTwo(sal_Int8(2));
1739
1740 uno::Reference<style::XStyleFamiliesSupplier> xStylesSupplier(m_pImpl->m_xTextDocument, uno::UNO_QUERY);
1741 uno::Reference<container::XNameAccess> xStyleFamilies = xStylesSupplier->getStyleFamilies();
1743 xStyleFamilies->getByName("ParagraphStyles") >>= xParagraphStyles;
1745 // This is the built-in default style that every style inherits from
1746 xParagraphStyles->getByName("Paragraph style") >>= xDefault;
1747
1748 const uno::Sequence< beans::PropertyValue > aPropValues = m_pImpl->m_pDefaultParaProps->GetPropertyValues();
1749 for( const auto& rPropValue : aPropValues )
1750 {
1751 try
1752 {
1753 xDefault->setPropertyValue(rPropValue.Name, rPropValue.Value);
1754 }
1755 catch( const uno::Exception& )
1756 {
1757 TOOLS_WARN_EXCEPTION( "writerfilter", "setPropertyValue");
1758 }
1759 }
1760 }
1761 if( !bParaProperties && m_pImpl->m_pDefaultCharProps )
1762 {
1763 // tdf#108350: Earlier in DomainMapper for DOCX, Calibri/11pt was set to match MSWord 2007+,
1764 // but that is valid only if DocDefaults_rPrDefault is omitted.
1765 // Now that DocDefaults_rPrDefault is known, the defaults should be reset to Times New Roman/10pt.
1766 if ( m_pImpl->m_rDMapper.IsOOXMLImport() )
1767 m_pImpl->m_xTextDefaults->setPropertyValue( getPropertyName(PROP_CHAR_FONT_NAME), css::uno::Any(OUString("Times New Roman")) );
1768
1769 const uno::Sequence< beans::PropertyValue > aPropValues = m_pImpl->m_pDefaultCharProps->GetPropertyValues();
1770 for( const auto& rPropValue : aPropValues )
1771 {
1772 try
1773 {
1774 m_pImpl->m_xTextDefaults->setPropertyValue( rPropValue.Name, rPropValue.Value );
1775 }
1776 catch( const uno::Exception& )
1777 {
1778 TOOLS_WARN_EXCEPTION( "writerfilter", "exception");
1779 }
1780 }
1781 }
1782 }
1783 catch( const uno::Exception& )
1784 {
1785 }
1786}
1787
1788
1789OUString StyleSheetTable::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate )
1790{
1791 //find out if any of the styles already has the required properties then return its name
1792 OUString sListLabel = m_pImpl->HasListCharStyle(rCharProperties);
1793 // Don't try to reuse an existing character style if requested.
1794 if( !sListLabel.isEmpty() && !bAlwaysCreate)
1795 return sListLabel;
1796
1797 //create a new one otherwise
1798 const uno::Reference< container::XNameContainer >& xCharStyles = m_pImpl->m_rDMapper.GetCharacterStyles();
1799 sListLabel = m_pImpl->m_rDMapper.GetUnusedCharacterStyleName();
1800 uno::Reference< lang::XMultiServiceFactory > xDocFactory( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW );
1801 try
1802 {
1803 uno::Reference< style::XStyle > xStyle( xDocFactory->createInstance(
1804 getPropertyName( PROP_SERVICE_CHAR_STYLE )), uno::UNO_QUERY_THROW);
1805 uno::Reference< beans::XPropertySet > xStyleProps(xStyle, uno::UNO_QUERY_THROW );
1806 for( const auto& rCharProp : rCharProperties)
1807 {
1808 try
1809 {
1810 xStyleProps->setPropertyValue( rCharProp.Name, rCharProp.Value );
1811 }
1812 catch( const uno::Exception& )
1813 {
1814 TOOLS_WARN_EXCEPTION( "writerfilter", "StyleSheetTable::getOrCreateCharStyle - Style::setPropertyValue");
1815 }
1816 }
1817 xCharStyles->insertByName( sListLabel, uno::Any( xStyle) );
1818 m_pImpl->m_aListCharStylePropertyVector.emplace_back( sListLabel, std::vector(rCharProperties) );
1819 }
1820 catch( const uno::Exception& )
1821 {
1822 TOOLS_WARN_EXCEPTION( "writerfilter", "StyleSheetTable::getOrCreateCharStyle");
1823 }
1824
1825 return sListLabel;
1826}
1827
1828}//namespace writerfilter
1829
1830/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::vector< css::beans::PropertyValue > PropertyValueVector_t
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
#define WW_OUTLINE_MAX
#define WW_OUTLINE_MIN
PropertyValueVector_t aPropertyValues
OUString sCharStyleName
std::vector< beans::PropertyValue > m_aValues
PropertiesInfo aProperties
const_iterator find(const Value &x) const
const_iterator end() const
T * get() const
An SPRM: Section, Paragraph and Run Modifier.
virtual sal_uInt32 getId() const =0
Returns id of the SPRM.
virtual writerfilter::Reference< Properties >::Pointer_t getProps()=0
Returns reference to properties contained in the SPRM.
virtual Value::Pointer_t getValue()=0
Returns value of the SPRM.
static TagLogger & getInstance()
Definition: TagLogger.cxx:95
void element(const std::string &name)
Definition: TagLogger.cxx:102
virtual int getInt() const =0
Returns integer representation of the value.
virtual OUString getString() const =0
Returns string representation of the value.
Handler for a latent style (w:lsdException element)
css::beans::PropertyValue GetInteropGrabBag()
Used for table styles, has a name.
css::beans::PropertyValues GetInteropGrabBagSeq() const
Used for existing styles, just a list of properties.
const tools::SvRef< StyleSheetPropertyMap > m_pProperties
std::vector< css::beans::PropertyValue > m_aInteropGrabBag
PropertyMapPtr GetMergedInheritedProperties(const StyleSheetTablePtr &pStyleSheetTable)
void AppendInteropGrabBag(const css::beans::PropertyValue &rValue)
void ApplyStyleSheetsImpl(const FontTablePtr &rFontTable, std::vector< StyleSheetEntryPtr > const &rEntries)
void ApplyClonedTOCStyles()
Replace the applied en-US Word built-in styles that were referenced from TOC fields (also STYLEREF an...
OUString CloneTOCStyle(FontTablePtr const &rFontTable, StyleSheetEntryPtr const pStyle, OUString const &rName)
virtual void lcl_sprm(Sprm &sprm) override
StyleSheetEntryPtr FindStyleSheetByConvertedStyleName(std::u16string_view rIndex)
void SetDefaultParaProps(PropertyIds eId, const css::uno::Any &rAny)
virtual void lcl_entry(writerfilter::Reference< Properties >::Pointer_t ref) override
OUString ConvertStyleName(const OUString &rWWName, bool bExtendedSearch=false)
PropertyMapPtr const & GetDefaultParaProps() const
OUString getOrCreateCharStyle(PropertyValueVector_t &rCharProperties, bool bAlwaysCreate)
const StyleSheetEntryPtr & GetCurrentEntry() const
StyleSheetEntryPtr FindStyleSheetByISTD(const OUString &sIndex)
std::unique_ptr< StyleSheetTable_Impl > m_pImpl
void applyDefaults(bool bParaProperties)
PropertyMapPtr const & GetDefaultCharProps() const
Returns the default character properties.
StyleSheetTable(DomainMapper &rDMapper, css::uno::Reference< css::text::XTextDocument > const &xTextDocument, bool bIsNewDoc)
void ApplyStyleSheets(const FontTablePtr &rFontTable)
virtual void lcl_attribute(Id Name, Value &val) override
TableStyleSheetEntry(StyleSheetEntry const &aEntry)
PropertyMapPtr GetLocalPropertiesFromMask(sal_Int32 nMask)
void AddTblStylePr(TblStyleType nType, const PropertyMapPtr &pProps)
PropertyMapPtr GetProperties(sal_Int32 nMask)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define TOOLS_INFO_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
virtual void Insert(SotClipboardFormatId nFormat, const OUString &rFormatName) override
float u
OUString aName
Sequence< sal_Int8 > aSeq
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
aStr
aBuf
void set(css::uno::UnoInterfaceReference const &value)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill='\0')
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
sal_Int16 convertTableJustification(sal_Int32 nIntValue)
OUString getPropertyName(PropertyIds eId)
tools::SvRef< StyleSheetEntry > StyleSheetEntryPtr
static void lcl_mergeProps(const PropertyMapPtr &pToFill, const PropertyMapPtr &pToAdd, TblStyleType nStyleId)
void resolveSprmProps(Properties &rHandler, Sprm &rSprm)
Definition: util.cxx:62
sal_Int16 nId
QPRO_FUNC_TYPE nType
sal_uInt32 Id
void AppendLatentStyleProperty(const OUString &aName, Value const &rValue)
Appends the given key-value pair to the list of latent style properties of the current entry.
static void SetPropertiesToDefault(const uno::Reference< style::XStyle > &xStyle)
Sets all properties of xStyle back to default.
uno::Reference< beans::XPropertySet > m_xTextDefaults
uno::Reference< text::XTextDocument > m_xTextDocument
StyleSheetTable_Impl(DomainMapper &rDMapper, uno::Reference< text::XTextDocument > xTextDocument, bool bIsNewDoc)
std::map< OUString, StyleSheetEntryPtr > m_aStyleSheetEntriesMap
OUString HasListCharStyle(const PropertyValueVector_t &rCharProperties)
std::vector< ListCharStylePropertyMap_t > m_aListCharStylePropertyVector
std::map< OUString, OUString > m_ClonedTOCStylesMap
void ApplyClonedTOCStylesToXText(uno::Reference< text::XText > const &xText)
std::vector< StyleSheetEntryPtr > m_aStyleSheetEntries
Reference< XFrame > xFrame
OUString Name
signed char sal_Int8
ResultType type
PointerStyles const styles[]