Avoid potential negative array index access to cached text.
[LibreOffice.git] / writerfilter / source / dmapper / DomainMapper.cxx
blobbfca0214a0178c69e01da0dbb4c635fb71457baf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "BorderHandler.hxx"
20 #include "PageBordersHandler.hxx"
22 #include "util.hxx"
23 #include "SdtHelper.hxx"
24 #include "TagLogger.hxx"
25 #include "TDefTableHandler.hxx"
26 #include "DomainMapper_Impl.hxx"
27 #include "ConversionHelper.hxx"
28 #include "ModelEventListener.hxx"
29 #include "MeasureHandler.hxx"
30 #include <i18nlangtag/languagetag.hxx>
31 #include <i18nutil/paper.hxx>
32 #include <ooxml/resourceids.hxx>
33 #include <oox/token/tokens.hxx>
34 #include <oox/drawingml/drawingmltypes.hxx>
36 #include <com/sun/star/awt/Gradient2.hpp>
37 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
38 #include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp>
39 #include <com/sun/star/drawing/FillStyle.hpp>
40 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
41 #include <com/sun/star/table/BorderLineStyle.hpp>
42 #include <com/sun/star/table/ShadowFormat.hpp>
43 #include <com/sun/star/text/HoriOrientation.hpp>
44 #include <com/sun/star/text/RelOrientation.hpp>
45 #include <com/sun/star/text/VertOrientation.hpp>
46 #include <com/sun/star/text/WrapTextMode.hpp>
47 #include <com/sun/star/text/SizeType.hpp>
48 #include <com/sun/star/text/XEndnotesSupplier.hpp>
49 #include <com/sun/star/text/XFootnotesSupplier.hpp>
50 #include <com/sun/star/text/XLineNumberingProperties.hpp>
51 #include <com/sun/star/awt/FontRelief.hpp>
52 #include <com/sun/star/awt/FontWeight.hpp>
53 #include <com/sun/star/awt/FontUnderline.hpp>
54 #include <com/sun/star/awt/FontStrikeout.hpp>
55 #include <com/sun/star/awt/FontSlant.hpp>
56 #include <com/sun/star/document/XEventBroadcaster.hpp>
57 #include <com/sun/star/style/ParagraphAdjust.hpp>
58 #include <com/sun/star/style/BreakType.hpp>
59 #include <com/sun/star/style/CaseMap.hpp>
60 #include <com/sun/star/style/LineSpacing.hpp>
61 #include <com/sun/star/style/LineSpacingMode.hpp>
62 #include <com/sun/star/text/FootnoteNumbering.hpp>
63 #include <com/sun/star/text/TextGridMode.hpp>
64 #include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
65 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
66 #include <com/sun/star/text/WritingMode.hpp>
67 #include <com/sun/star/text/WritingMode2.hpp>
68 #include <com/sun/star/text/XFootnote.hpp>
69 #include <com/sun/star/text/XTextColumns.hpp>
70 #include <com/sun/star/text/RubyPosition.hpp>
71 #include <com/sun/star/uno/XComponentContext.hpp>
72 #include <com/sun/star/text/FontEmphasis.hpp>
73 #include <com/sun/star/awt/CharSet.hpp>
74 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
75 #include <com/sun/star/util/XComplexColor.hpp>
76 #include <comphelper/types.hxx>
77 #include <comphelper/storagehelper.hxx>
78 #include <comphelper/sequence.hxx>
79 #include <editeng/escapementitem.hxx>
80 #include <filter/msfilter/util.hxx>
81 #include <sfx2/DocumentMetadataAccess.hxx>
82 #include <unotools/localedatawrapper.hxx>
83 #include <unotools/mediadescriptor.hxx>
85 #include "TextEffectsHandler.hxx"
86 #include "ThemeColorHandler.hxx"
87 #include "CellColorHandler.hxx"
88 #include "SectionColumnHandler.hxx"
89 #include "GraphicHelpers.hxx"
90 #include <dmapper/GraphicZOrderHelper.hxx>
91 #include <comphelper/diagnose_ex.hxx>
92 #include <sal/log.hxx>
93 #include <tools/UnitConversion.hxx>
95 using namespace ::com::sun::star;
96 using namespace oox;
98 namespace writerfilter::dmapper{
100 struct
102 sal_Int32 h;
103 bool orient;
104 sal_Int32 w;
105 } CT_PageSz;
108 DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xContext,
109 uno::Reference<io::XInputStream> const& xInputStream,
110 uno::Reference<lang::XComponent> const& xModel,
111 bool bRepairStorage,
112 SourceDocumentType eDocumentType,
113 utl::MediaDescriptor const & rMediaDesc) :
114 LoggedProperties("DomainMapper"),
115 LoggedTable("DomainMapper"),
116 LoggedStream("DomainMapper"),
117 m_pImpl(new DomainMapper_Impl(*this, xContext, xModel, eDocumentType, rMediaDesc)),
118 mbIsSplitPara(false),
119 mbHasControls(false),
120 mbWasShapeInPara(false)
122 if (m_pImpl->IsNewDoc())
124 // #i24363# tab stops relative to indent
125 m_pImpl->SetDocumentSettingsProperty(
126 getPropertyName(PROP_TABS_RELATIVE_TO_INDENT),
127 uno::Any(false));
128 m_pImpl->SetDocumentSettingsProperty(
129 getPropertyName(PROP_SURROUND_TEXT_WRAP_SMALL),
130 uno::Any(true));
131 m_pImpl->SetDocumentSettingsProperty(
132 getPropertyName(PROP_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING),
133 uno::Any(true));
135 // Don't load the default style definitions to avoid weird mix
136 m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::Any(true));
137 m_pImpl->SetDocumentSettingsProperty("MsWordCompTrailingBlanks", uno::Any(true));
138 m_pImpl->SetDocumentSettingsProperty("HeaderSpacingBelowLastPara",
139 uno::Any(true));
140 m_pImpl->SetDocumentSettingsProperty("FrameAutowidthWithMorePara", uno::Any(true));
141 m_pImpl->SetDocumentSettingsProperty("FootnoteInColumnToPageEnd", uno::Any(true));
142 m_pImpl->SetDocumentSettingsProperty("TabAtLeftIndentForParagraphsInList", uno::Any(true));
143 m_pImpl->SetDocumentSettingsProperty(u"NoGapAfterNoteNumber"_ustr,
144 uno::Any(true));
146 // Enable only for new documents, since pasting from clipboard can influence existing doc
147 m_pImpl->SetDocumentSettingsProperty("NoNumberingShowFollowBy", uno::Any(true));
150 // Initialize RDF metadata, to be able to add statements during the import.
153 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY_THROW);
154 uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
155 OUString aBaseURL = rMediaDesc.getUnpackedValueOrDefault("URL", OUString());
156 const uno::Reference<frame::XModel> xModel_(xModel,
157 uno::UNO_QUERY_THROW);
158 const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xContext, xModel_, aBaseURL, u""));
159 const uno::Reference<task::XInteractionHandler> xHandler;
160 xDocumentMetadataAccess->loadMetadataFromStorage(xStorage, xBaseURI, xHandler);
162 catch (const uno::Exception&)
164 DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize RDF metadata");
167 if (eDocumentType == SourceDocumentType::OOXML) {
168 // tdf#108350
169 // In Word since version 2007, the default document font is Calibri 11 pt.
170 // If a DOCX document doesn't contain font information, we should assume
171 // the intended font to provide best layout match.
174 uno::Reference< beans::XPropertySet > xDefProps(GetTextFactory()->createInstance("com.sun.star.text.Defaults"),
175 uno::UNO_QUERY_THROW);
176 xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), css::uno::Any(OUString("Calibri")));
177 xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), css::uno::Any(double(11)));
179 catch (const uno::Exception&)
181 DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize default font");
185 //import document properties
188 m_pImpl->m_xDocumentStorage = comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(
189 OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xContext, bRepairStorage);
191 uno::Reference< uno::XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext(
192 "com.sun.star.document.OOXMLDocumentPropertiesImporter",
193 xContext);
195 uno::Reference< document::XOOXMLDocumentPropertiesImporter > xImporter( xTemp, uno::UNO_QUERY_THROW );
196 uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier( xModel, uno::UNO_QUERY_THROW);
197 xImporter->importProperties(m_pImpl->m_xDocumentStorage,
198 xPropSupplier->getDocumentProperties());
200 catch( const uno::Exception& ) {}
203 void DomainMapper::setDocumentReference(writerfilter::ooxml::OOXMLDocument* pDocument)
205 m_pImpl->setDocumentReference(pDocument);
208 DomainMapper::~DomainMapper()
212 // Remove temporary footnotes and endnotes
213 m_pImpl->RemoveTemporaryFootOrEndnotes();
215 uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
216 sal_Int32 nIndexes = 0;
217 if( xIndexesSupplier.is() )
219 uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes();
220 nIndexes = xIndexes->getCount();
222 // If we have page references, those need updating as well, similar to the indexes.
223 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
224 if(xTextFieldsSupplier.is())
226 uno::Reference<container::XEnumeration> xEnumeration = xTextFieldsSupplier->getTextFields()->createEnumeration();
227 while(xEnumeration->hasMoreElements())
229 ++nIndexes;
230 xEnumeration->nextElement();
234 mbHasControls |= m_pImpl->m_pSdtHelper->hasElements();
235 if ( nIndexes || mbHasControls )
237 //index update has to wait until first view is created
238 uno::Reference< document::XEventBroadcaster > xBroadcaster(xIndexesSupplier, uno::UNO_QUERY);
239 if (xBroadcaster.is())
240 xBroadcaster->addEventListener(uno::Reference< document::XEventListener >(new ModelEventListener(nIndexes, mbHasControls)));
244 // Apply the document settings for both DOCX and RTF after everything else
245 m_pImpl->GetSettingsTable()->ApplyProperties( m_pImpl->GetTextDocument( ) );
247 // now that importing is finished, re-enable default styles for any that were never defined/imported.
248 m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::Any(false));
250 // Grab-bag handling
251 comphelper::SequenceAsHashMap aProperties;
253 // Add the saved w:themeFontLang setting
254 aProperties["ThemeFontLangProps"] <<= m_pImpl->GetSettingsTable()->GetThemeFontLangProperties();
256 // Add the saved compat settings
257 aProperties["CompatSettings"] <<= m_pImpl->GetSettingsTable()->GetCompatSettings();
259 // Add the saved DocumentProtection settings
260 aProperties["DocumentProtection"] <<= m_pImpl->GetSettingsTable()->GetDocumentProtectionSettings();
262 // Add the saved w:doNotHyphenateCaps setting
263 aProperties["NoHyphenateCaps"] <<= m_pImpl->GetSettingsTable()->GetNoHyphenateCaps();
265 uno::Reference<beans::XPropertySet> xDocProps(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
266 if (xDocProps.is())
268 comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue("InteropGrabBag"));
269 aGrabBag.update(aProperties);
270 xDocProps->setPropertyValue("InteropGrabBag", uno::Any(aGrabBag.getAsConstPropertyValueList()));
273 // tdf#138782: for docs created in MS Word 2010 and older (compatibilityMode <= 14)
274 m_pImpl->SetDocumentSettingsProperty(
275 "AddFrameOffsets",
276 uno::Any(14 >= m_pImpl->GetSettingsTable()->GetWordCompatibilityMode()));
278 catch( const uno::Exception& ) {}
280 #ifdef DBG_UTIL
281 TagLogger::getInstance().endDocument();
282 #endif
285 void DomainMapper::lcl_attribute(Id nName, Value & val)
287 if (m_pImpl->hasTableManager() && m_pImpl->getTableManager().attribute(nName, val))
288 return;
290 static const int nSingleLineSpacing = 240;
291 sal_Int32 nIntValue = val.getInt();
292 OUString sStringValue = val.getString();
294 SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
295 switch( nName )
297 case NS_ooxml::LN_CT_Lvl_start:
298 break;
299 case NS_ooxml::LN_CT_Lvl_numFmt:
300 break;
301 case NS_ooxml::LN_CT_Lvl_isLgl:
302 break;
303 case NS_ooxml::LN_CT_Lvl_legacy:
304 break;
305 case NS_ooxml::LN_CT_AbstractNum_nsid:
306 break;
307 case NS_ooxml::LN_CT_AbstractNum_tmpl:
308 break;
309 case NS_ooxml::LN_CT_Border_sz:
310 break;
311 case NS_ooxml::LN_CT_Border_val:
312 break;
313 case NS_ooxml::LN_CT_Border_space:
314 break;
315 case NS_ooxml::LN_CT_Border_shadow:
316 break;
317 case NS_ooxml::LN_CT_Border_frame:
318 break;
319 case NS_ooxml::LN_headerr:
320 break;
321 case NS_ooxml::LN_footerr:
322 break;
323 case NS_ooxml::LN_endnote:
324 break;
325 case NS_ooxml::LN_CT_Bookmark_name:
326 m_pImpl->SetBookmarkName( sStringValue );
327 break;
328 case NS_ooxml::LN_CT_MarkupRangeBookmark_id:
329 // add a bookmark range -- this remembers a bookmark starting here
330 // or, if the bookmark was already started or, if the bookmark was
331 // already started before, writes out the bookmark
332 m_pImpl->StartOrEndBookmark( sStringValue );
333 break;
334 case NS_ooxml::LN_CT_MarkupRange_displacedByCustomXml:
335 break;
336 case NS_ooxml::LN_NUMBERING:
337 break;
338 case NS_ooxml::LN_FONTTABLE:
339 break;
340 case NS_ooxml::LN_STYLESHEET:
341 break;
343 case NS_ooxml::LN_CT_Sym_char:
344 m_pImpl->SetSymbolChar(nIntValue);
345 break;
346 case NS_ooxml::LN_CT_Sym_font:
347 m_pImpl->SetSymbolFont(sStringValue);
348 break;
349 case NS_ooxml::LN_CT_Underline_val:
350 if (m_pImpl->GetTopContext())
351 handleUnderlineType(nIntValue, m_pImpl->GetTopContext());
352 break;
353 case NS_ooxml::LN_CT_Underline_color:
354 if (m_pImpl->GetTopContext())
356 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_HAS_COLOR, uno::Any( true ) );
357 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COLOR, uno::Any( nIntValue ) );
359 break;
360 case NS_ooxml::LN_CT_Underline_themeColor:
361 case NS_ooxml::LN_CT_Underline_themeTint:
362 case NS_ooxml::LN_CT_Underline_themeShade:
363 if (m_pImpl->GetTopContext())
365 uno::Reference<util::XComplexColor> xComplexColor;
366 model::ComplexColor aComplexColor;
368 PropertyMapPtr pTopContext = m_pImpl->GetTopContext();
369 std::optional<PropertyMap::Property> aValue;
370 if (pTopContext && (aValue = pTopContext->getProperty(PROP_CHAR_UNDERLINE_COMPLEX_COLOR)))
372 aValue->second >>= xComplexColor;
373 if (xComplexColor.is())
374 aComplexColor = model::color::getFromXComplexColor(xComplexColor);
377 if (nName == NS_ooxml::LN_CT_Underline_themeColor)
379 auto eThemeColorType = TDefTableHandler::getThemeColorTypeIndex(nIntValue);
380 aComplexColor.setThemeColor(eThemeColorType);
382 else if (nName == NS_ooxml::LN_CT_Underline_themeTint)
384 if (nIntValue > 0)
386 sal_Int16 nTransformedValue = sal_Int16((255.0 - nIntValue) * 10000.0 / 255.0);
387 aComplexColor.addTransformation({model::TransformationType::Tint, sal_Int16(nTransformedValue)});
390 else if (nName == NS_ooxml::LN_CT_Underline_themeShade)
392 if (nIntValue > 0)
394 sal_Int16 nTransformedValue = sal_Int16((255.0 - nIntValue) * 10000.0 / 255.0);
395 aComplexColor.addTransformation({model::TransformationType::Shade, sal_Int16(nTransformedValue)});
398 xComplexColor = model::color::createXComplexColor(aComplexColor);
399 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COMPLEX_COLOR, uno::Any(xComplexColor));
401 break;
403 case NS_ooxml::LN_CT_TabStop_val:
404 if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_TabJc_clear)
406 m_pImpl->m_aCurrentTabStop.bDeleted = true;
408 else
410 m_pImpl->m_aCurrentTabStop.bDeleted = false;
411 m_pImpl->m_aCurrentTabStop.Alignment = getTabAlignFromValue(nIntValue);
413 break;
414 case NS_ooxml::LN_CT_TabStop_leader:
415 m_pImpl->m_aCurrentTabStop.FillChar = getFillCharFromValue(nIntValue);
416 break;
417 case NS_ooxml::LN_CT_TabStop_pos:
418 m_pImpl->m_aCurrentTabStop.Position = ConversionHelper::convertTwipToMM100(nIntValue);
419 break;
421 case NS_ooxml::LN_CT_Fonts_ascii:
422 if (m_pImpl->GetTopContext())
424 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, uno::Any( sStringValue ));
426 break;
427 case NS_ooxml::LN_CT_Fonts_asciiTheme:
428 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeHandler::getStringForTheme(nIntValue));
429 if (m_pImpl->GetTopContext())
431 // note: overwrite Fonts_ascii with Fonts_asciiTheme *even if*
432 // theme font is empty - this is apparently what Word 2013 does
433 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
434 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, aPropValue );
435 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_ASCII, aPropValue, true, CHAR_GRAB_BAG );
436 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_ASCII, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
438 break;
439 case NS_ooxml::LN_CT_Fonts_hAnsi:
440 break;//unsupported
441 case NS_ooxml::LN_CT_Fonts_hAnsiTheme:
442 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeHandler::getStringForTheme(nIntValue));
443 if (m_pImpl->GetTopContext())
444 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_H_ANSI, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
445 break;
446 case NS_ooxml::LN_CT_Fonts_eastAsia:
447 if (m_pImpl->GetTopContext())
448 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::Any( sStringValue ));
449 break;
450 case NS_ooxml::LN_CT_Fonts_eastAsiaTheme:
451 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsiaTheme", ThemeHandler::getStringForTheme(nIntValue));
452 if (m_pImpl->GetTopContext())
454 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
455 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, aPropValue );
456 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_EAST_ASIA, aPropValue, true, CHAR_GRAB_BAG );
457 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_EAST_ASIA, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
459 break;
460 case NS_ooxml::LN_CT_Fonts_cs:
461 if (m_pImpl->GetTopContext())
462 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::Any( sStringValue ));
463 break;
464 case NS_ooxml::LN_CT_Fonts_cstheme:
465 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "cstheme", ThemeHandler::getStringForTheme(nIntValue));
466 if (m_pImpl->GetTopContext())
468 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
469 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aPropValue );
470 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_CS, aPropValue, true, CHAR_GRAB_BAG );
471 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_CS, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
473 break;
474 case NS_ooxml::LN_CT_Spacing_before:
475 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "before", OUString::number(nIntValue));
476 if (m_pImpl->GetTopContext())
477 // Don't overwrite NS_ooxml::LN_CT_Spacing_beforeAutospacing.
478 m_pImpl->GetTopContext()->Insert(
479 PROP_PARA_TOP_MARGIN,
480 uno::Any(static_cast<sal_Int32>(convertTwipToMm100(nIntValue))), false);
481 break;
482 case NS_ooxml::LN_CT_Spacing_beforeLines:
483 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "beforeLines", OUString::number(nIntValue));
484 // We would need to make sure that this doesn't overwrite any
485 // NS_ooxml::LN_CT_Spacing_before in parent styles before style
486 // sheet support can be enabled.
487 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
488 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
489 break;
490 case NS_ooxml::LN_CT_Spacing_after:
491 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "after", OUString::number(nIntValue));
492 if (m_pImpl->GetTopContext())
494 // Don't overwrite NS_ooxml::LN_CT_Spacing_afterAutospacing.
495 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
497 uno::Any aContextualSpacingFromStyle = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_CONTEXT_MARGIN);
498 if (aContextualSpacingFromStyle.hasValue())
499 // Setting "after" spacing means Writer doesn't inherit
500 // contextual spacing anymore from style, but Word does.
501 m_pImpl->GetTopContext()->Insert(PROP_PARA_CONTEXT_MARGIN, aContextualSpacingFromStyle);
503 break;
504 case NS_ooxml::LN_CT_Spacing_afterLines:
505 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "afterLines", OUString::number(nIntValue));
506 // We would need to make sure that this doesn't overwrite any
507 // NS_ooxml::LN_CT_Spacing_after in parent styles before style
508 // sheet support can be enabled.
509 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
510 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
511 break;
512 case NS_ooxml::LN_CT_Spacing_line: //91434
513 case NS_ooxml::LN_CT_Spacing_lineRule: //91435
515 style::LineSpacing aSpacing;
516 PropertyMapPtr pTopContext = m_pImpl->GetTopContext();
517 std::optional<PropertyMap::Property> aLineSpacingVal;
518 if (pTopContext && (aLineSpacingVal = pTopContext->getProperty(PROP_PARA_LINE_SPACING)) )
520 aLineSpacingVal->second >>= aSpacing;
522 else
524 //default to single line spacing
525 aSpacing.Mode = style::LineSpacingMode::FIX;
526 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
528 if( nName == NS_ooxml::LN_CT_Spacing_line )
530 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "line", OUString::number(nIntValue));
531 //now set the value depending on the Mode
532 if( aSpacing.Mode == style::LineSpacingMode::PROP )
533 aSpacing.Height = sal_Int16(nIntValue * 100 / nSingleLineSpacing );
534 else
535 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nIntValue ));
537 else //NS_ooxml::LN_CT_Spacing_lineRule:
539 // exactly, atLeast, auto
540 if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_auto)
542 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "auto");
543 if (aSpacing.Height >= 0)
545 aSpacing.Mode = style::LineSpacingMode::PROP;
546 //reinterpret the already set value
547 aSpacing.Height = sal_Int16( aSpacing.Height * 100 / ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
549 else
551 // Negative value still means a positive height,
552 // just the mode is "exact".
553 aSpacing.Mode = style::LineSpacingMode::FIX;
554 aSpacing.Height *= -1;
557 else if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast)
559 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "atLeast");
560 aSpacing.Mode = style::LineSpacingMode::MINIMUM;
562 else // NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact
564 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "exact");
565 aSpacing.Mode = style::LineSpacingMode::FIX;
568 if (pTopContext)
569 pTopContext->Insert(PROP_PARA_LINE_SPACING, uno::Any( aSpacing ));
571 break;
572 case NS_ooxml::LN_CT_Ind_start:
573 case NS_ooxml::LN_CT_Ind_left:
574 if (m_pImpl->GetTopContext())
576 // Word inherits FirstLineIndent property of the numbering, even if ParaLeftMargin is set, Writer does not.
577 // So copy it explicitly, if necessary.
578 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
579 sal_Int32 nIndentAt = m_pImpl->getCurrentNumberingProperty("IndentAt");
581 sal_Int32 nParaLeftMargin = ConversionHelper::convertTwipToMM100(nIntValue);
582 if (nParaLeftMargin != 0 && nIndentAt == nParaLeftMargin)
583 // Avoid direct left margin when it's the same as from the
584 // numbering.
585 break;
587 if (nFirstLineIndent != 0)
588 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::Any(nFirstLineIndent), /*bOverwrite=*/false);
590 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN,
591 uno::Any(nParaLeftMargin));
593 break;
594 case NS_ooxml::LN_CT_Ind_end:
595 case NS_ooxml::LN_CT_Ind_right:
596 if (m_pImpl->GetTopContext())
598 // Word inherits FirstLineIndent/ParaLeftMargin property of the numbering, even if ParaRightMargin is set, Writer does not.
599 // So copy it explicitly, if necessary.
600 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
601 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
603 if (nFirstLineIndent != 0)
604 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::Any(nFirstLineIndent), /*bOverwrite=*/false);
605 if (nParaLeftMargin != 0)
606 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::Any(nParaLeftMargin), /*bOverwrite=*/false);
608 m_pImpl->GetTopContext()->Insert(
609 PROP_PARA_RIGHT_MARGIN, uno::Any( ConversionHelper::convertTwipToMM100(nIntValue ) ));
611 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "right", OUString::number(nIntValue));
612 break;
613 case NS_ooxml::LN_CT_Ind_hanging:
614 if (m_pImpl->GetTopContext())
616 sal_Int32 nValue = ConversionHelper::convertTwipToMM100( nIntValue );
617 m_pImpl->GetTopContext()->Insert(
618 PROP_PARA_FIRST_LINE_INDENT, uno::Any( - nValue ));
620 // See above, need to inherit left margin from list style when first is set.
621 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
622 if (nParaLeftMargin != 0)
623 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::Any(nParaLeftMargin), /*bOverwrite=*/false);
625 break;
626 case NS_ooxml::LN_CT_Ind_firstLine:
627 if (m_pImpl->GetTopContext())
629 sal_Int32 nFirstLineIndent
630 = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
631 sal_Int32 nParaFirstLineIndent = ConversionHelper::convertTwipToMM100(nIntValue);
632 if (nParaFirstLineIndent != 0 && nFirstLineIndent == nParaFirstLineIndent)
633 // Avoid direct first margin when it's the same as from the
634 // numbering.
635 break;
636 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT,
637 uno::Any(nParaFirstLineIndent));
639 break;
640 case NS_ooxml::LN_CT_Ind_rightChars:
641 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "rightChars", OUString::number(nIntValue));
642 break;
644 case NS_ooxml::LN_CT_EastAsianLayout_id:
645 break;
646 case NS_ooxml::LN_CT_EastAsianLayout_combine:
647 if (m_pImpl->GetTopContext())
648 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_IS_ON, uno::Any ( nIntValue != 0 ));
649 break;
650 case NS_ooxml::LN_CT_EastAsianLayout_combineBrackets:
651 if (m_pImpl->GetTopContext())
653 OUString sCombinePrefix = getBracketStringFromEnum(nIntValue);
654 OUString sCombineSuffix = getBracketStringFromEnum(nIntValue, false);
655 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_PREFIX, uno::Any ( sCombinePrefix ));
656 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_SUFFIX, uno::Any ( sCombineSuffix ));
658 break;
659 case NS_ooxml::LN_CT_EastAsianLayout_vert:
660 if (m_pImpl->GetTopContext())
662 sal_Int16 nRotationAngle = (nIntValue ? 900 : 0);
663 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION, uno::Any ( nRotationAngle ));
665 break;
666 case NS_ooxml::LN_CT_EastAsianLayout_vertCompress:
667 if (m_pImpl->GetTopContext())
668 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION_IS_FIT_TO_LINE, uno::Any ( nIntValue != 0 ));
669 break;
671 case NS_ooxml::LN_CT_PageSz_code:
672 break;
673 case NS_ooxml::LN_CT_PageSz_h:
675 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100WithoutLimit(nIntValue);
676 CT_PageSz.h = PaperInfo::sloppyFitPageDimension(nHeight);
678 break;
679 case NS_ooxml::LN_CT_PageSz_orient:
680 CT_PageSz.orient = (nIntValue != NS_ooxml::LN_Value_ST_PageOrientation_portrait);
681 break;
682 case NS_ooxml::LN_CT_PageSz_w:
684 sal_Int32 nWidth = ConversionHelper::convertTwipToMM100WithoutLimit(nIntValue);
685 CT_PageSz.w = PaperInfo::sloppyFitPageDimension(nWidth);
687 break;
689 case NS_ooxml::LN_CT_PageMar_top:
690 m_pImpl->SetPageMarginTwip( PAGE_MAR_TOP, nIntValue );
691 break;
692 case NS_ooxml::LN_CT_PageMar_right:
693 m_pImpl->SetPageMarginTwip( PAGE_MAR_RIGHT, nIntValue );
694 break;
695 case NS_ooxml::LN_CT_PageMar_bottom:
696 m_pImpl->SetPageMarginTwip( PAGE_MAR_BOTTOM, nIntValue );
697 break;
698 case NS_ooxml::LN_CT_PageMar_left:
699 m_pImpl->SetPageMarginTwip( PAGE_MAR_LEFT, nIntValue );
700 break;
701 case NS_ooxml::LN_CT_PageMar_header:
702 m_pImpl->SetPageMarginTwip( PAGE_MAR_HEADER, nIntValue );
703 break;
704 case NS_ooxml::LN_CT_PageMar_footer:
705 m_pImpl->SetPageMarginTwip( PAGE_MAR_FOOTER, nIntValue );
706 break;
707 case NS_ooxml::LN_CT_PageMar_gutter:
708 m_pImpl->SetPageMarginTwip( PAGE_MAR_GUTTER, nIntValue );
709 break;
710 case NS_ooxml::LN_CT_PaperSource_first:
711 m_pImpl->SetPaperSource(PAPER_SOURCE_FIRST, nIntValue);
712 break;
713 case NS_ooxml::LN_CT_PaperSource_other:
714 m_pImpl->SetPaperSource(PAPER_SOURCE_OTHER, nIntValue);
715 break;
716 case NS_ooxml::LN_CT_Language_val: //90314
717 case NS_ooxml::LN_CT_Language_eastAsia: //90315
718 case NS_ooxml::LN_CT_Language_bidi: //90316
720 // store decimal symbol associated to the language of the document
721 if ( m_pImpl->IsDocDefaultsImport() && ( nName == NS_ooxml::LN_CT_Language_val ) )
723 LanguageTag aLanguageTag( sStringValue );
724 LocaleDataWrapper aLocaleWrapper( std::move(aLanguageTag) );
725 if ( aLocaleWrapper.getNumDecimalSep() == "," )
726 m_pImpl->SetIsDecimalComma();
729 if (nName == NS_ooxml::LN_CT_Language_eastAsia)
730 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsia", sStringValue);
731 else if (nName == NS_ooxml::LN_CT_Language_val)
732 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", sStringValue);
733 else if (nName == NS_ooxml::LN_CT_Language_bidi)
734 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "bidi", sStringValue);
735 lang::Locale aLocale;
736 if (sStringValue.getLength() <= 3 && sStringValue.getLength() >= 1)
738 // Cheesy Google Docs is known to tag language-only even for
739 // "en" or others that need some region to distinguish language
740 // variants for spell-checker and hyphenation. Obtain our known
741 // fallback to clarify and match. The original value/context is
742 // unknown anyway.
743 LanguageTag aLanguageTag( sStringValue);
744 aLanguageTag.makeFallback();
745 if (aLanguageTag.getLanguage() == sStringValue)
746 aLocale = aLanguageTag.getLocale();
747 else
749 // Do not fallback for an unknown language, which usually
750 // results in "en-US", or any other non-matching case.
751 aLocale = LanguageTag::convertToLocale( sStringValue);
754 else
756 aLocale = LanguageTag::convertToLocale( sStringValue);
758 if (m_pImpl->GetTopContext())
759 m_pImpl->GetTopContext()->Insert(NS_ooxml::LN_CT_Language_val== nName ? PROP_CHAR_LOCALE :
760 NS_ooxml::LN_CT_Language_eastAsia == nName ? PROP_CHAR_LOCALE_ASIAN : PROP_CHAR_LOCALE_COMPLEX,
761 uno::Any( aLocale ) );
763 break;
764 // See SwWW8ImplReader::GetParagraphAutoSpace() on why these are 100 and 280
765 case NS_ooxml::LN_CT_Spacing_beforeAutospacing:
767 sal_Int32 default_spacing = -1;
768 if (nIntValue)
770 m_pImpl->SetParaAutoBefore(true);
772 default_spacing = 100;
773 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
775 // 49 is just the old value that should be removed, once the
776 // root cause in SwTabFrm::MakeAll() is fixed.
777 if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
778 default_spacing = 49;
779 else
780 default_spacing = 280;
782 // required at export (here mainly for StyleSheets) to determine if the setting has changed from grab_bag
783 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(default_spacing)));
785 m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING, uno::Any( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG );
787 break;
788 case NS_ooxml::LN_CT_Spacing_afterAutospacing:
790 sal_Int32 default_spacing = -1;
791 if (nIntValue)
793 default_spacing = 100;
794 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
796 if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
797 default_spacing = 49;
798 else
799 default_spacing = 280;
801 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(default_spacing)));
803 m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING, uno::Any( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG );
805 break;
806 case NS_ooxml::LN_CT_SmartTagRun_uri:
807 m_pImpl->getSmartTagHandler().setURI(val.getString());
808 break;
809 case NS_ooxml::LN_CT_SmartTagRun_element:
810 m_pImpl->getSmartTagHandler().setElement(val.getString());
811 break;
812 case NS_ooxml::LN_CT_Br_type:
813 // Handled in the OOXMLBreakHandler dtor.
814 break;
815 case NS_ooxml::LN_CT_Br_clear:
816 m_pImpl->HandleLineBreakClear(val.getInt());
817 break;
818 case NS_ooxml::LN_CT_Fonts_hint :
819 /* assigns script type to ambiguous characters, values can be:
820 NS_ooxml::LN_Value_ST_Hint_default
821 NS_ooxml::LN_Value_ST_Hint_eastAsia
822 NS_ooxml::LN_Value_ST_Hint_cs
824 //TODO: unsupported?
825 break;
826 case NS_ooxml::LN_CT_TblBorders_right:
827 case NS_ooxml::LN_CT_TblBorders_top:
828 case NS_ooxml::LN_CT_TblBorders_left:
829 case NS_ooxml::LN_CT_TblBorders_bottom:
830 //todo: handle cell mar
831 break;
832 case NS_ooxml::LN_blip: // contains the binary graphic
833 case NS_ooxml::LN_shape:
835 //looks a bit like a hack - and it is. The graphic import is split into the inline_inline part and
836 //afterwards the adding of the binary data.
837 m_pImpl->m_eGraphicImportType = IMPORT_AS_DETECTED_INLINE; // really ???
838 m_pImpl->GetGraphicImport()->attribute(nName, val);
839 m_pImpl->ImportGraphic(val.getProperties());
841 break;
842 case NS_ooxml::LN_Value_math_ST_Jc_centerGroup:
843 case NS_ooxml::LN_Value_math_ST_Jc_center:
844 m_pImpl->appendStarMath(val);
845 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_CENTER));
846 break;
847 case NS_ooxml::LN_Value_math_ST_Jc_left:
848 m_pImpl->appendStarMath(val);
849 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_LEFT));
850 break;
851 case NS_ooxml::LN_Value_math_ST_Jc_right:
852 m_pImpl->appendStarMath(val);
853 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_RIGHT));
854 break;
855 case NS_ooxml::LN_starmath:
856 m_pImpl->appendStarMath(val);
857 break;
858 case NS_ooxml::LN_CT_FramePr_dropCap:
859 case NS_ooxml::LN_CT_FramePr_lines:
860 case NS_ooxml::LN_CT_FramePr_hAnchor:
861 case NS_ooxml::LN_CT_FramePr_vAnchor:
862 case NS_ooxml::LN_CT_FramePr_x:
863 case NS_ooxml::LN_CT_FramePr_xAlign:
864 case NS_ooxml::LN_CT_FramePr_y:
865 case NS_ooxml::LN_CT_FramePr_yAlign:
866 case NS_ooxml::LN_CT_FramePr_hRule:
867 case NS_ooxml::LN_CT_FramePr_w:
868 case NS_ooxml::LN_CT_FramePr_h:
869 case NS_ooxml::LN_CT_FramePr_wrap:
870 case NS_ooxml::LN_CT_FramePr_hSpace:
871 case NS_ooxml::LN_CT_FramePr_vSpace:
873 ParagraphPropertiesPropertyMap* pParaProperties = nullptr;
874 // handle frame properties at styles
875 if( m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET )
876 pParaProperties = dynamic_cast< ParagraphPropertiesPropertyMap*>( m_pImpl->GetTopContextOfType( CONTEXT_STYLESHEET ).get() );
877 else
878 pParaProperties = dynamic_cast< ParagraphPropertiesPropertyMap*>( m_pImpl->GetTopContextOfType( CONTEXT_PARAGRAPH ).get() );
880 if( pParaProperties )
882 switch( nName )
884 case NS_ooxml::LN_CT_FramePr_dropCap:
885 pParaProperties->props().SetDropCap( nIntValue );
886 break;
887 case NS_ooxml::LN_CT_FramePr_lines:
888 pParaProperties->props().SetLines( nIntValue );
889 break;
890 case NS_ooxml::LN_CT_FramePr_hAnchor:
891 switch(nIntValue)
893 case NS_ooxml::LN_Value_doc_ST_HAnchor_text: //relative to column
894 nIntValue = text::RelOrientation::FRAME; break;
895 case NS_ooxml::LN_Value_doc_ST_HAnchor_margin: nIntValue = text::RelOrientation::PAGE_PRINT_AREA; break;
896 case NS_ooxml::LN_Value_doc_ST_HAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
897 default:;
899 pParaProperties->props().SethAnchor( nIntValue );
900 break;
901 case NS_ooxml::LN_CT_FramePr_vAnchor:
902 switch(nIntValue)
904 case NS_ooxml::LN_Value_doc_ST_VAnchor_text: //relative to paragraph
905 nIntValue = text::RelOrientation::FRAME; break;
906 case NS_ooxml::LN_Value_doc_ST_VAnchor_margin:nIntValue = text::RelOrientation::PAGE_PRINT_AREA ; break;
907 case NS_ooxml::LN_Value_doc_ST_VAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
908 default:;
910 pParaProperties->props().SetvAnchor( nIntValue );
911 break;
912 case NS_ooxml::LN_CT_FramePr_x:
913 pParaProperties->props().Setx(
914 ConversionHelper::convertTwipToMM100(nIntValue ));
915 pParaProperties->props().SetxAlign( text::HoriOrientation::NONE );
916 break;
917 case NS_ooxml::LN_CT_FramePr_xAlign:
918 switch( nIntValue )
920 case NS_ooxml::LN_Value_doc_ST_XAlign_center : nIntValue = text::HoriOrientation::CENTER; break;
921 case NS_ooxml::LN_Value_doc_ST_XAlign_right : nIntValue = text::HoriOrientation::RIGHT; break;
922 case NS_ooxml::LN_Value_doc_ST_XAlign_inside : nIntValue = text::HoriOrientation::INSIDE; break;
923 case NS_ooxml::LN_Value_doc_ST_XAlign_outside : nIntValue = text::HoriOrientation::OUTSIDE; break;
924 case NS_ooxml::LN_Value_doc_ST_XAlign_left : nIntValue = text::HoriOrientation::LEFT; break;
925 default: nIntValue = text::HoriOrientation::NONE;
927 pParaProperties->props().SetxAlign( nIntValue );
928 break;
929 case NS_ooxml::LN_CT_FramePr_y:
930 pParaProperties->props().Sety(
931 ConversionHelper::convertTwipToMM100(nIntValue ));
932 pParaProperties->props().SetyAlign( text::VertOrientation::NONE );
933 break;
934 case NS_ooxml::LN_CT_FramePr_yAlign:
935 switch( nIntValue )
937 case NS_ooxml::LN_Value_doc_ST_YAlign_top :
938 case NS_ooxml::LN_Value_doc_ST_YAlign_inside :nIntValue = text::VertOrientation::TOP; break;
939 case NS_ooxml::LN_Value_doc_ST_YAlign_center :nIntValue = text::VertOrientation::CENTER;break;
940 case NS_ooxml::LN_Value_doc_ST_YAlign_bottom :
941 case NS_ooxml::LN_Value_doc_ST_YAlign_outside :nIntValue = text::VertOrientation::BOTTOM;break;
942 case NS_ooxml::LN_Value_doc_ST_YAlign_inline :
944 // HACK: This is for bnc#780851, where a table has one cell that has w:framePr,
945 // which causes that paragraph to be converted to a text frame, and the original
946 // paragraph object no longer exists, which makes table creation fail and furthermore
947 // it would be missing in the table layout anyway. So actually no letting that paragraph
948 // be a text frame "fixes" it. I'm not sure what "inline" is supposed to mean in practice
949 // anyway, so as long as this doesn't cause trouble elsewhere ...
950 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
951 if( pContext )
953 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
954 if (pParaContext)
955 pParaContext->props().SetFrameMode(false);
957 nIntValue = text::VertOrientation::NONE;
958 break;
960 default:
961 nIntValue = text::VertOrientation::NONE;
962 break;
964 pParaProperties->props().SetyAlign( nIntValue );
965 break;
966 case NS_ooxml::LN_CT_FramePr_hRule:
967 switch( nIntValue )
969 case NS_ooxml::LN_Value_doc_ST_HeightRule_exact:
970 nIntValue = text::SizeType::FIX;
971 break;
972 case NS_ooxml::LN_Value_doc_ST_HeightRule_atLeast:
973 nIntValue = text::SizeType::MIN;
974 break;
975 case NS_ooxml::LN_Value_doc_ST_HeightRule_auto:
976 //no break;
977 default:;
978 nIntValue = text::SizeType::VARIABLE;
980 pParaProperties->props().SethRule( nIntValue );
981 break;
982 case NS_ooxml::LN_CT_FramePr_wrap:
984 //should be either LN_Value_doc_ST_Wrap_notBeside or LN_Value_doc_ST_Wrap_around or LN_Value_doc_ST_Wrap_auto
985 OSL_ENSURE( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
986 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_notBeside ||
987 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
988 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none ||
989 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto,
990 "wrap not around, not_Beside, through, none or auto?");
991 if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
992 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto )
993 pParaProperties->props().SetWrap ( text::WrapTextMode_DYNAMIC ) ;
994 else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around)
995 pParaProperties->props().SetWrap(text::WrapTextMode_PARALLEL);
996 else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none)
997 pParaProperties->props().SetWrap ( text::WrapTextMode_THROUGH ) ;
998 else
999 pParaProperties->props().SetWrap ( text::WrapTextMode_NONE ) ;
1001 break;
1002 case NS_ooxml::LN_CT_FramePr_w:
1003 pParaProperties->props().Setw(
1004 ConversionHelper::convertTwipToMM100(nIntValue));
1005 break;
1006 case NS_ooxml::LN_CT_FramePr_h:
1007 pParaProperties->props().Seth(
1008 ConversionHelper::convertTwipToMM100(nIntValue));
1009 break;
1010 case NS_ooxml::LN_CT_FramePr_hSpace:
1011 pParaProperties->props().SethSpace(
1012 ConversionHelper::convertTwipToMM100(nIntValue ));
1013 break;
1014 case NS_ooxml::LN_CT_FramePr_vSpace:
1015 pParaProperties->props().SetvSpace(
1016 ConversionHelper::convertTwipToMM100(nIntValue ));
1017 break;
1018 default:;
1022 break;
1023 case NS_ooxml::LN_CT_TrackChange_author:
1024 m_pImpl->SetCurrentRedlineAuthor( sStringValue );
1025 break;
1026 case NS_ooxml::LN_CT_TrackChange_date:
1027 m_pImpl->SetCurrentRedlineDate( sStringValue );
1028 break;
1029 case NS_ooxml::LN_CT_Markup_id:
1030 m_pImpl->SetCurrentRedlineId( nIntValue );
1031 break;
1032 case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart:
1033 m_pImpl->AddAnnotationPosition( true, nIntValue );
1034 break;
1035 case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd:
1036 m_pImpl->AddAnnotationPosition( false, nIntValue );
1037 break;
1038 case NS_ooxml::LN_CT_Comment_initials:
1039 m_pImpl->SetCurrentRedlineInitials(sStringValue);
1040 break;
1041 case NS_ooxml::LN_token:
1042 m_pImpl->SetCurrentRedlineToken( nIntValue );
1043 break;
1044 case NS_ooxml::LN_CT_LineNumber_start:
1045 case NS_ooxml::LN_CT_LineNumber_distance:
1046 case NS_ooxml::LN_CT_LineNumber_countBy:
1047 case NS_ooxml::LN_CT_LineNumber_restart:
1049 //line numbering in Writer is a global document setting
1050 //in Word is a section setting
1051 //if line numbering is switched on anywhere in the document it's set at the global settings
1052 LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
1053 switch( nName )
1055 case NS_ooxml::LN_CT_LineNumber_countBy:
1056 aSettings.nInterval = nIntValue;
1057 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1058 if( pSectionContext )
1059 pSectionContext->SetLnnMod( nIntValue );
1060 break;
1061 case NS_ooxml::LN_CT_LineNumber_start:
1062 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1063 if( pSectionContext )
1064 pSectionContext->SetLnnMin( nIntValue );
1065 break;
1066 case NS_ooxml::LN_CT_LineNumber_distance:
1067 aSettings.nDistance = ConversionHelper::convertTwipToMM100( nIntValue );
1068 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1069 if( pSectionContext )
1070 pSectionContext->SetdxaLnn( nIntValue );
1071 break;
1072 case NS_ooxml::LN_CT_LineNumber_restart:
1073 aSettings.bRestartAtEachPage = nIntValue == NS_ooxml::LN_Value_ST_LineNumberRestart_newPage;
1074 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1075 if( pSectionContext )
1076 pSectionContext->SetLnc( nIntValue );
1077 break;
1078 default:;
1080 m_pImpl->SetLineNumberSettings( aSettings );
1082 break;
1083 case NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows:
1084 m_pImpl->StartCustomFootnote(m_pImpl->GetTopContext());
1085 break;
1086 case NS_ooxml::LN_CT_FtnEdnRef_id:
1087 // footnote or endnote reference id - not needed
1088 break;
1089 case NS_ooxml::LN_CT_DocGrid_linePitch:
1091 //see SwWW8ImplReader::SetDocumentGrid
1092 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1093 if(pSectionContext)
1095 pSectionContext->SetGridLinePitch( ConversionHelper::convertTwipToMM100( nIntValue ) );
1098 break;
1099 case NS_ooxml::LN_CT_DocGrid_charSpace:
1101 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1102 if(pSectionContext)
1104 pSectionContext->SetDxtCharSpace( nIntValue );
1107 break;
1108 case NS_ooxml::LN_CT_DocGrid_type:
1110 if (pSectionContext != nullptr)
1112 switch( nIntValue )
1114 case NS_ooxml::LN_Value_doc_ST_DocGrid_default:
1115 pSectionContext->SetGridType(text::TextGridMode::NONE);
1116 break;
1117 case NS_ooxml::LN_Value_doc_ST_DocGrid_lines:
1118 pSectionContext->SetGridType(text::TextGridMode::LINES);
1119 break;
1120 case NS_ooxml::LN_Value_doc_ST_DocGrid_linesAndChars:
1121 pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
1122 pSectionContext->SetGridSnapToChars( false );
1123 break;
1124 case NS_ooxml::LN_Value_doc_ST_DocGrid_snapToChars:
1125 pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
1126 pSectionContext->SetGridSnapToChars( true );
1127 break;
1128 default :
1129 OSL_FAIL("unknown SwTextGrid value");
1133 break;
1134 case NS_ooxml::LN_CT_SdtBlock_sdtContent:
1135 case NS_ooxml::LN_CT_SdtRun_sdtContent:
1137 m_pImpl->m_pSdtHelper->SetSdtType(nName);
1139 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::unknown)
1141 // Still not determined content type? and it is even not unsupported? Then it is plain text field
1142 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::plainText);
1144 if (nName == NS_ooxml::LN_CT_SdtRun_sdtContent)
1146 if (m_pImpl->GetSdtStarts().empty() && m_pImpl->m_pSdtHelper->hasUnusedText())
1148 // A non-inline SDT is already started, first convert that to a field and only
1149 // then map the inline SDT to a content control.
1150 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText)
1152 m_pImpl->m_pSdtHelper->createPlainTextControl();
1156 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
1157 if (pContext && m_pImpl->isBreakDeferred(PAGE_BREAK))
1159 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape()
1160 && !m_pImpl->IsInComments())
1162 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
1164 m_pImpl->m_bIsSplitPara = true;
1165 finishParagraph();
1166 lcl_startParagraphGroup();
1168 else // IsFirstRun
1170 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
1172 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
1176 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
1177 m_pImpl->clearDeferredBreaks();
1180 else if (pContext && m_pImpl->isBreakDeferred(COLUMN_BREAK))
1182 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
1184 mbIsSplitPara = true;
1185 m_pImpl->m_bIsSplitPara = true;
1186 finishParagraph();
1187 lcl_startParagraphGroup();
1189 else // IsFirstRun
1191 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
1193 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
1197 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
1198 m_pImpl->clearDeferredBreaks();
1201 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::richText);
1202 m_pImpl->PushSdt();
1203 break;
1205 m_pImpl->SetSdt(true);
1207 break;
1208 case NS_ooxml::LN_CT_SdtBlock_sdtEndContent:
1209 case NS_ooxml::LN_CT_SdtRun_sdtEndContent:
1210 if (nName == NS_ooxml::LN_CT_SdtRun_sdtEndContent)
1212 // Inline SDT.
1213 switch (m_pImpl->m_pSdtHelper->getControlType())
1215 case SdtControlType::richText:
1216 case SdtControlType::plainText:
1217 case SdtControlType::checkBox:
1218 case SdtControlType::dropDown:
1219 case SdtControlType::comboBox:
1220 case SdtControlType::picture:
1221 case SdtControlType::datePicker:
1222 m_pImpl->PopSdt();
1223 break;
1224 default:
1225 break;
1229 m_pImpl->SetSdt(false);
1231 // It's not possible to insert the relevant property to the character context here:
1232 // the previous, already sent character context may be still active, so the property would be lost.
1233 if (m_pImpl->m_pSdtHelper->isOutsideAParagraph())
1234 m_pImpl->setParaSdtEndDeferred(true);
1235 else
1236 m_pImpl->setSdtEndDeferred(true);
1238 switch (m_pImpl->m_pSdtHelper->getControlType())
1240 case SdtControlType::dropDown:
1241 case SdtControlType::comboBox:
1242 m_pImpl->m_pSdtHelper->createDropDownControl();
1243 break;
1244 case SdtControlType::plainText:
1245 m_pImpl->m_pSdtHelper->createPlainTextControl();
1246 break;
1247 case SdtControlType::datePicker:
1248 m_pImpl->m_pSdtHelper->createDateContentControl();
1249 break;
1250 case SdtControlType::unknown:
1251 default:;
1253 break;
1254 case NS_ooxml::LN_CT_SdtListItem_displayText:
1255 m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().push_back(sStringValue);
1256 break;
1257 case NS_ooxml::LN_CT_SdtListItem_value:
1258 m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue);
1259 break;
1260 case NS_ooxml::LN_CT_SdtDate_fullDate:
1261 m_pImpl->m_pSdtHelper->getDate().append(sStringValue);
1262 break;
1263 case NS_ooxml::LN_CT_Background_color:
1264 if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape())
1265 m_pImpl->m_oBackgroundColor = nIntValue;
1266 break;
1267 case NS_ooxml::LN_CT_PageNumber_start:
1268 if (pSectionContext != nullptr && !m_pImpl->IsAltChunk())
1269 pSectionContext->SetPageNumber(nIntValue);
1270 break;
1271 case NS_ooxml::LN_CT_PageNumber_fmt:
1272 if (pSectionContext)
1274 sal_Int16 nNumberType = ConversionHelper::ConvertNumberingType(nIntValue, -1);
1275 if (nNumberType != -1)
1276 pSectionContext->SetPageNumberType(nNumberType);
1278 break;
1279 case NS_ooxml::LN_CT_FtnEdn_type:
1280 // This is the "separator" footnote, ignore its linebreaks/text.
1281 if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator)
1282 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::ON );
1283 else
1284 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
1285 break;
1286 case NS_ooxml::LN_CT_FtnEdn_id:
1288 SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
1289 if ( eSkip == SkipFootnoteSeparator::ON )
1290 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
1291 else if ( eSkip == SkipFootnoteSeparator::SKIPPING )
1292 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
1294 break;
1295 case NS_ooxml::LN_CT_DataBinding_prefixMappings:
1296 m_pImpl->m_pSdtHelper->setDataBindingPrefixMapping(sStringValue);
1297 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_prefixMappings", sStringValue);
1298 break;
1299 case NS_ooxml::LN_CT_DataBinding_xpath:
1300 m_pImpl->m_pSdtHelper->setDataBindingXPath(sStringValue);
1301 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_xpath", sStringValue);
1302 break;
1303 case NS_ooxml::LN_CT_DataBinding_storeItemID:
1304 m_pImpl->m_pSdtHelper->setDataBindingStoreItemID(sStringValue);
1305 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_storeItemID", sStringValue);
1306 break;
1307 case NS_ooxml::LN_CT_SdtPlaceholder_docPart_val:
1308 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtPlaceholder_docPart_val", sStringValue);
1309 m_pImpl->m_pSdtHelper->SetPlaceholderDocPart(sStringValue);
1310 break;
1311 case NS_ooxml::LN_CT_SdtColor_val:
1312 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtColor_val", sStringValue);
1313 m_pImpl->m_pSdtHelper->SetColor(sStringValue);
1314 break;
1315 case NS_ooxml::LN_CT_SdtAppearance_val:
1316 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtAppearance_val", sStringValue);
1317 m_pImpl->m_pSdtHelper->SetAppearance(sStringValue);
1318 break;
1319 case NS_ooxml::LN_CT_SdtText_multiLine:
1320 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtText_multiLine", sStringValue);
1321 break;
1322 case NS_ooxml::LN_CT_PTab_leader:
1323 case NS_ooxml::LN_CT_PTab_relativeTo:
1324 break;
1325 case NS_ooxml::LN_CT_PTab_alignment:
1326 m_pImpl->HandlePTab(nIntValue);
1327 break;
1328 case NS_ooxml::LN_CT_Cnf_lastRowLastColumn:
1329 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowLastColumn", OUString::number(nIntValue));
1330 break;
1331 case NS_ooxml::LN_CT_Cnf_lastRowFirstColumn:
1332 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowFirstColumn", OUString::number(nIntValue));
1333 break;
1334 case NS_ooxml::LN_CT_Cnf_firstRowLastColumn:
1335 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowLastColumn", OUString::number(nIntValue));
1336 break;
1337 case NS_ooxml::LN_CT_Cnf_oddHBand:
1338 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddHBand", OUString::number(nIntValue));
1339 break;
1340 case NS_ooxml::LN_CT_Cnf_firstRowFirstColumn:
1341 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowFirstColumn", OUString::number(nIntValue));
1342 break;
1343 case NS_ooxml::LN_CT_Cnf_evenVBand:
1344 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenVBand", OUString::number(nIntValue));
1345 break;
1346 case NS_ooxml::LN_CT_Cnf_evenHBand:
1347 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenHBand", OUString::number(nIntValue));
1348 break;
1349 case NS_ooxml::LN_CT_Cnf_lastColumn:
1350 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastColumn", OUString::number(nIntValue));
1351 break;
1352 case NS_ooxml::LN_CT_Cnf_firstColumn:
1353 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstColumn", OUString::number(nIntValue));
1354 break;
1355 case NS_ooxml::LN_CT_Cnf_oddVBand:
1356 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddVBand", OUString::number(nIntValue));
1357 break;
1358 case NS_ooxml::LN_CT_Cnf_lastRow:
1359 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRow", OUString::number(nIntValue));
1360 break;
1361 case NS_ooxml::LN_CT_Cnf_firstRow:
1362 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRow", OUString::number(nIntValue));
1363 break;
1364 case NS_ooxml::LN_CT_Cnf_val:
1365 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "val", sStringValue);
1366 break;
1367 case NS_ooxml::LN_CT_DocPartName_val:
1369 m_sGlossaryEntryName = sStringValue;
1370 break;
1372 case NS_ooxml::LN_CT_DocPartGallery_val:
1374 const OUString& sGlossaryEntryGallery = sStringValue;
1375 if(m_pImpl->GetTopContext())
1377 OUString sName = sGlossaryEntryGallery + ":" + m_sGlossaryEntryName;
1378 // Add glossary entry name as a first paragraph in section
1379 m_pImpl->appendTextPortion(sName, m_pImpl->GetTopContext());
1381 break;
1383 case NS_ooxml::LN_CT_PermStart_ed:
1385 m_pImpl->setPermissionRangeEd(sStringValue);
1386 break;
1388 case NS_ooxml::LN_CT_PermStart_edGrp:
1390 m_pImpl->setPermissionRangeEdGrp(sStringValue);
1391 break;
1393 case NS_ooxml::LN_CT_PermStart_id:
1395 m_pImpl->startOrEndPermissionRange(nIntValue);
1396 break;
1398 case NS_ooxml::LN_CT_PermEnd_id:
1400 m_pImpl->startOrEndPermissionRange(nIntValue);
1401 break;
1403 case NS_ooxml::LN_CT_NumFmt_val:
1407 uno::Reference<beans::XPropertySet> xFtnEdnSettings;
1408 if (m_pImpl->IsInFootnoteProperties())
1410 uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(
1411 m_pImpl->GetTextDocument(), uno::UNO_QUERY);
1412 if (xFootnotesSupplier.is())
1413 xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings();
1415 else
1417 uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(
1418 m_pImpl->GetTextDocument(), uno::UNO_QUERY);
1419 if (xEndnotesSupplier.is())
1420 xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings();
1422 if (xFtnEdnSettings.is())
1424 sal_Int16 nNumType = ConversionHelper::ConvertNumberingType(nIntValue);
1425 xFtnEdnSettings->setPropertyValue(getPropertyName(PROP_NUMBERING_TYPE),
1426 uno::Any(nNumType));
1429 catch (const uno::Exception&)
1433 break;
1434 case NS_ooxml::LN_CT_AltChunk:
1436 m_pImpl->HandleAltChunk(sStringValue);
1438 break;
1439 case NS_ooxml::LN_AG_Parids_paraId:
1440 if (ParagraphPropertyMap* pParaContext
1441 = dynamic_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContext().get()))
1443 pParaContext->props().SetParaId(sStringValue);
1445 break;
1446 case NS_ooxml::LN_OfficeArtExtension_Decorative_val:
1447 m_pImpl->GetGraphicImport()->attribute(nName, val);
1448 break;
1449 default:
1450 SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName);
1454 void DomainMapper::lcl_sprm(Sprm & rSprm)
1456 if (!m_pImpl->hasTableManager() || !m_pImpl->getTableManager().sprm(rSprm))
1457 sprmWithProps(rSprm, m_pImpl->GetTopContext());
1460 // In rtl-paragraphs the meaning of left/right are to be exchanged
1461 static bool ExchangeLeftRight(const PropertyMapPtr& rContext, DomainMapper_Impl& rImpl)
1463 bool bExchangeLeftRight = false;
1464 sal_Int32 aAdjust;
1465 uno::Any aPropPara = rImpl.GetAnyProperty(PROP_WRITING_MODE, rContext);
1466 if( (aPropPara >>= aAdjust) && aAdjust == text::WritingMode2::RL_TB )
1467 bExchangeLeftRight = true;
1468 return bExchangeLeftRight;
1471 void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
1473 // These SPRM's are not specific to any section, so it's expected that there is no context yet.
1474 switch (rSprm.getId())
1476 case NS_ooxml::LN_background_background:
1478 // if a VML background has been defined, it was imported into a shape to hold the properties
1479 uno::Reference<drawing::XShape> xFill(m_pImpl->PopPendingShape());
1480 if (xFill.is())
1482 assert(!m_pImpl->GetTopContext());
1483 assert(m_pImpl->GetIsFirstParagraphInShape());
1484 assert(mbWasShapeInPara);
1485 assert(m_pImpl->GetIsFirstParagraphInSection());
1486 assert(m_pImpl->IsOutsideAParagraph());
1487 if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape())
1489 // apply the XATTR_FILL attributes to the default page style
1490 const uno::Reference<beans::XPropertySet> xFillPropertySet(xFill, uno::UNO_QUERY);
1491 const uno::Reference<beans::XPropertySetInfo> xFillInfo
1492 = xFillPropertySet->getPropertySetInfo();
1493 uno::Reference<beans::XPropertySet> xPS(
1494 m_pImpl->GetPageStyles()->getByName("Standard"), uno::UNO_QUERY_THROW);
1495 for (const beans::Property& rProp : xPS->getPropertySetInfo()->getProperties())
1497 if (rProp.Name == "FillComplexColor" || rProp.Name == "FillGradientName"
1498 || rProp.Name == "FillGradientStepCount"
1499 || rProp.Name == "FillTransparenceGradientName"
1500 || rProp.Name == "FillBitmapURL" || rProp.Name == "FillColor2")
1502 // silence exceptions for unsupported stuff when appling to page style
1503 continue;
1505 if (!rProp.Name.startsWith("Fill"))
1506 continue;
1508 if (!xFillInfo->hasPropertyByName(rProp.Name))
1509 continue;
1513 const uno::Any aFillValue = xFillPropertySet->getPropertyValue(rProp.Name);
1514 xPS->setPropertyValue(rProp.Name, aFillValue);
1516 catch (uno::Exception&)
1518 DBG_UNHANDLED_EXCEPTION("writerfilter", "Exception setting page background fill");
1522 m_pImpl->m_bCopyStandardPageStyleFill = true;
1525 // The background was unhelpfully imported into the text body: remove it
1526 uno::Reference<lang::XComponent> xComponent(xFill, uno::UNO_QUERY_THROW);
1527 xComponent->dispose();
1529 m_pImpl->SetIsFirstParagraphInShape(false);
1530 mbWasShapeInPara = false;
1532 return;
1534 default:
1535 break;
1538 OSL_ENSURE(rContext, "PropertyMap has to be valid!");
1539 if(!rContext)
1540 return ;
1542 sal_uInt32 nSprmId = rSprm.getId();
1543 //needed for page properties
1544 SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
1545 Value::Pointer_t pValue = rSprm.getValue();
1546 sal_Int32 nIntValue = pValue->getInt();
1547 const OUString sStringValue = pValue->getString();
1549 switch(nSprmId)
1551 case NS_ooxml::LN_CT_PPrBase_jc:
1553 bool bExchangeLeftRight = !IsRTFImport() && !m_pImpl->IsInComments() && ExchangeLeftRight(rContext, *m_pImpl);
1554 handleParaJustification(nIntValue, rContext, bExchangeLeftRight);
1555 break;
1557 case NS_ooxml::LN_CT_PPrBase_keepLines:
1558 rContext->Insert(PROP_PARA_SPLIT, uno::Any(nIntValue == 0));
1559 break;
1560 case NS_ooxml::LN_CT_PPrBase_keepNext:
1561 rContext->Insert(PROP_PARA_KEEP_TOGETHER, uno::Any( nIntValue != 0 ) );
1562 break;
1563 case NS_ooxml::LN_CT_PPrBase_pageBreakBefore:
1564 rContext->Insert(PROP_BREAK_TYPE, uno::Any(nIntValue ? style::BreakType_PAGE_BEFORE : style::BreakType_NONE), /*bOverwrite=*/bool(nIntValue));
1565 break;
1566 case NS_ooxml::LN_CT_NumPr_ilvl:
1567 if (nIntValue < 0 || 10 <= nIntValue)
1569 SAL_INFO("writerfilter",
1570 "unsupported numbering level " << nIntValue);
1571 break;
1573 if( IsStyleSheetImport() )
1575 //style sheets cannot have a numbering rule attached
1576 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1577 if (pStyleSheetPropertyMap)
1578 pStyleSheetPropertyMap->SetListLevel( static_cast<sal_Int16>(nIntValue) );
1580 // 0-8 are the 9 levels that Microsoft supports. (LO supports 10 levels).
1581 // 9 indicates "no numbering", for which LO has no corresponding concept,
1582 // and so it will be treated as the 10th level.
1583 // finishParagraph() will convert the 9 into "no numbering" for direct formatting.
1584 // (Styles only use this PROP for round-tripping and UI, but cannot trust it for import)
1585 if (!IsStyleSheetImport() || nIntValue != 9)
1586 rContext->Insert(PROP_NUMBERING_LEVEL, uno::Any(static_cast<sal_Int16>(nIntValue)));
1587 break;
1588 case NS_ooxml::LN_CT_NumPr_numId:
1590 //convert the ListTable entry to a NumberingRules property and apply it
1591 ListsManager::Pointer pListTable = m_pImpl->GetListTable();
1592 ListDef::Pointer pList = pListTable->GetList( nIntValue );
1593 if( IsStyleSheetImport() )
1595 //style sheets cannot have a numbering rule attached
1596 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1597 if (pStyleSheetPropertyMap)
1598 pStyleSheetPropertyMap->props().SetListId( nIntValue );
1600 if( pList )
1602 if( !IsStyleSheetImport() )
1604 uno::Any aRules( pList->GetNumberingRules( ) );
1605 rContext->Insert( PROP_NUMBERING_RULES, aRules );
1606 rContext->Erase( PROP_NUMBERING_STYLE_NAME);
1607 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
1608 if (pContext)
1610 assert(dynamic_cast<ParagraphPropertyMap*>(pContext.get()));
1611 static_cast<ParagraphPropertyMap*>(pContext.get())->props().SetListId(pList->GetId());
1614 // Indentation can came from:
1615 // 1) Paragraph style's numbering's indentation: the current non-style numId has priority over it.
1616 // 2) Numbering's indentation: Writer handles that natively, so it should not be set on rContext.
1617 // 3) Paragraph style's indentation: ditto.
1618 // 4) Direct paragraph formatting: that will came later.
1619 // So no situation where keeping indentation at this point would make sense -> erase.
1620 rContext->Erase(PROP_PARA_FIRST_LINE_INDENT);
1621 rContext->Erase(PROP_PARA_LEFT_MARGIN);
1622 rContext->Erase(PROP_PARA_RIGHT_MARGIN);
1625 else
1627 if( !IsStyleSheetImport() )
1629 // eg. disabled numbering using non-existent numId "0"
1630 rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::Any( OUString() ) );
1631 // disable inheritance of indentation of parent styles
1632 rContext->Insert( PROP_PARA_LEFT_MARGIN, uno::Any( sal_Int32(0) ), /*bOverwrite=*/false);
1633 rContext->Insert( PROP_PARA_FIRST_LINE_INDENT,
1634 uno::Any( sal_Int32(0) ), /*bOverwrite=*/false);
1638 break;
1639 case NS_ooxml::LN_CT_PPrBase_suppressLineNumbers:
1640 rContext->Insert(PROP_PARA_LINE_NUMBER_COUNT, uno::Any( nIntValue == 0 ) );
1641 break;
1642 case NS_ooxml::LN_inTbl:
1643 break;
1644 case NS_ooxml::LN_tblDepth:
1645 //not handled via sprm but via text( 0x07 )
1646 break;
1647 case NS_ooxml::LN_CT_FramePr_w:
1648 break;
1649 case NS_ooxml::LN_CT_FramePr_wrap:
1650 break;
1652 case NS_ooxml::LN_CT_PrBase_pBdr: //paragraph border
1653 resolveSprmProps(*this, rSprm);
1654 break;
1655 case NS_ooxml::LN_CT_PBdr_top:
1656 case NS_ooxml::LN_CT_PBdr_left:
1657 case NS_ooxml::LN_CT_PBdr_bottom:
1658 case NS_ooxml::LN_CT_PBdr_right:
1659 case NS_ooxml::LN_CT_PBdr_between:
1661 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1662 if( pProperties )
1664 auto pBorderHandler = std::make_shared<BorderHandler>( true );
1665 pProperties->resolve(*pBorderHandler);
1666 PropertyIds eBorderId = PropertyIds::INVALID;
1667 PropertyIds eBorderComplexColorId = PropertyIds::INVALID;
1668 PropertyIds eBorderDistId = PropertyIds::INVALID;
1669 switch( nSprmId )
1671 case NS_ooxml::LN_CT_PBdr_top:
1672 eBorderId = PROP_TOP_BORDER;
1673 eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
1674 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
1675 break;
1676 case NS_ooxml::LN_CT_PBdr_left:
1677 eBorderId = PROP_LEFT_BORDER;
1678 eBorderComplexColorId = PROP_BORDER_LEFT_COMPLEX_COLOR;
1679 eBorderDistId = PROP_LEFT_BORDER_DISTANCE;
1680 break;
1681 case NS_ooxml::LN_CT_PBdr_bottom:
1682 eBorderId = PROP_BOTTOM_BORDER;
1683 eBorderComplexColorId = PROP_BORDER_BOTTOM_COMPLEX_COLOR;
1684 eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE;
1685 break;
1686 case NS_ooxml::LN_CT_PBdr_right:
1687 eBorderId = PROP_RIGHT_BORDER;
1688 eBorderComplexColorId = PROP_BORDER_RIGHT_COMPLEX_COLOR;
1689 eBorderDistId = PROP_RIGHT_BORDER_DISTANCE;
1690 break;
1691 case NS_ooxml::LN_CT_PBdr_between:
1692 if (m_pImpl->handlePreviousParagraphBorderInBetween())
1694 // If previous paragraph also had border in between property
1695 // then it is possible to emulate this border as top border
1696 // for current paragraph
1697 eBorderId = PROP_TOP_BORDER;
1698 eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
1699 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
1701 // Since there are borders in between, each paragraph will have own borders. No more joining
1702 rContext->Insert(PROP_PARA_CONNECT_BORDERS, uno::Any(false));
1703 break;
1704 default:;
1707 if (eBorderId != PropertyIds::INVALID)
1709 rContext->Insert(eBorderId, uno::Any(pBorderHandler->getBorderLine()));
1711 if (eBorderComplexColorId != PropertyIds::INVALID)
1713 auto aComplexColor = pBorderHandler->getComplexColor();
1714 auto xComplexColor = model::color::createXComplexColor(aComplexColor);
1715 rContext->Insert(eBorderComplexColorId, uno::Any(xComplexColor));
1717 if (eBorderDistId != PropertyIds::INVALID)
1719 rContext->Insert(eBorderDistId, uno::Any(pBorderHandler->getLineDistance()));
1721 if ( nSprmId == NS_ooxml::LN_CT_PBdr_right )
1723 table::ShadowFormat aFormat;
1724 // Word only allows shadows on visible borders
1725 if ( pBorderHandler->getShadow() && pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE )
1726 aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
1727 rContext->Insert(PROP_PARA_SHADOW_FORMAT, uno::Any(aFormat));
1731 break;
1732 case NS_ooxml::LN_CT_PBdr_bar:
1733 break;
1734 case NS_ooxml::LN_CT_PPrBase_suppressAutoHyphens:
1735 rContext->Insert(PROP_PARA_IS_HYPHENATION, uno::Any( nIntValue == 0 ));
1736 break;
1737 case NS_ooxml::LN_CT_FramePr_h:
1738 break;
1739 case NS_ooxml::LN_CT_PrBase_shd:
1741 //contains fore color, back color and shadow percentage, results in a brush
1742 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1743 if( pProperties )
1745 auto pCellColorHandler = std::make_shared<CellColorHandler>();
1746 pCellColorHandler->setOutputFormat( CellColorHandler::Paragraph );
1747 bool bEnableTempGrabBag = !pCellColorHandler->isInteropGrabBagEnabled();
1748 if( bEnableTempGrabBag )
1749 pCellColorHandler->enableInteropGrabBag( "TempShdPropsGrabBag" );
1751 pProperties->resolve(*pCellColorHandler);
1752 rContext->InsertProps(pCellColorHandler->getProperties().get());
1754 rContext->Insert(PROP_CHAR_THEME_FILL, pCellColorHandler->getInteropGrabBag().Value, true, PARA_GRAB_BAG);
1755 if(bEnableTempGrabBag)
1756 pCellColorHandler->disableInteropGrabBag();
1759 break;
1760 case NS_ooxml::LN_CT_FramePr_vSpace:
1761 break; // sprmPDyaFromText
1762 case NS_ooxml::LN_CT_FramePr_hSpace:
1763 break; // sprmPDxaFromText
1764 case NS_ooxml::LN_CT_FramePr_anchorLock:
1765 break;
1766 case NS_ooxml::LN_CT_PPrBase_widowControl:
1768 uno::Any aVal( uno::Any( sal_Int8(nIntValue ? 2 : 0 )));
1769 rContext->Insert( PROP_PARA_WIDOWS, aVal );
1770 rContext->Insert( PROP_PARA_ORPHANS, aVal );
1772 break; // sprmPFWidowControl
1773 case NS_ooxml::LN_CT_PPrBase_overflowPunct:
1774 rContext->Insert(PROP_PARA_IS_HANGING_PUNCTUATION, uno::Any( nIntValue == 0 ));
1775 break;
1776 case NS_ooxml::LN_CT_PPrBase_topLinePunct:
1777 break;
1778 case NS_ooxml::LN_CT_PPrBase_autoSpaceDE:
1779 break;
1780 case NS_ooxml::LN_CT_PPrBase_autoSpaceDN:
1781 break;
1782 case NS_ooxml::LN_CT_PPrBase_textAlignment:
1784 sal_Int16 nAlignment = 0;
1785 switch (nIntValue)
1787 case NS_ooxml::LN_Value_doc_ST_TextAlignment_top:
1788 nAlignment = 2;
1789 break;
1790 case NS_ooxml::LN_Value_doc_ST_TextAlignment_center:
1791 nAlignment = 3;
1792 break;
1793 case NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline:
1794 nAlignment = 1;
1795 break;
1796 case NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom:
1797 nAlignment = 4;
1798 break;
1799 case NS_ooxml::LN_Value_doc_ST_TextAlignment_auto:
1800 default:
1801 break;
1803 rContext->Insert( PROP_PARA_VERT_ALIGNMENT, uno::Any( nAlignment) );
1805 break;
1806 case NS_ooxml::LN_CT_PPrBase_textDirection:
1808 switch (nIntValue)
1810 case NS_ooxml::LN_Value_ST_TextDirection_tbRl: // ~ vert="eaVert"
1812 m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL);
1813 break;
1815 case NS_ooxml::LN_Value_ST_TextDirection_btLr: // ~ vert="vert270"
1817 m_pImpl->SetFrameDirection(text::WritingMode2::BT_LR);
1818 break;
1820 case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
1822 // East Asian character rotation is not implemented in LO, use ordinary LR_TB instead.
1823 m_pImpl->SetFrameDirection(text::WritingMode2::LR_TB);
1824 break;
1826 case NS_ooxml::LN_Value_ST_TextDirection_tbRlV: // ~ vert="vert"
1828 m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL90);
1829 break;
1831 case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
1832 // default in LO. Do not overwrite RL_TB set by bidi.
1833 break;
1834 case NS_ooxml::LN_Value_ST_TextDirection_tbLrV: // ~ vert="mongolianVert"
1836 m_pImpl->SetFrameDirection(text::WritingMode2::TB_LR);
1837 break;
1839 default:
1840 SAL_WARN("writerfilter", "DomainMapper::sprmWithProps: unhandled textDirection");
1843 break;
1844 case NS_ooxml::LN_CT_PPrBase_outlineLvl:
1846 if (nIntValue < WW_OUTLINE_MIN || nIntValue > WW_OUTLINE_MAX)
1847 break; // invalid value is ignored by MS Word
1849 if( IsStyleSheetImport() )
1851 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1852 if (pStyleSheetPropertyMap)
1853 pStyleSheetPropertyMap->SetOutlineLevel(nIntValue);
1855 else
1857 // convert MS body level (9) to LO body level (0) and equivalent outline levels
1858 sal_Int16 nLvl = nIntValue == WW_OUTLINE_MAX ? 0 : nIntValue + 1;
1859 rContext->Insert(PROP_OUTLINE_LEVEL, uno::Any ( nLvl ));
1862 break;
1863 case NS_ooxml::LN_CT_PPrBase_bidi:
1865 // Four situations to handle:
1866 // 1.) bidi same as previous setting: no adjust change
1867 // 2.) no previous adjust: set appropriate default for this bidi
1868 // 3.) previous adjust and bidi different from previous: swap adjusts
1869 // 4.) previous adjust and no previous bidi: RTL swaps adjust
1871 const sal_Int16 nWritingMode = nIntValue ? text::WritingMode2::RL_TB : text::WritingMode2::LR_TB;
1872 sal_Int16 nParentBidi = -1;
1873 m_pImpl->GetPropertyFromParaStyleSheet(PROP_WRITING_MODE) >>= nParentBidi;
1874 // Paragraph justification reverses its meaning in an RTL context.
1875 // 1. Only make adjustments if the BiDi changes.
1876 if (nParentBidi != nWritingMode && !IsRTFImport() && !m_pImpl->IsInComments())
1878 style::ParagraphAdjust eAdjust = style::ParagraphAdjust(-1);
1879 // 2. no adjust property exists yet
1880 if ( !(m_pImpl->GetAnyProperty(PROP_PARA_ADJUST, rContext) >>= eAdjust) )
1882 // RTL defaults to right adjust
1883 eAdjust = nIntValue ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
1884 rContext->Insert(PROP_PARA_ADJUST, uno::Any( eAdjust ), /*bOverwrite=*/false);
1886 // 3,4. existing adjust: if RTL, then swap. If LTR, but previous was RTL, also swap.
1887 else if ( nIntValue || nParentBidi == sal_Int16(text::WritingMode2::RL_TB) )
1889 if ( eAdjust == style::ParagraphAdjust_RIGHT )
1890 rContext->Insert(PROP_PARA_ADJUST, uno::Any( style::ParagraphAdjust_LEFT ));
1891 else if ( eAdjust == style::ParagraphAdjust_LEFT )
1892 rContext->Insert(PROP_PARA_ADJUST, uno::Any( style::ParagraphAdjust_RIGHT ));
1895 rContext->Insert(PROP_WRITING_MODE, uno::Any( nWritingMode ));
1898 break;
1899 case NS_ooxml::LN_EG_SectPrContents_bidi:
1900 if (pSectionContext != nullptr)
1902 const sal_Int16 writingMode = (nIntValue != 0) ? sal_Int16(text::WritingMode2::RL_TB) : sal_Int16(text::WritingMode2::LR_TB);
1903 pSectionContext->Insert(PROP_WRITING_MODE, uno::Any(writingMode));
1905 break;
1906 case NS_ooxml::LN_EG_SectPrContents_rtlGutter:
1907 if (pSectionContext != nullptr)
1909 bool bRtlGutter = nIntValue != 0;
1910 pSectionContext->Insert(PROP_RTL_GUTTER, uno::Any(bRtlGutter));
1912 break;
1913 case NS_ooxml::LN_EG_RPrBase_highlight:
1915 // MS Word completely ignores character highlighting in character styles.
1916 if ( IsStyleSheetImport() )
1918 const StyleSheetEntryPtr pCurrStyle = GetStyleSheetTable()->GetCurrentEntry();
1919 if ( pCurrStyle && pCurrStyle->m_nStyleTypeCode == STYLE_TYPE_CHAR )
1920 break;
1923 PropertyIds ePropertyId = m_pImpl->IsInComments() ? PROP_CHAR_BACK_COLOR : PROP_CHAR_HIGHLIGHT;
1925 // OOXML import uses an ID
1926 if( IsOOXMLImport() )
1928 sal_Int32 nColor = 0;
1929 if( getColorFromId(nIntValue, nColor) )
1930 rContext->Insert(ePropertyId, uno::Any(nColor));
1932 // RTF import uses the actual color value
1933 else if( IsRTFImport() )
1935 rContext->Insert(ePropertyId, uno::Any(nIntValue));
1938 break;
1939 case NS_ooxml::LN_EG_RPrBase_em:
1940 rContext->Insert(PROP_CHAR_EMPHASIS, uno::Any ( getEmphasisValue (nIntValue)));
1941 break;
1942 case NS_ooxml::LN_EG_RPrBase_emboss:
1943 case NS_ooxml::LN_EG_RPrBase_b:
1944 case NS_ooxml::LN_EG_RPrBase_bCs:
1945 case NS_ooxml::LN_EG_RPrBase_i:
1946 case NS_ooxml::LN_EG_RPrBase_iCs:
1947 case NS_ooxml::LN_EG_RPrBase_strike:
1948 case NS_ooxml::LN_EG_RPrBase_dstrike:
1949 case NS_ooxml::LN_EG_RPrBase_outline:
1950 case NS_ooxml::LN_EG_RPrBase_shadow:
1951 case NS_ooxml::LN_EG_RPrBase_caps:
1952 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1953 case NS_ooxml::LN_EG_RPrBase_vanish:
1954 case NS_ooxml::LN_EG_RPrBase_webHidden:
1956 PropertyIds ePropertyId = PROP_CHAR_WEIGHT; //initialized to prevent warning!
1957 switch( nSprmId )
1959 case NS_ooxml::LN_EG_RPrBase_b:
1960 case NS_ooxml::LN_EG_RPrBase_bCs:
1961 ePropertyId = nSprmId != NS_ooxml::LN_EG_RPrBase_bCs ? PROP_CHAR_WEIGHT : PROP_CHAR_WEIGHT_COMPLEX;
1962 break;
1963 case NS_ooxml::LN_EG_RPrBase_i:
1964 case NS_ooxml::LN_EG_RPrBase_iCs:
1965 ePropertyId = nSprmId == NS_ooxml::LN_EG_RPrBase_i ? PROP_CHAR_POSTURE : PROP_CHAR_POSTURE_COMPLEX;
1966 break;
1967 case NS_ooxml::LN_EG_RPrBase_strike:
1968 case NS_ooxml::LN_EG_RPrBase_dstrike:
1969 ePropertyId = PROP_CHAR_STRIKEOUT;
1970 break;
1971 case NS_ooxml::LN_EG_RPrBase_outline:
1972 ePropertyId = PROP_CHAR_CONTOURED;
1973 break;
1974 case NS_ooxml::LN_EG_RPrBase_shadow:
1975 ePropertyId = PROP_CHAR_SHADOWED;
1976 break;
1977 case NS_ooxml::LN_EG_RPrBase_caps:
1978 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1979 ePropertyId = PROP_CHAR_CASE_MAP;
1980 break;
1981 case NS_ooxml::LN_EG_RPrBase_vanish:
1982 case NS_ooxml::LN_EG_RPrBase_webHidden:
1983 ePropertyId = PROP_CHAR_HIDDEN;
1984 break;
1985 case NS_ooxml::LN_EG_RPrBase_emboss:
1986 ePropertyId = PROP_CHAR_RELIEF;
1987 break;
1989 //expected: 0,1,128,129
1990 if(nIntValue != 128) //inherited from paragraph - ignore
1992 if( nIntValue == 129) //inverted style sheet value
1994 //get value from style sheet and invert it
1995 sal_Int16 nStyleValue = 0;
1996 uno::Any aStyleVal = m_pImpl->GetPropertyFromParaStyleSheet(ePropertyId);
1997 if( !aStyleVal.hasValue() )
1999 nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
2000 4 : 1;
2002 else if(aStyleVal.getValueTypeClass() == uno::TypeClass_FLOAT )
2004 double fDoubleValue = 0;
2005 //only in case of awt::FontWeight
2006 aStyleVal >>= fDoubleValue;
2007 nIntValue = fDoubleValue > 100. ? 0 : 1;
2009 else if((aStyleVal >>= nStyleValue) ||
2010 (nStyleValue = static_cast<sal_Int16>(comphelper::getEnumAsINT32(aStyleVal))) >= 0 )
2012 nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
2013 nStyleValue ? 0 : 4 :
2014 nStyleValue ? 0 : 1;
2016 else
2018 OSL_FAIL( "what type was it");
2022 switch( nSprmId )
2024 case NS_ooxml::LN_EG_RPrBase_b:
2025 case NS_ooxml::LN_EG_RPrBase_bCs:
2027 uno::Any aBold( uno::Any( nIntValue ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL ) );
2029 rContext->Insert(ePropertyId, aBold );
2030 if( nSprmId != NS_ooxml::LN_EG_RPrBase_bCs )
2031 rContext->Insert(PROP_CHAR_WEIGHT_ASIAN, aBold );
2033 if (nSprmId == NS_ooxml::LN_EG_RPrBase_b)
2034 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "b", OUString::number(nIntValue));
2035 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_bCs)
2036 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "bCs", OUString::number(nIntValue));
2038 break;
2039 case NS_ooxml::LN_EG_RPrBase_i:
2040 case NS_ooxml::LN_EG_RPrBase_iCs:
2042 uno::Any aPosture( uno::Any( nIntValue ? awt::FontSlant_ITALIC : awt::FontSlant_NONE ) );
2043 rContext->Insert( ePropertyId, aPosture );
2044 if (nSprmId != NS_ooxml::LN_EG_RPrBase_iCs)
2045 rContext->Insert(PROP_CHAR_POSTURE_ASIAN, aPosture );
2046 if (nSprmId == NS_ooxml::LN_EG_RPrBase_i)
2047 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "i", OUString::number(nIntValue));
2049 break;
2050 case NS_ooxml::LN_EG_RPrBase_strike:
2052 const auto eStrike
2053 = nIntValue ? awt::FontStrikeout::SINGLE : awt::FontStrikeout::NONE;
2054 const bool bOverwrite(nIntValue);
2055 rContext->Insert(ePropertyId, uno::Any(eStrike), bOverwrite);
2057 break;
2058 case NS_ooxml::LN_EG_RPrBase_dstrike:
2060 const auto eStrike
2061 = nIntValue ? awt::FontStrikeout::DOUBLE : awt::FontStrikeout::NONE;
2062 const bool bOverwrite(nIntValue);
2063 rContext->Insert(ePropertyId, uno::Any(eStrike), bOverwrite);
2065 break;
2066 case NS_ooxml::LN_EG_RPrBase_outline:
2067 case NS_ooxml::LN_EG_RPrBase_shadow:
2068 case NS_ooxml::LN_EG_RPrBase_vanish:
2069 case NS_ooxml::LN_EG_RPrBase_webHidden:
2070 rContext->Insert(ePropertyId, uno::Any( nIntValue != 0 ));
2071 break;
2072 case NS_ooxml::LN_EG_RPrBase_smallCaps:
2073 // If smallcaps would be just disabled and another casemap is already inserted, don't do anything.
2074 if (nIntValue || !rContext->isSet(ePropertyId) )
2075 rContext->Insert(ePropertyId, uno::Any( nIntValue ? style::CaseMap::SMALLCAPS : style::CaseMap::NONE));
2076 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "smallCaps", OUString::number(nIntValue));
2077 break;
2078 case NS_ooxml::LN_EG_RPrBase_caps:
2079 rContext->Insert(ePropertyId,
2080 uno::Any( nIntValue ? style::CaseMap::UPPERCASE : style::CaseMap::NONE));
2081 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "caps", OUString::number(nIntValue));
2082 break;
2083 case NS_ooxml::LN_EG_RPrBase_emboss:
2084 rContext->Insert(ePropertyId,
2085 uno::Any( nIntValue ? awt::FontRelief::EMBOSSED : awt::FontRelief::NONE ));
2086 break;
2091 break;
2092 case NS_ooxml::LN_EG_RPrBase_sz:
2093 case NS_ooxml::LN_EG_RPrBase_szCs:
2095 //multiples of half points (12pt == 24)
2096 double fVal = double(nIntValue) / 2.;
2097 uno::Any aVal( fVal );
2098 if( NS_ooxml::LN_EG_RPrBase_szCs == nSprmId )
2100 rContext->Insert( PROP_CHAR_HEIGHT_COMPLEX, aVal );
2102 else
2104 const RubyInfo &aInfo = m_pImpl->GetRubyInfo();
2105 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt && aInfo.nHps > 0 )
2107 fVal = double(aInfo.nHps) / 2.;
2108 aVal <<= fVal;
2110 else if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase && aInfo.nHpsBaseText > 0 )
2112 fVal = double(aInfo.nHpsBaseText) / 2.;
2113 aVal <<= fVal;
2115 //Asian get the same value as Western
2116 rContext->Insert( PROP_CHAR_HEIGHT, aVal );
2117 rContext->Insert( PROP_CHAR_HEIGHT_ASIAN, aVal );
2119 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, (nSprmId == NS_ooxml::LN_EG_RPrBase_sz ? OUString("sz") : OUString("szCs")), OUString::number(nIntValue));
2121 break;
2122 case NS_ooxml::LN_EG_RPrBase_position:
2123 // The spec says 0 is the same as the lack of the value, so don't parse that.
2124 if ( nIntValue )
2126 if (!IsStyleSheetImport() && !IsNumberingImport())
2127 m_pImpl->deferCharacterProperty( nSprmId, uno::Any( nIntValue ));
2128 else if (!m_pImpl->IsDocDefaultsImport())
2130 // For some undocumented reason, MS Word seems to ignore this in docDefaults
2132 const StyleSheetEntryPtr pCurrStyle = GetStyleSheetTable()->GetCurrentEntry();
2133 if (pCurrStyle && pCurrStyle->m_nStyleTypeCode == STYLE_TYPE_PARA && nIntValue < 0)
2135 m_pImpl->deferCharacterProperty(nSprmId, uno::Any(nIntValue));
2136 break;
2139 // DON'T FIXME: Truly calculating this for Character Styles will be tricky,
2140 // because it depends on the final fontsize - regardless of
2141 // where it is set. So at the style level,
2142 // the escapement value would need to be grabbagged.
2143 // At appendText time the final fontsize needs to be determined, and then
2144 // the escapement can be calculated from the grabbag'd half-point value
2145 // and directly applied. Yuck.
2146 // It seems best to just treat charstyle escapement like
2147 // pre-commit e70df84352d3670508a4666c97df44f82c1ce934
2148 // which just assigned default values and ignored the actual/given escapement.
2149 sal_Int16 nEscapement = nIntValue > 0 ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB;
2150 sal_Int8 nProp = DFLT_ESC_PROP;
2151 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( nEscapement ) );
2152 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
2155 break;
2156 case NS_ooxml::LN_EG_RPrBase_spacing:
2158 //Kerning half point values
2159 //TODO: there are two kerning values -
2160 // in ww8par6.cxx NS_sprm::LN_CHpsKern is used as boolean AutoKerning
2161 sal_Int16 nResult = static_cast<sal_Int16>(ConversionHelper::convertTwipToMM100(nIntValue));
2162 if (m_pImpl->IsInComments())
2164 nResult = static_cast<sal_Int16>(nIntValue);
2166 rContext->Insert(PROP_CHAR_CHAR_KERNING, uno::Any(nResult));
2167 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", OUString::number(nIntValue));
2169 break;
2170 case NS_ooxml::LN_EG_RPrBase_kern: // auto kerning is bound to a minimum font size in Word - but not in Writer :-(
2171 rContext->Insert(PROP_CHAR_AUTO_KERNING, uno::Any( nIntValue != 0 ) );
2172 break;
2173 case NS_ooxml::LN_EG_RPrBase_w:
2174 // ST_TextScale must fall between 1% and 600% according to spec, otherwise resets to 100% according to experience
2175 if ((1 <= nIntValue) && (nIntValue <= 600))
2177 rContext->Insert(PROP_CHAR_SCALE_WIDTH,
2178 uno::Any( sal_Int16(nIntValue) ));
2180 else
2182 rContext->Insert(PROP_CHAR_SCALE_WIDTH,
2183 uno::Any( sal_Int16(100) ));
2185 break;
2186 case NS_ooxml::LN_EG_RPrBase_imprint:
2187 // FontRelief: NONE, EMBOSSED, ENGRAVED
2188 rContext->Insert(PROP_CHAR_RELIEF,
2189 uno::Any( nIntValue ? awt::FontRelief::ENGRAVED : awt::FontRelief::NONE ));
2190 break;
2191 case NS_ooxml::LN_EG_RPrBase_effect:
2192 // The file-format has many character animations. We have only
2193 // one, so we use it always. Suboptimal solution though.
2194 if (nIntValue != NS_ooxml::LN_Value_ST_TextEffect_none)
2195 rContext->Insert(PROP_CHAR_FLASH, uno::Any( true ));
2196 else
2197 rContext->Insert(PROP_CHAR_FLASH, uno::Any( false ));
2198 break;
2199 case NS_ooxml::LN_EG_RPrBase_rtl:
2200 break;
2201 case NS_ooxml::LN_EG_RPrBase_shd:
2203 //contains fore color, back color and shadow percentage, results in a brush
2204 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2205 if( pProperties )
2207 auto pCellColorHandler = std::make_shared<CellColorHandler>();
2208 pCellColorHandler->setOutputFormat( CellColorHandler::Character );
2209 pProperties->resolve(*pCellColorHandler);
2210 rContext->InsertProps(pCellColorHandler->getProperties().get());
2211 m_pImpl->GetTopContext()->Insert(PROP_CHAR_SHADING_MARKER, uno::Any(true), true, CHAR_GRAB_BAG );
2213 // EditEng doesn't have a corresponding property for Shading Value, so eliminate it.
2214 if (m_pImpl->IsInComments())
2215 rContext->Erase(PROP_CHAR_SHADING_VALUE);
2217 break;
2219 case NS_ooxml::LN_EG_SectPrContents_type:
2220 /* break type
2221 0 - No break
2222 1 - New Column
2223 2 - New page
2224 3 - Even page
2225 4 - odd page
2227 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2228 if(pSectionContext)
2230 //continuous break only allowed if it is not the only section break
2231 SectionPropertyMap* pLastContext = m_pImpl->GetLastSectionContext();
2232 if ( nIntValue != NS_ooxml::LN_Value_ST_SectionMark_continuous || pLastContext || m_pImpl->GetParaSectpr() )
2233 pSectionContext->SetBreakType( nIntValue );
2235 break;
2236 case NS_ooxml::LN_EG_SectPrContents_titlePg:
2238 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2239 if(pSectionContext)
2240 pSectionContext->SetTitlePage( nIntValue > 0 );//section has title page
2242 break;
2243 case 165:
2245 //page height, rounded to default values, default: 0x3dc0 twip
2246 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100( nIntValue );
2247 rContext->Insert( PROP_HEIGHT, uno::Any( PaperInfo::sloppyFitPageDimension( nHeight ) ) );
2249 break;
2250 case NS_ooxml::LN_EG_SectPrContents_textDirection:
2252 sal_Int16 nDirection = text::WritingMode2::LR_TB;
2253 switch( nIntValue )
2255 // East Asian 270deg rotation in lrTbV is not implemented in LO
2256 case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
2257 case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
2258 nDirection = text::WritingMode2::LR_TB; // =0
2259 break;
2260 case NS_ooxml::LN_Value_ST_TextDirection_tbRl:
2261 nDirection = text::WritingMode2::TB_RL; // =2
2262 break;
2263 // Word does not write btLr in sections, but LO would be able to use it.
2264 case NS_ooxml::LN_Value_ST_TextDirection_btLr:
2265 nDirection = text::WritingMode2::BT_LR; // =5
2266 break;
2267 // Word maps mongolian direction to tbRlV in sections in file save, as of Aug 2022.
2268 // From point of OOXML standard it would be tbLrV. Since tbRlV is currently not
2269 // implemented in LO for text direction in page styles, we follow Word here.
2270 case NS_ooxml::LN_Value_ST_TextDirection_tbRlV:
2271 case NS_ooxml::LN_Value_ST_TextDirection_tbLrV:
2272 nDirection = text::WritingMode2::TB_LR; // =3
2273 break;
2274 default:;
2277 PropertyMap * pTargetContext = rContext.get();
2279 if (pSectionContext)
2281 pTargetContext = pSectionContext;
2284 pTargetContext->Insert(PROP_WRITING_MODE, uno::Any( sal_Int16(nDirection) ) );
2286 break; // sprmSTextFlow
2287 // the following are not part of the official documentation
2288 case NS_ooxml::LN_CT_Tabs_tab:
2289 resolveSprmProps(*this, rSprm);
2290 m_pImpl->IncorporateTabStop(m_pImpl->m_aCurrentTabStop);
2291 m_pImpl->m_aCurrentTabStop = DeletableTabStop();
2292 break;
2293 case NS_ooxml::LN_CT_PPrBase_tabs:
2295 // Initialize tab stop vector from style sheet
2296 // fdo#81033: for RTF, a tab stop is inherited from the style if it
2297 // is also applied to the paragraph directly, and cleared if it is
2298 // not applied to the paragraph directly => don't InitTabStopFromStyle
2299 if ( !IsRTFImport() )
2301 uno::Any aValue = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_TAB_STOPS);
2302 uno::Sequence< style::TabStop > aStyleTabStops;
2303 if(aValue >>= aStyleTabStops)
2305 m_pImpl->InitTabStopFromStyle( aStyleTabStops );
2308 resolveSprmProps(*this, rSprm);
2309 rContext->Insert(PROP_PARA_TAB_STOPS, uno::Any( m_pImpl->GetCurrentTabStopAndClear()));
2311 break;
2313 case NS_ooxml::LN_CT_DocDefaults_pPrDefault:
2314 case NS_ooxml::LN_CT_DocDefaults_rPrDefault:
2315 GetStyleSheetTable()->sprm( rSprm );
2316 break;
2317 case NS_ooxml::LN_EG_RPrBase_bdr:
2319 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2320 if( pProperties )
2322 auto pBorderHandler = std::make_shared<BorderHandler>( true );
2323 pProperties->resolve(*pBorderHandler);
2325 rContext->Insert( PROP_CHAR_TOP_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2326 rContext->Insert( PROP_CHAR_BOTTOM_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2327 rContext->Insert( PROP_CHAR_LEFT_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2328 rContext->Insert( PROP_CHAR_RIGHT_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2330 rContext->Insert( PROP_CHAR_TOP_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2331 rContext->Insert( PROP_CHAR_BOTTOM_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2332 rContext->Insert( PROP_CHAR_LEFT_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2333 rContext->Insert( PROP_CHAR_RIGHT_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2335 auto xComplexColor = model::color::createXComplexColor(pBorderHandler->getComplexColor());
2337 rContext->Insert( PROP_CHAR_BORDER_TOP_COMPLEX_COLOR, uno::Any(xComplexColor));
2338 rContext->Insert( PROP_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, uno::Any(xComplexColor));
2339 rContext->Insert( PROP_CHAR_BORDER_LEFT_COMPLEX_COLOR, uno::Any(xComplexColor));
2340 rContext->Insert( PROP_CHAR_BORDER_RIGHT_COMPLEX_COLOR, uno::Any(xComplexColor));
2342 table::ShadowFormat aFormat;
2343 // Word only allows shadows on visible borders
2344 if ( pBorderHandler->getShadow() && pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE )
2345 aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
2346 rContext->Insert(PROP_CHAR_SHADOW_FORMAT, uno::Any(aFormat));
2349 break;
2350 case NS_ooxml::LN_EG_RPrBase_color:
2352 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2353 if (pProperties)
2355 auto pThemeColorHandler = std::make_shared<ThemeColorHandler>();
2356 pProperties->resolve(*pThemeColorHandler);
2358 uno::Any aThemeColorName(TDefTableHandler::getThemeColorTypeString(pThemeColorHandler->mnIndex));
2359 uno::Any aThemeColorTint(OUString::number(pThemeColorHandler->mnTint, 16));
2360 uno::Any aThemeColorShade(OUString::number(pThemeColorHandler->mnShade, 16));
2362 if (m_pImpl->GetTopContext())
2364 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR, uno::Any(pThemeColorHandler->mnColor));
2366 auto eType = TDefTableHandler::getThemeColorTypeIndex(pThemeColorHandler->mnIndex);
2367 if (eType != model::ThemeColorType::Unknown)
2370 model::ComplexColor aComplexColor;
2371 aComplexColor.setThemeColor(eType);
2373 auto eUsage = TDefTableHandler::getThemeColorUsage(pThemeColorHandler->mnIndex);
2374 aComplexColor.setThemeColorUsage(eUsage);
2376 if (pThemeColorHandler->mnTint > 0 )
2378 sal_Int16 nTint = sal_Int16((255 - pThemeColorHandler->mnTint) * 10000 / 255);
2379 aComplexColor.addTransformation({model::TransformationType::Tint, nTint});
2381 if (pThemeColorHandler->mnShade > 0)
2383 sal_Int16 nShade = sal_Int16((255 - pThemeColorHandler->mnShade) * 10000 / 255);
2384 aComplexColor.addTransformation({model::TransformationType::Shade, nShade});
2387 auto xComplexColor = model::color::createXComplexColor(aComplexColor);
2388 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMPLEX_COLOR, uno::Any(xComplexColor));
2391 uno::Any aColorAny(msfilter::util::ConvertColorOU(Color(ColorTransparency, pThemeColorHandler->mnColor)));
2392 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_ORIGINAL_COLOR, aColorAny, true, CHAR_GRAB_BAG);
2394 if (pThemeColorHandler->mnIndex >= 0)
2395 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR, aThemeColorName, true, CHAR_GRAB_BAG);
2397 if (pThemeColorHandler->mnTint > 0)
2398 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_TINT, aThemeColorTint, true, CHAR_GRAB_BAG);
2400 if (pThemeColorHandler->mnShade > 0)
2401 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_SHADE, aThemeColorShade, true, CHAR_GRAB_BAG);
2404 if (pThemeColorHandler->mnIndex >= 0)
2406 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeColor", aThemeColorName.get<OUString>());
2407 if (pThemeColorHandler->mnTint > 0)
2408 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeTint", aThemeColorTint.get<OUString>());
2409 if (pThemeColorHandler->mnShade > 0)
2410 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeShade", aThemeColorShade.get<OUString>());
2412 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "color", m_pImpl->m_aSubInteropGrabBag);
2416 break;
2417 case NS_ooxml::LN_CT_PPr_sectPr:
2418 case NS_ooxml::LN_EG_RPrBase_rFonts:
2419 case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
2420 case NS_ooxml::LN_EG_RPrBase_u:
2421 case NS_ooxml::LN_EG_RPrBase_lang:
2422 case NS_ooxml::LN_CT_PPrBase_spacing:
2423 case NS_ooxml::LN_CT_PPrBase_ind:
2424 case NS_ooxml::LN_CT_RPrDefault_rPr:
2425 case NS_ooxml::LN_CT_PPrDefault_pPr:
2426 case NS_ooxml::LN_CT_Style_pPr:
2427 case NS_ooxml::LN_CT_Style_rPr:
2428 case NS_ooxml::LN_CT_PPr_rPr:
2429 case NS_ooxml::LN_CT_PPrBase_numPr:
2431 if (nSprmId == NS_ooxml::LN_CT_PPr_sectPr)
2432 m_pImpl->SetParaSectpr(true);
2433 resolveSprmProps(*this, rSprm);
2434 if (nSprmId == NS_ooxml::LN_CT_PPrBase_spacing)
2435 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", m_pImpl->m_aSubInteropGrabBag);
2436 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_rFonts)
2437 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "rFonts", m_pImpl->m_aSubInteropGrabBag);
2438 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_lang)
2439 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lang", m_pImpl->m_aSubInteropGrabBag);
2440 else if (nSprmId == NS_ooxml::LN_CT_PPrBase_ind)
2441 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ind", m_pImpl->m_aSubInteropGrabBag);
2443 break;
2444 case NS_ooxml::LN_CT_PPrBase_wordWrap:
2445 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "wordWrap", "");
2446 break;
2447 case NS_ooxml::LN_EG_SectPrContents_footnotePr:
2448 case NS_ooxml::LN_EG_SectPrContents_endnotePr:
2449 m_pImpl->SetInFootnoteProperties( NS_ooxml::LN_EG_SectPrContents_footnotePr == nSprmId );
2450 resolveSprmProps(*this, rSprm);
2451 break;
2452 case NS_ooxml::LN_EG_SectPrContents_lnNumType:
2454 resolveSprmProps(*this, rSprm);
2455 LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
2456 m_pImpl->SetLineNumberSettings( aSettings );
2457 //apply settings at XLineNumberingProperties
2460 uno::Reference< text::XLineNumberingProperties > xLineNumberingProperties( m_pImpl->GetTextDocument(), uno::UNO_QUERY_THROW );
2461 uno::Reference< beans::XPropertySet > xLineNumberingPropSet = xLineNumberingProperties->getLineNumberingProperties();
2462 if( aSettings.nInterval == 0 )
2463 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::Any(false) );
2464 else
2466 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::Any(true) );
2467 if( aSettings.nInterval )
2468 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_INTERVAL ), uno::Any(static_cast<sal_Int16>(aSettings.nInterval)) );
2469 if( aSettings.nDistance != -1 )
2470 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::Any(aSettings.nDistance) );
2471 else
2473 // set Auto value (0.5 cm)
2474 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::Any(static_cast<sal_Int32>(500)) );
2475 if( pSectionContext )
2476 pSectionContext->SetdxaLnn( static_cast<sal_Int32>(283) );
2478 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_RESTART_AT_EACH_PAGE ), uno::Any(aSettings.bRestartAtEachPage) );
2481 catch( const uno::Exception& )
2486 break;
2487 case NS_ooxml::LN_CT_PPrBase_framePr:
2489 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
2490 if( pContext )
2492 // If there is a deferred page break applied to this framed paragraph,
2493 // create a dummy paragraph without extra properties,
2494 // so that the anchored frame will be on the correct page (similar to shapes).
2495 if (pContext->isSet(PROP_BREAK_TYPE))
2497 pContext->Erase(PROP_BREAK_TYPE);
2499 lcl_startParagraphGroup();
2500 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
2501 lcl_startCharacterGroup();
2502 sal_Unicode const sBreak[] = { 0x0d };
2503 lcl_utext(sBreak, 1);
2504 lcl_endCharacterGroup();
2505 lcl_endParagraphGroup();
2508 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
2509 if (pParaContext)
2510 pParaContext->props().SetFrameMode();
2512 if (!IsInHeaderFooter())
2513 m_pImpl->m_bIsActualParagraphFramed = true;
2515 else
2517 //TODO: What about style sheet import of frame properties
2519 m_pImpl->NewFrameDirection();
2520 resolveSprmProps(*this, rSprm);
2522 break;
2523 case NS_ooxml::LN_EG_SectPrContents_pgSz:
2525 PaperInfo aLetter(PAPER_LETTER);
2526 CT_PageSz.w = aLetter.getWidth();
2527 CT_PageSz.h = aLetter.getHeight();
2529 CT_PageSz.orient = false;
2530 resolveSprmProps(*this, rSprm);
2531 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2532 if(pSectionContext)
2534 if (!m_pImpl->IsAltChunk())
2536 pSectionContext->Insert(PROP_HEIGHT, uno::Any(CT_PageSz.h));
2538 pSectionContext->Insert( PROP_IS_LANDSCAPE, uno::Any( CT_PageSz.orient ));
2539 if (!m_pImpl->IsAltChunk())
2541 pSectionContext->Insert(PROP_WIDTH, uno::Any(CT_PageSz.w));
2544 break;
2546 case NS_ooxml::LN_EG_SectPrContents_pgMar:
2547 m_pImpl->InitPageMargins();
2548 resolveSprmProps(*this, rSprm);
2549 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2550 if(pSectionContext)
2552 const PageMar& rPageMar = m_pImpl->GetPageMargins();
2553 pSectionContext->SetTopMargin( rPageMar.top );
2554 pSectionContext->SetRightMargin( rPageMar.right );
2555 pSectionContext->SetBottomMargin( rPageMar.bottom );
2556 pSectionContext->SetLeftMargin( rPageMar.left );
2557 pSectionContext->SetHeaderTop( rPageMar.header );
2558 pSectionContext->SetHeaderBottom( rPageMar.footer );
2559 pSectionContext->SetGutterMargin(rPageMar.gutter);
2561 break;
2562 case NS_ooxml::LN_EG_SectPrContents_paperSrc:
2563 m_pImpl->InitPaperSource();
2564 resolveSprmProps(*this, rSprm);
2565 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2566 if(pSectionContext)
2568 const PaperSource& rPaperSource = m_pImpl->GetPaperSource();
2569 pSectionContext->SetPaperSource( rPaperSource.first, rPaperSource.other );
2571 break;
2572 case NS_ooxml::LN_EG_SectPrContents_cols:
2574 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2575 if( pProperties )
2578 tools::SvRef< SectionColumnHandler > pSectHdl( new SectionColumnHandler );
2579 pProperties->resolve(*pSectHdl);
2580 if(pSectionContext && !m_pImpl->isInIndexContext())
2582 sal_Int16 nColumnCount = pSectHdl->GetNum() == 1 ? 0 : pSectHdl->GetNum();
2583 if( pSectHdl->IsEqualWidth() )
2585 pSectionContext->SetEvenlySpaced( true );
2586 pSectionContext->SetColumnCount( nColumnCount );
2587 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2588 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2590 else if( !pSectHdl->GetColumns().empty() )
2592 pSectionContext->SetEvenlySpaced( false );
2593 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2594 nColumnCount = pSectHdl->GetColumns().size();
2595 pSectionContext->SetColumnCount( nColumnCount == 1 ? 0 : nColumnCount );
2596 std::vector<Column_>::const_iterator tmpIter = pSectHdl->GetColumns().begin();
2597 for (; tmpIter != pSectHdl->GetColumns().end(); ++tmpIter)
2599 pSectionContext->AppendColumnWidth( tmpIter->nWidth );
2600 if ((tmpIter != pSectHdl->GetColumns().end() - 1) || (tmpIter->nSpace > 0))
2601 pSectionContext->AppendColumnSpacing( tmpIter->nSpace );
2603 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2605 else if( nColumnCount )
2607 pSectionContext->SetColumnCount( nColumnCount );
2608 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2609 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2613 else if ( pSectionContext )
2615 FieldContextPtr pContext = m_pImpl->GetTopFieldContext();
2616 uno::Reference< beans::XPropertySet > xTOC = pContext->GetTOC();
2617 if( xTOC.is() )
2619 uno::Reference<text::XTextColumns> xTextColumns;
2620 xTOC->getPropertyValue(getPropertyName( PROP_TEXT_COLUMNS )) >>= xTextColumns;
2621 if (xTextColumns.is())
2623 uno::Reference< beans::XPropertySet > xColumnPropSet( xTextColumns, uno::UNO_QUERY_THROW );
2624 xColumnPropSet->setPropertyValue( getPropertyName( PROP_AUTOMATIC_DISTANCE ), uno::Any( pSectHdl->GetSpace() ));
2625 xTOC->setPropertyValue( getPropertyName( PROP_TEXT_COLUMNS ), uno::Any( xTextColumns ) );
2631 break;
2632 case NS_ooxml::LN_EG_SectPrContents_docGrid:
2633 resolveSprmProps(*this, rSprm);
2634 break;
2635 case NS_ooxml::LN_EG_SectPrContents_pgBorders:
2637 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2638 if( pProperties && pSectionContext )
2640 tools::SvRef< PageBordersHandler > pHandler( new PageBordersHandler );
2641 pProperties->resolve( *pHandler );
2643 // Set the borders to the context and apply them to the styles
2644 pHandler->SetBorders( pSectionContext );
2647 break;
2649 case NS_ooxml::LN_CT_PPrBase_snapToGrid:
2650 if (!IsStyleSheetImport()||!m_pImpl->isInteropGrabBagEnabled())
2652 rContext->Insert( PROP_SNAP_TO_GRID, uno::Any(bool(nIntValue)));
2654 else
2656 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "snapToGrid", OUString::number(nIntValue));
2658 break;
2659 case NS_ooxml::LN_CT_PPrBase_pStyle:
2661 StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable();
2662 const OUString sConvertedStyleName = pStyleTable->ConvertStyleNameExt(sStringValue);
2663 m_pImpl->SetCurrentParaStyleName( sConvertedStyleName );
2664 if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION)
2665 m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::Any( sConvertedStyleName ));
2667 break;
2668 case NS_ooxml::LN_EG_RPrBase_rStyle:
2670 OUString const sConvertedName(m_pImpl->GetStyleSheetTable()->ConvertStyleNameExt(sStringValue));
2671 if (m_pImpl->CheckFootnoteStyle() && m_pImpl->GetFootnoteContext())
2672 m_pImpl->SetHasFootnoteStyle(m_pImpl->GetFootnoteContext()->GetFootnoteStyle() == sConvertedName);
2674 // First check if the style exists in the document.
2675 StyleSheetEntryPtr pEntry = m_pImpl->GetStyleSheetTable( )->FindStyleSheetByConvertedStyleName( sConvertedName );
2676 bool bExists = pEntry && ( pEntry->m_nStyleTypeCode == STYLE_TYPE_CHAR );
2677 // Add the property if the style exists, but do not add it elements in TOC:
2678 // they will receive later another style references from TOC
2679 if ( bExists && m_pImpl->GetTopContext() && !m_pImpl->IsInTOC())
2680 m_pImpl->GetTopContext()->Insert( PROP_CHAR_STYLE_NAME, uno::Any( sConvertedName ) );
2682 break;
2683 case NS_ooxml::LN_CT_TblPrBase_tblCellMar: //cell margins
2685 resolveSprmProps(*this, rSprm);//contains LN_CT_TblCellMar_top, LN_CT_TblCellMar_left, LN_CT_TblCellMar_bottom, LN_CT_TblCellMar_right
2687 break;
2688 case NS_ooxml::LN_CT_TblCellMar_top:
2689 case NS_ooxml::LN_CT_TblCellMar_start:
2690 case NS_ooxml::LN_CT_TblCellMar_left:
2691 case NS_ooxml::LN_CT_TblCellMar_bottom:
2692 case NS_ooxml::LN_CT_TblCellMar_end:
2693 case NS_ooxml::LN_CT_TblCellMar_right:
2695 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2696 if( pProperties )
2698 MeasureHandlerPtr pMeasureHandler( new MeasureHandler );
2699 pProperties->resolve(*pMeasureHandler);
2700 sal_Int32 nMeasureValue = pMeasureHandler->getMeasureValue();
2701 PropertyIds eId = META_PROP_CELL_MAR_TOP;
2702 bool rtl = false; // TODO
2703 switch(nSprmId)
2705 case NS_ooxml::LN_CT_TblCellMar_top:
2706 break;
2707 case NS_ooxml::LN_CT_TblCellMar_start:
2708 eId = rtl ? META_PROP_CELL_MAR_RIGHT : META_PROP_CELL_MAR_LEFT;
2709 break;
2710 case NS_ooxml::LN_CT_TblCellMar_left:
2711 eId = META_PROP_CELL_MAR_LEFT;
2712 break;
2713 case NS_ooxml::LN_CT_TblCellMar_bottom:
2714 eId = META_PROP_CELL_MAR_BOTTOM;
2715 break;
2716 case NS_ooxml::LN_CT_TblCellMar_end:
2717 eId = rtl ? META_PROP_CELL_MAR_LEFT : META_PROP_CELL_MAR_RIGHT;
2718 break;
2719 case NS_ooxml::LN_CT_TblCellMar_right:
2720 eId = META_PROP_CELL_MAR_RIGHT;
2721 break;
2722 default:;
2724 rContext->Insert( eId, uno::Any(nMeasureValue), false);
2727 break;
2728 case NS_ooxml::LN_EG_RPrBase_noProof: // no grammar and spell checking, unsupported
2729 break;
2730 case NS_ooxml::LN_anchor_anchor: // at_character drawing
2731 case NS_ooxml::LN_inline_inline: // as_character drawing
2733 if ( m_pImpl->IsDiscardHeaderFooter() )
2734 break;
2735 //tdf112342: Break before images as well, if there are page break
2736 if (m_pImpl->isBreakDeferred(BreakType::PAGE_BREAK)
2737 && nSprmId == NS_ooxml::LN_inline_inline && !m_pImpl->IsInShape())
2739 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
2741 m_pImpl->m_bIsSplitPara = true;
2742 finishParagraph();
2743 lcl_startParagraphGroup();
2745 else
2747 m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)
2748 ->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
2749 m_pImpl->clearDeferredBreak(PAGE_BREAK);
2753 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2754 if( pProperties )
2756 m_pImpl->m_eGraphicImportType =
2757 (NS_ooxml::LN_anchor_anchor ==
2758 sal::static_int_cast<Id>(nSprmId)) ?
2759 IMPORT_AS_DETECTED_ANCHOR :
2760 IMPORT_AS_DETECTED_INLINE;
2761 GraphicImportPtr pGraphicImport = m_pImpl->GetGraphicImport();
2762 pProperties->resolve(*pGraphicImport);
2763 m_pImpl->ImportGraphic(pProperties);
2764 if( !pGraphicImport->IsGraphic() )
2766 m_pImpl->ResetGraphicImport();
2767 // todo: It's a shape, now start shape import
2771 break;
2772 case NS_ooxml::LN_EG_RPrBase_vertAlign:
2774 sal_Int16 nEscapement = 0;
2775 sal_Int8 nProp = DFLT_ESC_PROP;
2776 if ( sStringValue == "superscript" )
2777 nEscapement = DFLT_ESC_AUTO_SUPER;
2778 else if ( sStringValue == "subscript" )
2779 nEscapement = DFLT_ESC_AUTO_SUB;
2780 else
2781 nProp = 100;
2783 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( nEscapement ) );
2784 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
2786 break;
2787 case NS_ooxml::LN_CT_FtnProps_pos:
2788 //footnotes in word can be at page end or beneath text - writer supports only the first
2789 //endnotes in word can be at section end or document end - writer supports only the latter
2790 // -> so this property can be ignored
2791 break;
2792 case NS_ooxml::LN_CT_FtnProps_numFmt:
2793 case NS_ooxml::LN_CT_EdnProps_numFmt:
2795 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2796 if (pProperties)
2798 pProperties->resolve(*this);
2801 break;
2802 case NS_ooxml::LN_EG_FtnEdnNumProps_numStart:
2803 case NS_ooxml::LN_EG_FtnEdnNumProps_numRestart:
2807 uno::Reference< beans::XPropertySet > xFtnEdnSettings;
2808 if( m_pImpl->IsInFootnoteProperties() )
2810 uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2811 if (xFootnotesSupplier.is())
2812 xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings();
2814 else
2816 uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2817 if (xEndnotesSupplier.is())
2818 xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings();
2820 if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId && xFtnEdnSettings.is())
2822 xFtnEdnSettings->setPropertyValue(
2823 getPropertyName( PROP_START_AT),
2824 uno::Any( sal_Int16( nIntValue - 1 )));
2826 else if( NS_ooxml::LN_EG_FtnEdnNumProps_numRestart == nSprmId && xFtnEdnSettings.is())
2828 sal_Int16 nFootnoteCounting = 0;
2829 switch (nIntValue)
2831 case NS_ooxml::LN_Value_ST_RestartNumber_continuous: nFootnoteCounting = text::FootnoteNumbering::PER_DOCUMENT; break;
2832 case NS_ooxml::LN_Value_ST_RestartNumber_eachPage: nFootnoteCounting = text::FootnoteNumbering::PER_PAGE; break;
2833 case NS_ooxml::LN_Value_ST_RestartNumber_eachSect: nFootnoteCounting = text::FootnoteNumbering::PER_CHAPTER; break;
2834 default: break;
2836 xFtnEdnSettings->setPropertyValue(
2837 getPropertyName( PROP_FOOTNOTE_COUNTING ),
2838 uno::Any( nFootnoteCounting ));
2840 else if (xFtnEdnSettings.is())
2842 sal_Int16 nNumType = ConversionHelper::ConvertNumberingType( nIntValue );
2843 xFtnEdnSettings->setPropertyValue(
2844 getPropertyName( PROP_NUMBERING_TYPE),
2845 uno::Any( nNumType ));
2848 catch( const uno::Exception& )
2852 break;
2853 case NS_ooxml::LN_EG_RangeMarkupElements_moveFromRangeStart:
2854 m_pImpl->SetMoveBookmark(/*bIsFrom=*/true);
2855 if (m_pImpl->hasTableManager())
2856 m_pImpl->getTableManager().setMoved( getPropertyName(PROP_TABLE_ROW_DELETE) );
2857 break;
2858 case NS_ooxml::LN_EG_RangeMarkupElements_moveToRangeStart:
2859 m_pImpl->SetMoveBookmark(/*bIsFrom=*/false);
2860 if (m_pImpl->hasTableManager())
2861 m_pImpl->getTableManager().setMoved( getPropertyName(PROP_TABLE_ROW_INSERT) );
2862 break;
2863 case NS_ooxml::LN_EG_RangeMarkupElements_moveFromRangeEnd:
2864 case NS_ooxml::LN_EG_RangeMarkupElements_moveToRangeEnd:
2865 if (m_pImpl->hasTableManager())
2866 m_pImpl->getTableManager().setMoved( OUString() );
2867 break;
2868 case NS_ooxml::LN_CT_ParaRPr_moveFrom:
2869 case NS_ooxml::LN_CT_ParaRPr_moveTo:
2870 m_pImpl->StartParaMarkerMove( );
2871 break;
2872 case NS_ooxml::LN_paratrackchange:
2873 m_pImpl->StartParaMarkerChange( );
2874 [[fallthrough]];
2875 case NS_ooxml::LN_CT_PPr_pPrChange:
2876 case NS_ooxml::LN_CT_ParaRPr_rPrChange:
2877 case NS_ooxml::LN_trackchange:
2878 case NS_ooxml::LN_EG_RPrContent_rPrChange:
2879 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeStart:
2880 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeEnd:
2881 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeStart:
2882 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeEnd:
2883 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeStart:
2884 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeEnd:
2886 HandleRedline( rSprm );
2888 break;
2889 case NS_ooxml::LN_endtrackchange:
2890 m_pImpl->RemoveTopRedline();
2891 break;
2892 case NS_ooxml::LN_CT_RPrChange_rPr:
2894 // Push all the current 'Character' properties to the stack, so that we don't store them
2895 // as 'tracked changes' by mistake
2896 m_pImpl->PushProperties(CONTEXT_CHARACTER);
2898 // Resolve all the properties that are under the 'rPrChange'->'rPr' XML node
2899 resolveSprmProps(*this, rSprm );
2901 // Get all the properties that were processed in the 'rPrChange'->'rPr' XML node
2902 uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2904 // Pop back out the character properties that were on the run
2905 m_pImpl->PopProperties(CONTEXT_CHARACTER);
2907 // Store these properties in the current redline object (do it after the PopProperties() above, since
2908 // otherwise it'd be stored in the content dropped there).
2909 m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2911 break;
2912 case NS_ooxml::LN_CT_PPrChange_pPr:
2914 // Push all the current 'Paragraph' properties to the stack, so that we don't store them
2915 // as 'tracked changes' by mistake
2916 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2918 // Resolve all the properties that are under the 'pPrChange'->'pPr' XML node
2919 resolveSprmProps(*this, rSprm );
2921 // Get all the properties that were processed in the 'pPrChange'->'pPr' XML node
2922 uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2924 // Pop back out the character properties that were on the run
2925 m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
2927 // Store these properties in the current redline object (do it after the PopProperties() above, since
2928 // otherwise it'd be stored in the content dropped there).
2929 m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2931 break;
2932 case NS_ooxml::LN_object:
2934 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2935 if( pProperties )
2937 auto pOLEHandler = std::make_shared<OLEHandler>(*this);
2938 pProperties->resolve(*pOLEHandler);
2939 if ( pOLEHandler->isOLEObject( ) )
2941 OUString sStreamName = pOLEHandler->copyOLEOStream( m_pImpl->GetTextDocument() );
2942 if( !sStreamName.isEmpty() )
2944 m_pImpl->appendOLE( sStreamName, pOLEHandler );
2949 break;
2950 case NS_ooxml::LN_EG_HdrFtrReferences_headerReference: // header reference - not needed
2951 case NS_ooxml::LN_EG_HdrFtrReferences_footerReference: // footer reference - not needed
2952 break;
2953 case NS_ooxml::LN_EG_RPrBase_snapToGrid: // "Use document grid settings for inter-paragraph spacing"
2954 break;
2955 case NS_ooxml::LN_CT_PPrBase_contextualSpacing:
2956 rContext->Insert(PROP_PARA_CONTEXT_MARGIN, uno::Any( nIntValue != 0 ));
2957 break;
2958 case NS_ooxml::LN_CT_PPrBase_mirrorIndents: // mirrorIndents
2959 rContext->Insert(PROP_MIRROR_INDENTS, uno::Any( nIntValue != 0 ), true, PARA_GRAB_BAG);
2960 break;
2961 case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection
2963 if( pSectionContext )
2964 pSectionContext->Insert( PROP_IS_PROTECTED, uno::Any( bool(nIntValue) ) );
2966 break;
2967 case NS_ooxml::LN_EG_SectPrContents_vAlign:
2969 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2970 if( pSectionContext )
2972 drawing::TextVerticalAdjust nVA = drawing::TextVerticalAdjust_TOP;
2973 switch( nIntValue )
2975 case NS_ooxml::LN_Value_ST_VerticalJc_center: //92367
2976 nVA = drawing::TextVerticalAdjust_CENTER;
2977 break;
2978 case NS_ooxml::LN_Value_ST_VerticalJc_both: //92368 - justify
2979 nVA = drawing::TextVerticalAdjust_BLOCK;
2980 break;
2981 case NS_ooxml::LN_Value_ST_VerticalJc_bottom: //92369
2982 nVA = drawing::TextVerticalAdjust_BOTTOM;
2983 break;
2984 default:
2985 break;
2987 pSectionContext->Insert( PROP_TEXT_VERTICAL_ADJUST, uno::Any( nVA ), true, PARA_GRAB_BAG );
2990 break;
2991 case NS_ooxml::LN_EG_RPrBase_fitText:
2992 break;
2993 case NS_ooxml::LN_ffdata:
2995 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2996 if (pProperties)
2998 FFDataHandler::Pointer_t pFFDataHandler(new FFDataHandler());
3000 pProperties->resolve(*pFFDataHandler);
3001 m_pImpl->SetFieldFFData(pFFDataHandler);
3004 break;
3005 case NS_ooxml::LN_CT_SdtPr_comboBox:
3007 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::comboBox);
3008 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3009 if (pProperties)
3010 pProperties->resolve(*this);
3012 break;
3013 case NS_ooxml::LN_CT_SdtPr_dropDownList:
3015 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::dropDown);
3016 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3017 if (pProperties)
3018 pProperties->resolve(*this);
3020 break;
3021 case NS_ooxml::LN_CT_SdtDropDownList_listItem:
3023 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3025 size_t nDropDownDisplayTexts = m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().size();
3026 size_t nDropDownItems = m_pImpl->m_pSdtHelper->getDropDownItems().size();
3028 if (pProperties)
3029 pProperties->resolve(*this);
3031 if (m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().size() != nDropDownDisplayTexts + 1)
3033 // w:displayText="..." is optional, add empty value if it was not provided.
3034 m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().push_back(OUString());
3036 if (m_pImpl->m_pSdtHelper->getDropDownItems().size() != nDropDownItems + 1)
3038 // w:value="..." is optional, add empty value if it was not provided.
3039 m_pImpl->m_pSdtHelper->getDropDownItems().push_back(OUString());
3042 break;
3043 case NS_ooxml::LN_CT_SdtPr_placeholder:
3045 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3046 if (pProperties)
3047 pProperties->resolve(*this);
3049 break;
3050 break;
3051 case NS_ooxml::LN_CT_SdtPr_date:
3053 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::datePicker);
3054 resolveSprmProps(*this, rSprm);
3055 m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
3057 break;
3058 case NS_ooxml::LN_CT_SdtDate_dateFormat:
3060 m_pImpl->m_pSdtHelper->getDateFormat().append(sStringValue);
3062 break;
3063 case NS_ooxml::LN_CT_SdtDate_storeMappedDataAs:
3066 break;
3067 case NS_ooxml::LN_CT_SdtDate_calendar:
3070 break;
3071 case NS_ooxml::LN_CT_SdtDate_lid:
3073 m_pImpl->m_pSdtHelper->getLocale().append(sStringValue);
3075 break;
3076 case NS_ooxml::LN_CT_SdtPr_text:
3078 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::plainText);
3079 if (m_pImpl->m_pSdtHelper->GetSdtType() == NS_ooxml::LN_CT_SdtRun_sdtContent)
3081 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3082 break;
3084 enableInteropGrabBag("ooxml:CT_SdtPr_text");
3085 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3086 if (pProperties)
3087 pProperties->resolve(*this);
3088 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
3089 m_pImpl->disableInteropGrabBag();
3091 break;
3092 case NS_ooxml::LN_CT_SdtPr_dataBinding:
3093 case NS_ooxml::LN_CT_SdtPr_equation:
3094 case NS_ooxml::LN_CT_SdtPr_checkbox:
3095 case NS_ooxml::LN_CT_SdtPr_docPartObj:
3096 case NS_ooxml::LN_CT_SdtPr_docPartList:
3097 case NS_ooxml::LN_CT_SdtPr_picture:
3098 case NS_ooxml::LN_CT_SdtPr_citation:
3099 case NS_ooxml::LN_CT_SdtPr_group:
3100 case NS_ooxml::LN_CT_SdtPr_id:
3101 case NS_ooxml::LN_CT_SdtPr_alias:
3102 case NS_ooxml::LN_CT_SdtPlaceholder_docPart:
3103 case NS_ooxml::LN_CT_SdtPr_showingPlcHdr:
3104 case NS_ooxml::LN_CT_SdtPr_color:
3105 case NS_ooxml::LN_CT_SdtPr_appearance:
3106 case NS_ooxml::LN_CT_SdtPr_tag:
3107 case NS_ooxml::LN_CT_SdtPr_tabIndex:
3108 case NS_ooxml::LN_CT_SdtPr_lock:
3110 if (!m_pImpl->GetSdtStarts().empty())
3112 if (nSprmId == NS_ooxml::LN_CT_SdtPr_showingPlcHdr)
3114 if (nIntValue)
3115 m_pImpl->m_pSdtHelper->SetShowingPlcHdr();
3118 if (nSprmId == NS_ooxml::LN_CT_SdtPr_color)
3120 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3121 if (pProperties)
3123 pProperties->resolve(*this);
3125 break;
3128 if (nSprmId == NS_ooxml::LN_CT_SdtPr_appearance)
3130 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3131 if (pProperties)
3133 pProperties->resolve(*this);
3135 break;
3138 if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias)
3140 m_pImpl->m_pSdtHelper->SetAlias(sStringValue);
3141 break;
3144 if (nSprmId == NS_ooxml::LN_CT_SdtPr_tag)
3146 m_pImpl->m_pSdtHelper->SetTag(sStringValue);
3147 break;
3150 if (nSprmId == NS_ooxml::LN_CT_SdtPr_id)
3152 m_pImpl->m_pSdtHelper->SetId(nIntValue);
3153 break;
3156 if (nSprmId == NS_ooxml::LN_CT_SdtPr_tabIndex)
3158 m_pImpl->m_pSdtHelper->SetTabIndex(nIntValue);
3159 break;
3162 if (nSprmId == NS_ooxml::LN_CT_SdtPr_lock)
3164 m_pImpl->m_pSdtHelper->SetLock(sStringValue);
3165 break;
3168 if (nSprmId == NS_ooxml::LN_CT_SdtPr_checkbox)
3170 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::checkBox);
3171 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3172 if (pProperties)
3174 pProperties->resolve(*this);
3176 break;
3178 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_picture)
3180 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::picture);
3181 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3182 if (pProperties)
3184 pProperties->resolve(*this);
3186 break;
3188 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_date)
3190 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::datePicker);
3191 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3192 if (pProperties)
3194 pProperties->resolve(*this);
3196 break;
3200 // this is an unsupported SDT property, create a grab bag for it
3201 OUString sName;
3202 switch (nSprmId)
3204 case NS_ooxml::LN_CT_SdtPr_dataBinding: sName = "ooxml:CT_SdtPr_dataBinding"; break;
3205 case NS_ooxml::LN_CT_SdtPr_equation: sName = "ooxml:CT_SdtPr_equation"; break;
3206 case NS_ooxml::LN_CT_SdtPr_checkbox: sName = "ooxml:CT_SdtPr_checkbox"; break;
3207 case NS_ooxml::LN_CT_SdtPr_docPartObj: sName = "ooxml:CT_SdtPr_docPartObj"; break;
3208 case NS_ooxml::LN_CT_SdtPr_docPartList: sName = "ooxml:CT_SdtPr_docPartList"; break;
3209 case NS_ooxml::LN_CT_SdtPr_picture: sName = "ooxml:CT_SdtPr_picture"; break;
3210 case NS_ooxml::LN_CT_SdtPr_citation: sName = "ooxml:CT_SdtPr_citation"; break;
3211 case NS_ooxml::LN_CT_SdtPr_group: sName = "ooxml:CT_SdtPr_group"; break;
3212 case NS_ooxml::LN_CT_SdtPr_id: sName = "ooxml:CT_SdtPr_id"; break;
3213 case NS_ooxml::LN_CT_SdtPr_alias: sName = "ooxml:CT_SdtPr_alias"; break;
3214 case NS_ooxml::LN_CT_SdtPr_tag: sName = "ooxml:CT_SdtPr_tag"; break;
3215 case NS_ooxml::LN_CT_SdtPr_tabIndex: sName = "ooxml:CT_SdtPr_tabIndex"; break;
3216 case NS_ooxml::LN_CT_SdtPr_lock: sName = "ooxml:CT_SdtPr_lock"; break;
3217 case NS_ooxml::LN_CT_SdtPlaceholder_docPart: sName = "ooxml:CT_SdtPlaceholder_docPart"; break;
3218 case NS_ooxml::LN_CT_SdtPr_showingPlcHdr: sName = "ooxml:CT_SdtPr_showingPlcHdr"; break;
3219 case NS_ooxml::LN_CT_SdtPr_color: sName = "ooxml:CT_SdtPr_color"; break;
3220 case NS_ooxml::LN_CT_SdtPr_appearance: sName = "ooxml:CT_SdtPr_appearance"; break;
3221 default: assert(false);
3223 if (
3224 nSprmId == NS_ooxml::LN_CT_SdtPr_checkbox ||
3225 nSprmId == NS_ooxml::LN_CT_SdtPr_docPartObj ||
3226 nSprmId == NS_ooxml::LN_CT_SdtPr_docPartList ||
3227 nSprmId == NS_ooxml::LN_CT_SdtPr_picture ||
3228 nSprmId == NS_ooxml::LN_CT_SdtPr_citation)
3230 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::unsupported);
3232 enableInteropGrabBag(sName);
3234 // process subitems
3235 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3236 if (pProperties)
3237 pProperties->resolve(*this);
3239 if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias || nSprmId == NS_ooxml::LN_CT_SdtPr_tag
3240 || nSprmId == NS_ooxml::LN_CT_SdtPr_lock)
3242 // Grabbag string values
3243 beans::PropertyValue aValue;
3244 aValue.Name = sName;
3245 aValue.Value <<= sStringValue;
3246 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3248 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_showingPlcHdr)
3250 // Grabbag boolean values
3251 beans::PropertyValue aValue;
3252 aValue.Name = sName;
3253 aValue.Value <<= bool(nIntValue);
3254 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3256 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_id || nSprmId == NS_ooxml::LN_CT_SdtPr_tabIndex)
3258 // Grabbag integer values
3259 beans::PropertyValue aValue;
3260 aValue.Name = sName;
3261 aValue.Value <<= nIntValue;
3262 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3264 else
3265 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
3266 m_pImpl->m_pSdtHelper->setOutsideAParagraph(m_pImpl->IsOutsideAParagraph());
3267 m_pImpl->disableInteropGrabBag();
3269 break;
3270 case NS_ooxml::LN_CT_SdtCheckbox_checked:
3271 if (!m_pImpl->GetSdtStarts().empty())
3273 // nIntValue is not just 0 or 1, because we're in the w14 namespace's ST_OnOff.
3274 if (nIntValue == NS_ooxml::LN_ST_OnOff_true || nIntValue == NS_ooxml::LN_ST_OnOff_1)
3276 m_pImpl->m_pSdtHelper->SetChecked();
3279 else
3281 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checked",
3282 TextEffectsHandler::getOnOffString(nIntValue));
3284 break;
3285 case NS_ooxml::LN_CT_SdtCheckbox_checkedState:
3286 if (!m_pImpl->GetSdtStarts().empty())
3288 m_pImpl->m_pSdtHelper->SetCheckedState(OUString(sal_Unicode(sStringValue.toInt32(16))));
3290 else
3292 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checkedState",
3293 sStringValue);
3295 break;
3296 case NS_ooxml::LN_CT_SdtCheckbox_uncheckedState:
3297 if (!m_pImpl->GetSdtStarts().empty())
3299 m_pImpl->m_pSdtHelper->SetUncheckedState(
3300 OUString(sal_Unicode(sStringValue.toInt32(16))));
3302 else
3304 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag,
3305 "ooxml:CT_SdtCheckbox_uncheckedState", sStringValue);
3307 break;
3308 case NS_ooxml::LN_CT_SdtDocPart_docPartGallery:
3309 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartGallery", sStringValue);
3310 break;
3311 case NS_ooxml::LN_CT_SdtDocPart_docPartCategory:
3312 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartCategory", sStringValue);
3313 break;
3314 case NS_ooxml::LN_CT_SdtDocPart_docPartUnique:
3315 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartUnique", sStringValue);
3316 break;
3317 case NS_ooxml::LN_EG_SectPrContents_pgNumType:
3319 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3320 if( pProperties )
3322 pProperties->resolve(*this);
3325 break;
3326 case NS_ooxml::LN_tblStart:
3329 * Hack for Importing Section Properties
3330 * LO is not able to import section properties if first element in the
3331 * section is a table. So in case first element is a table add a dummy para
3332 * and remove it again when lcl_endSectionGroup is called
3334 if (m_pImpl->m_StreamStateStack.top().nTableDepth == 0
3335 && m_pImpl->GetIsFirstParagraphInSection()
3336 && !m_pImpl->GetIsDummyParaAddedForTableInSection() && !m_pImpl->GetIsTextFrameInserted()
3337 && !m_pImpl->GetIsPreviousParagraphFramed() && !IsInHeaderFooter())
3339 m_pImpl->AddDummyParaForTableInSection();
3342 // if first paragraph style in table has break-before-page, transfer that setting to the table itself.
3343 if (m_pImpl->m_StreamStateStack.top().nTableDepth == 0)
3345 const uno::Any aBreakType(style::BreakType_PAGE_BEFORE);
3346 const PropertyMapPtr pParagraphProps = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3347 if( pParagraphProps && pParagraphProps->isSet(PROP_PARA_STYLE_NAME) )
3349 StyleSheetEntryPtr pStyle;
3350 OUString sStyleName;
3351 pParagraphProps->getProperty(PROP_PARA_STYLE_NAME)->second >>= sStyleName;
3352 if( !sStyleName.isEmpty() && GetStyleSheetTable() )
3353 pStyle = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( sStyleName );
3355 if( pStyle && pStyle->m_pProperties
3356 && pStyle->m_pProperties->isSet(PROP_BREAK_TYPE)
3357 && pStyle->m_pProperties->getProperty(PROP_BREAK_TYPE)->second == aBreakType )
3359 pParagraphProps->Insert(PROP_BREAK_TYPE, aBreakType);
3364 m_pImpl->m_StreamStateStack.top().nTableDepth++;
3366 break;
3367 case NS_ooxml::LN_tblEnd:
3368 m_pImpl->m_StreamStateStack.top().nTableDepth--;
3369 break;
3370 case NS_ooxml::LN_tcStart:
3371 m_pImpl->m_nTableCellDepth++;
3372 break;
3373 case NS_ooxml::LN_tcEnd:
3374 m_pImpl->m_nTableCellDepth--;
3375 break;
3376 case NS_ooxml::LN_glow_glow:
3377 case NS_ooxml::LN_shadow_shadow:
3378 case NS_ooxml::LN_reflection_reflection:
3379 case NS_ooxml::LN_textOutline_textOutline:
3380 case NS_ooxml::LN_textFill_textFill:
3381 case NS_ooxml::LN_scene3d_scene3d:
3382 case NS_ooxml::LN_props3d_props3d:
3383 case NS_ooxml::LN_ligatures_ligatures:
3384 case NS_ooxml::LN_numForm_numForm:
3385 case NS_ooxml::LN_numSpacing_numSpacing:
3386 case NS_ooxml::LN_stylisticSets_stylisticSets:
3387 case NS_ooxml::LN_cntxtAlts_cntxtAlts:
3389 tools::SvRef<TextEffectsHandler> pTextEffectsHandlerPtr( new TextEffectsHandler(nSprmId) );
3390 std::optional<PropertyIds> aPropertyId = pTextEffectsHandlerPtr->getGrabBagPropertyId();
3391 if(aPropertyId)
3393 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3394 if( pProperties )
3396 pProperties->resolve(*pTextEffectsHandlerPtr);
3398 beans::PropertyValue aGrabBag = pTextEffectsHandlerPtr->getInteropGrabBag();
3399 rContext->Insert(*aPropertyId, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
3401 sal_Int16 nTransparency = TextEffectsHandler::GetTextFillSolidFillAlpha(aGrabBag);
3402 if (nTransparency != 0)
3404 rContext->Insert(PROP_CHAR_TRANSPARENCE, uno::Any(nTransparency));
3407 else if (nSprmId == NS_ooxml::LN_cntxtAlts_cntxtAlts)
3409 pTextEffectsHandlerPtr->lcl_sprm(rSprm);
3410 beans::PropertyValue aGrabBag = pTextEffectsHandlerPtr->getInteropGrabBag();
3411 rContext->Insert(*aPropertyId, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
3415 break;
3416 case NS_ooxml::LN_CT_SdtPr_rPr:
3418 // Make sure properties from a previous SDT are not merged with the current ones.
3419 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3421 break;
3422 case NS_ooxml::LN_CT_TblPrBase_tblLook:
3424 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3425 if (pProperties)
3427 pProperties->resolve(*this);
3428 m_pImpl->getTableManager().finishTableLook();
3431 break;
3432 case NS_ooxml::LN_CT_TrPrBase_cnfStyle:
3434 m_pImpl->enableInteropGrabBag("cnfStyle");
3435 resolveSprmProps(*this, rSprm);
3437 TablePropertyMapPtr pPropMap(new TablePropertyMap());
3438 pPropMap->Insert(PROP_ROW_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, ROW_GRAB_BAG);
3439 m_pImpl->getTableManager().insertRowProps(pPropMap);
3441 m_pImpl->disableInteropGrabBag();
3443 break;
3444 case NS_ooxml::LN_CT_TcPrBase_cnfStyle:
3446 m_pImpl->enableInteropGrabBag("cnfStyle");
3447 resolveSprmProps(*this, rSprm);
3449 TablePropertyMapPtr pPropMap(new TablePropertyMap());
3450 pPropMap->Insert(PROP_CELL_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, CELL_GRAB_BAG);
3451 m_pImpl->getTableManager().cellProps(pPropMap);
3453 m_pImpl->disableInteropGrabBag();
3455 break;
3456 case NS_ooxml::LN_CT_PPrBase_cnfStyle:
3458 m_pImpl->enableInteropGrabBag("cnfStyle");
3459 resolveSprmProps(*this, rSprm);
3460 rContext->Insert(PROP_PARA_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, PARA_GRAB_BAG);
3461 m_pImpl->disableInteropGrabBag();
3463 break;
3464 case NS_ooxml::LN_EG_RunInnerContent_sym:
3466 resolveSprmProps(*this, rSprm);
3467 SymbolData aSymbolData = m_pImpl->GetSymbolData();
3468 uno::Any aVal( aSymbolData.sFont );
3469 auto xFootnote = rContext->GetFootnote();
3470 if (!xFootnote.is() && m_pImpl->IsInCustomFootnote())
3471 xFootnote = m_pImpl->GetFootnoteContext()->GetFootnote();
3472 if (xFootnote.is())
3474 // DOCX can have different labels for the footnote reference and the footnote area.
3475 // This skips the one from the footnote area and just uses the reference one.
3476 if (!m_pImpl->IsInFootOrEndnote())
3478 auto xAnchorRange = xFootnote->getAnchor();
3479 auto xAnchorCursor(xAnchorRange->getText()->createTextCursorByRange(xAnchorRange));
3481 // append a dummy character, so the following properties will be set as
3482 // as SwpHints::SwTextAttr instead of the SwAttrSet of the paragraph,
3483 // which would be removed by SwXText::Impl::finishOrAppendParagraph
3484 xAnchorCursor->collapseToEnd();
3485 uno::Reference<text::XTextRange> xHackRange(xAnchorCursor, uno::UNO_QUERY);
3486 xHackRange->setString("x");
3488 uno::Reference<beans::XPropertySet> xAnchorProps(xAnchorRange, uno::UNO_QUERY);
3489 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), aVal);
3490 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_ASIAN), aVal);
3491 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_COMPLEX), aVal);
3492 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_CHAR_SET), uno::Any(awt::CharSet::SYMBOL));
3494 // remove the dummy char
3495 xHackRange->setString("");
3497 OUString sLabel = xFootnote->getLabel() + OUStringChar(aSymbolData.cSymbol);
3498 xFootnote->setLabel(sLabel);
3501 else //it's a _real_ symbol
3503 rContext->Insert(PROP_CHAR_FONT_NAME, aVal);
3504 rContext->Insert(PROP_CHAR_FONT_NAME_ASIAN, aVal);
3505 rContext->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aVal);
3506 rContext->Insert(PROP_CHAR_FONT_CHAR_SET, uno::Any(awt::CharSet::SYMBOL));
3507 utext(&(aSymbolData.cSymbol), 1);
3510 break;
3511 case NS_ooxml::LN_EG_RunInnerContent_ruby:
3513 RubyInfo aInfo ;
3514 m_pImpl->SetRubyInfo(aInfo);
3516 break;
3517 case NS_ooxml::LN_CT_RubyPr:
3518 case NS_ooxml::LN_CT_Ruby_rt:
3519 case NS_ooxml::LN_CT_Ruby_rubyBase:
3521 m_pImpl->SetRubySprmId(nSprmId);
3522 if (nSprmId == NS_ooxml::LN_CT_RubyPr)
3524 resolveSprmProps(*this, rSprm);
3527 break;
3528 case NS_ooxml::LN_EG_RubyContent_r:
3530 const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
3531 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase)
3533 rContext->Insert(PROP_RUBY_TEXT, uno::Any(aInfo.sRubyText));
3534 rContext->Insert(PROP_RUBY_STYLE, uno::Any(aInfo.sRubyStyle));
3535 rContext->Insert(PROP_RUBY_ADJUST, uno::Any(static_cast<sal_Int16>(ConversionHelper::convertRubyAlign(aInfo.nRubyAlign))));
3536 if ( aInfo.nRubyAlign == NS_ooxml::LN_Value_ST_RubyAlign_rightVertical )
3537 rContext->Insert(PROP_RUBY_POSITION, uno::Any(css::text::RubyPosition::INTER_CHARACTER));
3539 m_pImpl->SetRubySprmId(0);
3542 break;
3543 case NS_ooxml::LN_CT_RubyPr_rubyAlign:
3544 case NS_ooxml::LN_CT_RubyPr_hps:
3545 case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
3547 RubyInfo aInfo = m_pImpl->GetRubyInfo();
3548 switch(nSprmId)
3550 case NS_ooxml::LN_CT_RubyPr_rubyAlign:
3551 aInfo.nRubyAlign = nIntValue;
3552 break;
3553 case NS_ooxml::LN_CT_RubyPr_hps:
3554 aInfo.nHps= nIntValue;
3555 break;
3556 case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
3557 aInfo.nHpsBaseText = nIntValue;
3558 break;
3560 m_pImpl->SetRubyInfo(aInfo);
3562 break;
3563 case NS_ooxml::LN_CT_SmartTagRun_smartTagPr:
3565 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3566 if (pProperties && m_pImpl->GetTopContextType() == CONTEXT_PARAGRAPH)
3567 pProperties->resolve(m_pImpl->getSmartTagHandler());
3569 break;
3570 case NS_ooxml::LN_CT_DocPartPr_name:
3572 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3573 if (pProperties)
3574 pProperties->resolve(*this);
3576 break;
3577 case NS_ooxml::LN_CT_DocPartPr_category:
3579 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3580 if (pProperties)
3581 pProperties->resolve(*this);
3583 break;
3584 case NS_ooxml::LN_CT_DocPartCategory_gallery:
3586 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3587 if (pProperties)
3588 pProperties->resolve(*this);
3590 break;
3591 case NS_ooxml::LN_EG_RunInnerContent_instrText:
3593 m_pImpl->SetIsTextDeleted(false);
3595 break;
3596 case NS_ooxml::LN_EG_RunInnerContent_delText:
3597 case NS_ooxml::LN_EG_RunInnerContent_delInstrText:
3599 m_pImpl->SetIsTextDeleted(true);
3601 break;
3602 default:
3604 #ifdef DBG_UTIL
3605 TagLogger::getInstance().startElement("unhandled");
3606 TagLogger::getInstance().attribute("id", nSprmId);
3607 TagLogger::getInstance().attribute("name", rSprm.getName());
3608 TagLogger::getInstance().endElement();
3609 #endif
3614 void DomainMapper::ProcessDeferredStyleCharacterProperties()
3616 assert(m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET);
3617 m_pImpl->processDeferredCharacterProperties(false);
3620 void DomainMapper::processDeferredCharacterProperties(
3621 const std::map<sal_Int32, uno::Any>& deferredCharacterProperties, bool bCharContext)
3623 if (bCharContext)
3625 assert(m_pImpl->GetTopContextType() == CONTEXT_CHARACTER);
3627 PropertyMapPtr rContext = m_pImpl->GetTopContext();
3628 for( const auto& rProp : deferredCharacterProperties )
3630 sal_Int32 Id = rProp.first;
3631 sal_Int32 nIntValue = 0;
3632 OUString sStringValue;
3633 rProp.second >>= nIntValue;
3634 rProp.second >>= sStringValue;
3635 switch( Id )
3637 case NS_ooxml::LN_EG_RPrBase_position:
3639 double nEscapement = 0;
3640 sal_Int8 nProp = 0;
3641 if ( nIntValue )
3643 nProp = 100;
3644 double fFontSize = 0;
3645 m_pImpl->GetAnyProperty(PROP_CHAR_HEIGHT, rContext) >>= fFontSize;
3646 if ( fFontSize )
3647 // nIntValue is in half-points, fontsize is in points, escapement is a percentage.
3648 nEscapement = round( nIntValue/2.0 / fFontSize * 100 );
3649 else
3650 nEscapement = nIntValue > 0 ? DFLT_ESC_SUPER : DFLT_ESC_SUB;
3652 if ( nEscapement > MAX_ESC_POS )
3653 nEscapement = MAX_ESC_POS;
3654 else if ( nEscapement < -MAX_ESC_POS )
3655 nEscapement = -MAX_ESC_POS;
3657 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( sal_Int16(nEscapement) ) );
3658 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
3660 break;
3661 default:
3662 SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" );
3663 break;
3668 void DomainMapper::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref)
3670 ref->resolve(*this);
3673 void DomainMapper::data(const sal_uInt8* /*buf*/, size_t /*len*/)
3677 void DomainMapper::lcl_startSectionGroup()
3679 if (!m_pImpl->isInIndexContext() && !m_pImpl->isInBibliographyContext())
3681 m_pImpl->PushProperties(CONTEXT_SECTION);
3683 m_pImpl->SetIsFirstParagraphInSection(true);
3684 m_pImpl->SetIsFirstParagraphInSectionAfterRedline(true);
3687 void DomainMapper::lcl_endSectionGroup()
3689 if (m_pImpl->isInIndexContext() || m_pImpl->isInBibliographyContext())
3690 return;
3692 m_pImpl->CheckUnregisteredFrameConversion();
3693 m_pImpl->ExecuteFrameConversion();
3694 // When pasting, it's fine to not have any paragraph inside the document at all.
3695 if (m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->IsNewDoc())
3697 // This section has no paragraph at all (e.g. they are all actually in a frame).
3698 // If this section has a page break, there would be nothing to apply to the page
3699 // style, so force a dummy paragraph.
3700 lcl_startParagraphGroup();
3701 lcl_startCharacterGroup();
3702 sal_Unicode const sBreak[] = { 0x0d };
3703 lcl_utext(sBreak, 1);
3704 lcl_endCharacterGroup();
3705 lcl_endParagraphGroup();
3707 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_SECTION);
3708 SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
3709 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
3710 if(pSectionContext)
3712 pSectionContext->CloseSectionGroup( *m_pImpl );
3713 // Remove the dummy paragraph if added for
3714 // handling the section properties if section starts with a table
3715 // tdf#135786: Added annotation condition
3716 if (m_pImpl->GetIsDummyParaAddedForTableInSection() && (m_pImpl->GetAnnotationId() < 0))
3717 m_pImpl->RemoveDummyParaForTableInSection();
3719 m_pImpl->SetIsTextFrameInserted( false );
3720 m_pImpl->PopProperties(CONTEXT_SECTION);
3723 void DomainMapper::lcl_startParagraphGroup()
3725 if (m_pImpl->hasTableManager())
3726 m_pImpl->getTableManager().startParagraphGroup();
3728 * Add new para properties only if paragraph is not split
3729 * or the top context is not of paragraph properties
3730 * Set mbIsSplitPara to false as it has been handled
3732 if (!mbIsSplitPara)
3733 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
3734 mbIsSplitPara = false;
3735 if (m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) != m_pImpl->GetTopContext())
3736 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
3738 if (!m_pImpl->IsInShape() && !m_pImpl->IsInComments())
3740 if (m_pImpl->GetTopContext())
3742 const OUString& sDefaultParaStyle = m_pImpl->GetDefaultParaStyleName();
3743 auto pContext = static_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContext().get());
3744 m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::Any( sDefaultParaStyle ) );
3745 m_pImpl->SetCurrentParaStyleName( sDefaultParaStyle );
3747 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3749 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
3751 // With a w:br at the start of a paragraph, compat14 apparently doesn't apply.
3752 // It works to insert a zero margin before importing paragraph properties because
3753 // TopMargin typically imports without overwrite any existing value. Very handy.
3754 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
3756 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3758 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
3760 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
3762 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
3766 mbWasShapeInPara = false;
3768 m_pImpl->clearDeferredBreaks();
3771 if (m_pImpl->isParaSdtEndDeferred() && m_pImpl->GetTopContext())
3772 m_pImpl->GetTopContext()->Insert(PROP_PARA_SDT_END_BEFORE, uno::Any(true), true, PARA_GRAB_BAG);
3773 m_pImpl->setParaSdtEndDeferred(false);
3775 m_pImpl->SetIsFirstRun(true);
3776 m_pImpl->SetIsOutsideAParagraph(false);
3779 void DomainMapper::lcl_endParagraphGroup()
3781 if (m_pImpl->isBreakDeferred(LINE_BREAK))
3783 if (m_pImpl->GetIsLastParagraphInSection())
3784 m_pImpl->clearDeferredBreak(LINE_BREAK);
3786 while (m_pImpl->isBreakDeferred(LINE_BREAK))
3788 m_pImpl->clearDeferredBreak(LINE_BREAK);
3789 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
3793 m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
3794 if (m_pImpl->hasTableManager())
3795 m_pImpl->getTableManager().endParagraphGroup();
3796 //frame conversion has to be executed after table conversion
3797 m_pImpl->ExecuteFrameConversion();
3798 m_pImpl->SetIsOutsideAParagraph(true);
3801 void DomainMapper::markLastParagraphInSection( )
3803 m_pImpl->SetIsLastParagraphInSection( true );
3806 void DomainMapper::markLastSectionGroup( )
3808 m_pImpl->SetIsLastSectionGroup( true );
3811 void DomainMapper::lcl_startShape(uno::Reference<drawing::XShape> const& xShape)
3813 assert(xShape.is());
3815 m_pImpl->AttachTextBoxContentToShape(xShape);
3816 if (m_pImpl->GetTopContext())
3818 // If there is a deferred page break, handle it now, so that the
3819 // started shape will be on the correct page.
3820 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3822 m_pImpl->clearDeferredBreak(PAGE_BREAK);
3823 lcl_startCharacterGroup();
3824 sal_Unicode const sBreak[] = { 0x0d };
3825 lcl_utext(sBreak, 1);
3826 lcl_endCharacterGroup();
3827 lcl_endParagraphGroup();
3828 lcl_startParagraphGroup();
3829 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
3831 m_pImpl->PushShapeContext( xShape );
3832 lcl_startParagraphGroup();
3834 else
3836 // No context? Then this image should not appear directly inside the
3837 // document, just save it for later usage.
3838 m_pImpl->PushPendingShape(xShape);
3841 m_pImpl->SetIsFirstParagraphInShape(true);
3842 mbWasShapeInPara = true;
3845 void DomainMapper::lcl_endShape( )
3847 if (!m_pImpl->GetTopContext())
3848 return;
3850 // End the current table, if there are any. Otherwise the unavoidable
3851 // empty paragraph at the end of the shape text will cause problems: if
3852 // the shape text ends with a table, the extra paragraph will be
3853 // handled as an additional row of the ending table.
3854 if (m_pImpl->hasTableManager())
3855 m_pImpl->getTableManager().endTable();
3857 lcl_endParagraphGroup();
3858 m_pImpl->PopShapeContext( );
3859 // A shape is always inside a paragraph (anchored or inline).
3860 m_pImpl->SetIsOutsideAParagraph(false);
3863 void DomainMapper::lcl_startTextBoxContent()
3865 m_pImpl->PushTextBoxContent();
3868 void DomainMapper::lcl_endTextBoxContent()
3870 m_pImpl->PopTextBoxContent();
3873 void DomainMapper::PushStyleSheetProperties( const PropertyMapPtr& pStyleProperties, bool bAffectTableMngr )
3875 m_pImpl->PushStyleProperties( pStyleProperties );
3876 if ( bAffectTableMngr )
3877 m_pImpl->getTableManager( ).SetStyleProperties( pStyleProperties );
3880 void DomainMapper::PopStyleSheetProperties( bool bAffectTableMngr )
3882 m_pImpl->PopProperties( CONTEXT_STYLESHEET );
3883 if ( bAffectTableMngr )
3885 PropertyMapPtr emptyPtr;
3886 m_pImpl->getTableManager( ).SetStyleProperties( emptyPtr );
3890 void DomainMapper::PushListProperties( const ::tools::SvRef<PropertyMap>& pListProperties )
3892 m_pImpl->PushListProperties( pListProperties );
3895 void DomainMapper::PopListProperties()
3897 m_pImpl->PopProperties( CONTEXT_LIST );
3900 void DomainMapper::lcl_startCharacterGroup()
3902 m_pImpl->PushProperties(CONTEXT_CHARACTER);
3903 if (m_pImpl->isSdtEndDeferred())
3905 // Fields have an empty character group before the real one, so don't
3906 // call setSdtEndDeferred(false) here, that will happen only in lcl_utext().
3907 m_pImpl->GetTopContext()->Insert(PROP_SDT_END_BEFORE, uno::Any(true), true, CHAR_GRAB_BAG);
3911 void DomainMapper::lcl_endCharacterGroup()
3913 if (m_pImpl->CheckFootnoteStyle())
3915 m_pImpl->SetCheckFootnoteStyle(m_pImpl->IsInCustomFootnote());
3916 m_pImpl->SetHasFootnoteStyle(false);
3918 m_pImpl->PopProperties(CONTEXT_CHARACTER);
3921 //copied from rtfsprm
3922 /// Is it problematic to deduplicate this SPRM?
3923 static bool isSPRMDeduplicateDenylist(PropertyIds nId, PropertyMapPtr pContext)
3925 switch (nId)
3927 // See the NS_ooxml::LN_CT_PPrBase_tabs handler in DomainMapper,
3928 // deduplication is explicitly not wanted for these tokens.
3929 case PROP_PARA_TAB_STOPS:
3930 case PROP_PARA_LINE_SPACING:
3931 return true;
3932 case PROP_TOP_BORDER:
3933 case PROP_LEFT_BORDER:
3934 case PROP_BOTTOM_BORDER:
3935 case PROP_RIGHT_BORDER:
3936 case META_PROP_HORIZONTAL_BORDER:
3937 case META_PROP_VERTICAL_BORDER:
3938 return true;
3939 // Removing \fi and \li if the style has the same value would mean taking these values from
3940 // \ls, while deduplication would be done to take the values from the style.
3941 case PROP_PARA_FIRST_LINE_INDENT:
3942 case PROP_PARA_LEFT_MARGIN:
3943 return pContext && pContext->getProperty(PROP_NUMBERING_RULES);
3945 default:
3946 return false;
3950 void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
3952 //TODO: Determine the right text encoding (FIB?)
3953 OUString sText( reinterpret_cast<const char*>(data_), len, RTL_TEXTENCODING_MS_1252 );
3954 #ifdef DBG_UTIL
3955 TagLogger::getInstance().startElement("text");
3956 TagLogger::getInstance().chars(sText);
3957 TagLogger::getInstance().endElement();
3958 #endif
3962 if(len == 1)
3964 switch(*data_)
3966 case 0x02: return; //footnote character
3967 case 0x08: // Lock field if in field context
3968 if (m_pImpl->IsOpenField())
3969 m_pImpl->SetFieldLocked();
3970 return;
3971 case 0x0c: //page break
3972 // page breaks aren't supported in footnotes and endnotes
3973 if (!m_pImpl->IsInFootOrEndnote())
3974 m_pImpl->deferBreak(PAGE_BREAK);
3975 return;
3976 case 0x0e: //column break
3977 m_pImpl->deferBreak(COLUMN_BREAK);
3978 return;
3979 case 0x0a: //line break
3980 if (m_pImpl->GetIsLastParagraphInSection())
3982 m_pImpl->deferBreak(LINE_BREAK);
3983 return;
3985 break;
3986 case 0x07:
3987 m_pImpl->getTableManager().text(data_, len);
3988 return;
3989 case 0x0d:
3991 assert(!"paragraph break is handled by utext() now");
3992 return;
3994 case cFieldStart:
3995 m_pImpl->PushFieldContext();
3996 return;
3997 case cFieldSep:
3998 // delimiter not necessarily available
3999 // appears only if field contains further content
4000 m_pImpl->CloseFieldCommand();
4001 return;
4002 case cFieldEnd:
4003 m_pImpl->PopFieldContext();
4004 return;
4005 default:
4006 break;
4010 // GetTopContext() is changed by inserted breaks, but we want to keep the current context
4011 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4013 while (m_pImpl->isBreakDeferred(LINE_BREAK))
4015 m_pImpl->clearDeferredBreak(LINE_BREAK);
4016 m_pImpl->appendTextPortion("\n", pContext);
4019 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
4021 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
4022 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
4023 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
4024 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
4025 m_pImpl->clearDeferredBreaks();
4028 if (pContext && pContext->GetFootnote().is() && m_pImpl->IsInCustomFootnote())
4030 pContext->GetFootnote()->setLabel(sText);
4031 m_pImpl->EndCustomFootnote();
4032 //otherwise ignore sText
4034 else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields())
4036 m_pImpl->AppendFieldCommand(sText);
4038 else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
4039 /*depending on the success of the field insert operation this result will be
4040 set at the field or directly inserted into the text*/
4041 m_pImpl->AppendFieldResult(sText);
4042 else
4044 if (pContext == nullptr)
4045 pContext = new PropertyMap();
4047 if (sText == "\n")
4049 m_pImpl->HandleLineBreak(pContext);
4051 else
4053 m_pImpl->appendTextPortion(sText, pContext);
4057 catch( const uno::RuntimeException& )
4059 TOOLS_WARN_EXCEPTION("writerfilter", "");
4063 void DomainMapper::lcl_positionOffset(const OUString& rText, bool bVertical)
4065 if (bVertical)
4066 m_pImpl->m_aPositionOffsets.second = rText;
4067 else
4068 m_pImpl->m_aPositionOffsets.first = rText;
4071 awt::Point DomainMapper::getPositionOffset()
4073 awt::Point aRet;
4074 aRet.X = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.first.toInt32());
4075 aRet.Y = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.second.toInt32());
4076 return aRet;
4079 void DomainMapper::lcl_align(const OUString& rText, bool bVertical)
4081 if (bVertical)
4082 m_pImpl->m_aAligns.second = rText;
4083 else
4084 m_pImpl->m_aAligns.first = rText;
4087 void DomainMapper::lcl_positivePercentage(const OUString& rText)
4089 m_pImpl->m_aPositivePercentages.push(rText);
4092 void DomainMapper::lcl_checkId(const sal_Int32 nId)
4094 if (m_pImpl->IsInFootnote())
4096 m_pImpl->m_aFootnoteIds.push_back(nId);
4097 // keep only the first real footnote
4098 if (m_pImpl->GetFootnoteCount() == -1 && m_pImpl->m_aFootnoteIds.size() == 2)
4099 m_pImpl->m_aFootnoteIds.pop_front();
4101 else
4103 m_pImpl->m_aEndnoteIds.push_back(nId);
4104 // keep only the first real endnote
4105 if (m_pImpl->GetEndnoteCount() == -1 && m_pImpl->m_aEndnoteIds.size() == 2)
4106 m_pImpl->m_aEndnoteIds.pop_front();
4110 void DomainMapper::ResetStyleProperties()
4112 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
4113 if (IsRTFImport() && pContext)
4115 //reset paragraph style properties not repeated at the paragraph
4116 std::optional<PropertyMap::Property> paraStyleName = pContext->getProperty(PROP_PARA_STYLE_NAME);
4117 if (paraStyleName.has_value()) {
4118 OUString uStyleName;
4119 paraStyleName->second >>= uStyleName;
4120 StyleSheetEntryPtr pStyleSheet = m_pImpl->GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(uStyleName);
4121 if (pStyleSheet != nullptr)
4123 std::vector< PropertyIds > stylePropertyIds = pStyleSheet->m_pProperties->GetPropertyIds();
4124 std::vector< PropertyIds >::iterator stylePropertyIdsIt = stylePropertyIds.begin();
4125 while (stylePropertyIdsIt != stylePropertyIds.end())
4127 PropertyIds ePropertyId = *stylePropertyIdsIt;
4128 std::optional< PropertyMap::Property > styleProperty = pStyleSheet->m_pProperties->getProperty(ePropertyId);
4129 std::optional< PropertyMap::Property > paragraphProperty = pContext->getProperty(ePropertyId);
4130 if (paragraphProperty.has_value()) {
4131 if (paragraphProperty->second == styleProperty->second &&
4132 !isSPRMDeduplicateDenylist(ePropertyId, pContext))
4134 pContext->Erase(ePropertyId);
4137 else
4139 switch (ePropertyId)
4141 case PROP_PARA_LEFT_MARGIN:
4142 if (!pContext->getProperty(PROP_NUMBERING_RULES))
4144 pContext->Insert(ePropertyId, uno::Any(0l));
4146 break;
4147 case PROP_PARA_RIGHT_MARGIN:
4148 pContext->Insert(ePropertyId, uno::Any(0l));
4149 break;
4150 case PROP_PARA_LAST_LINE_ADJUST:
4151 case PROP_PARA_ADJUST:
4152 pContext->Insert(ePropertyId, uno::Any(style::ParagraphAdjust_LEFT));
4153 break;
4154 case PROP_PARA_TAB_STOPS:
4155 pContext->Insert(ePropertyId, uno::Any(uno::Sequence< style::TabStop >()));
4156 break;
4157 case PROP_FILL_STYLE:
4158 pContext->Insert(ePropertyId, uno::Any(drawing::FillStyle_NONE));
4159 break;
4160 case PROP_FILL_COLOR:
4161 pContext->Insert(ePropertyId, uno::Any(sal_Int32(COL_TRANSPARENT)));
4162 break;
4163 case INVALID:
4164 default:
4165 break;
4168 ++stylePropertyIdsIt;
4175 void DomainMapper::lcl_utext(const sal_Unicode *const data_, size_t len)
4177 // All these fixed values are defined as static const sal_Unicode codepoints in the fast parser,
4178 // like uFtnEdnRef = 0x2, uFtnEdnSep = 0x3, ... and have a len of 1, if they aren't valid unicode.
4180 OUString const sText(data_, len);
4181 const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
4182 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt)
4184 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4185 PropertyValueVector_t aProps = comphelper::sequenceToContainer< PropertyValueVector_t >(pContext->GetPropertyValues());
4186 OUString sStyle = getOrCreateCharStyle(aProps, /*bAlwaysCreate=*/false);
4187 m_pImpl->SetRubyText(sText,sStyle);
4188 return;
4191 if (len == 1)
4193 if (sText[0] == 0x0d)
4195 ResetStyleProperties();
4198 // preload all footnotes in separated footnotes
4199 if (sText[0] == 0x5)
4201 if (m_pImpl->IsInFootnote())
4203 if (m_pImpl->GetFootnoteCount() > -1)
4205 m_pImpl->PopFootOrEndnote();
4206 m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/true);
4208 m_pImpl->IncrementFootnoteCount();
4210 else
4212 if (m_pImpl->GetEndnoteCount() > -1)
4214 m_pImpl->PopFootOrEndnote();
4215 m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/false);
4217 m_pImpl->IncrementEndnoteCount();
4221 // If the footnote contains a Footnote Reference Mark, it can't be a custom footnote
4222 // ******
4223 // This code block is wrong, as it should also be in m_pImpl->IsInFootOrEndnote().
4224 // The main problem is that
4226 // assert(len != 1 || sText[0] != 0x2)
4228 // is triggered by the unit test SwLayoutWriter::testForcepoint75, so all these pseudo
4229 // value handling is broken.
4230 // But this is just a symptom, as I guess it's possible to generate broken DOCX documents,
4231 // which might be problematic, triggering *funny* code paths left and right.
4232 // ******
4233 if (sText[0] == 0x2)
4235 m_pImpl->EndCustomFootnote();
4236 return;
4239 if (m_pImpl->IsInCustomFootnote())
4241 if (sText[0] != 0xd && sText[0] != 0x3)
4243 // DOCX can have different labels for the footnote reference and the footnote area.
4244 // This skips the one from the footnote area and just uses the reference one.
4245 if (!m_pImpl->IsInFootOrEndnote())
4247 if (PropertyMapPtr pFootnoteContext = m_pImpl->GetFootnoteContext())
4249 auto xFootnote = pFootnoteContext->GetFootnote();
4250 xFootnote->setLabel(xFootnote->getLabel() + sText);
4253 return;
4255 else
4256 m_pImpl->SetHasFootnoteStyle(true);
4260 if (m_pImpl->isSdtEndDeferred())
4262 // In case we have a field context, then save the property there, so
4263 // SDT's ending right before a field start are handled as well.
4264 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4265 if (m_pImpl->IsOpenField())
4266 pContext = m_pImpl->GetTopFieldContext()->getProperties();
4267 pContext->Insert(PROP_SDT_END_BEFORE, uno::Any(true), true, CHAR_GRAB_BAG);
4268 m_pImpl->setSdtEndDeferred(false);
4271 bool bNewLine = len == 1 && (sText[0] == 0x0d || sText[0] == 0x07);
4272 if (m_pImpl->GetSdtStarts().empty()
4273 && (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::dropDown
4274 || m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::comboBox))
4276 // Block, cell or row SDT.
4277 if (bNewLine)
4278 // Dropdown control has single-line texts, so in case of newline, create the control.
4279 m_pImpl->m_pSdtHelper->createDropDownControl();
4280 else
4282 m_pImpl->m_pSdtHelper->getSdtTexts().append(sText);
4283 return;
4286 else if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::datePicker)
4288 if (IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
4290 m_pImpl->m_pSdtHelper->getDateFormat().truncate();
4291 m_pImpl->m_pSdtHelper->getLocale().truncate();
4292 return;
4295 else if (m_pImpl->m_pSdtHelper->GetSdtType() != NS_ooxml::LN_CT_SdtRun_sdtContent && m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText)
4297 if (bNewLine)
4299 m_pImpl->m_pSdtHelper->createPlainTextControl();
4300 finishParagraph();
4301 return;
4304 else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty())
4306 // there are unsupported SDT properties in the document
4307 // save them in the paragraph interop grab bag
4308 if (m_pImpl->IsDiscardHeaderFooter())
4310 // Unless we're supposed to ignore this header/footer.
4311 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4312 return;
4314 if((m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") ||
4315 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") ||
4316 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") ||
4317 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") ||
4318 (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") &&
4319 m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph())
4321 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER);
4323 if (m_pImpl->IsOpenField())
4324 // We have a field, insert the SDT properties to the field's grab-bag, so they won't be lost.
4325 pContext = m_pImpl->GetTopFieldContext()->getProperties();
4327 uno::Sequence<beans::PropertyValue> aGrabBag = m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4328 if (m_pImpl->GetSdtStarts().empty()
4329 || (m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown
4330 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::comboBox))
4332 pContext->Insert(PROP_SDTPR, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
4335 else
4337 uno::Sequence<beans::PropertyValue> aGrabBag = m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4338 if (m_pImpl->GetSdtStarts().empty()
4339 || (m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown
4340 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::comboBox
4341 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::richText))
4343 m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR,
4344 uno::Any(aGrabBag), true, PARA_GRAB_BAG);
4348 else if (len == 1 && sText[0] == 0x03)
4350 // This is the uFtnEdnSep, remember that the document has a separator.
4351 m_pImpl->m_bHasFtnSep = true;
4352 return;
4354 else if (len == 1 && sText[0] == '\r')
4356 // Clear "last" one linebreak at end of section
4357 if (m_pImpl->GetIsLastParagraphInSection() && m_pImpl->isBreakDeferred(LINE_BREAK))
4358 m_pImpl->clearDeferredBreak(LINE_BREAK);
4359 // And emit all other linebreaks
4360 while (m_pImpl->isBreakDeferred(LINE_BREAK))
4362 m_pImpl->clearDeferredBreak(LINE_BREAK);
4363 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
4366 else if (len == 1 && sText[0] == '\t' )
4368 if ( m_pImpl->m_bCheckFirstFootnoteTab && m_pImpl->IsInFootOrEndnote() )
4370 // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent
4371 m_pImpl->m_bCheckFirstFootnoteTab = false;
4372 sal_Int32 nFirstLineIndent = 0;
4373 m_pImpl->GetAnyProperty(PROP_PARA_FIRST_LINE_INDENT, m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)) >>= nFirstLineIndent;
4374 if ( nFirstLineIndent < 0 )
4375 m_pImpl->m_bIgnoreNextTab = true;
4378 if ( m_pImpl->m_bIgnoreNextTab )
4380 m_pImpl->m_bIgnoreNextTab = false;
4381 return;
4384 if (!m_pImpl->hasTableManager())
4385 return;
4387 SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
4388 if ( eSkip == SkipFootnoteSeparator::ON || eSkip == SkipFootnoteSeparator::SKIPPING )
4390 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
4391 return;
4396 while (m_pImpl->isBreakDeferred(LINE_BREAK))
4398 m_pImpl->clearDeferredBreak(LINE_BREAK);
4399 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
4402 m_pImpl->getTableManager().utext(data_, len);
4404 if (bNewLine)
4406 const bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection();
4407 const bool bSingleParagraphAfterRedline = m_pImpl->GetIsFirstParagraphInSection(/*bAfterRedline=*/true) &&
4408 m_pImpl->GetIsLastParagraphInSection();
4409 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
4410 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
4412 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
4414 assert(pContext); // can't have deferred break without
4415 if (m_pImpl->GetSettingsTable()->GetSplitPgBreakAndParaMark())
4417 if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
4419 m_pImpl->m_bIsSplitPara = true;
4420 finishParagraph();
4421 lcl_startParagraphGroup();
4423 else // IsFirstRun
4425 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4427 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4431 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
4432 m_pImpl->clearDeferredBreaks();
4435 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
4437 assert(pContext); // can't have deferred break without
4438 if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
4440 mbIsSplitPara = true;
4441 m_pImpl->m_bIsSplitPara = true;
4442 finishParagraph();
4443 lcl_startParagraphGroup();
4445 else // IsFirstRun
4447 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4449 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4453 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
4454 m_pImpl->clearDeferredBreaks();
4458 // If the paragraph contains only the section properties and it has
4459 // no runs, we should not create a paragraph for it in Writer, unless that would remove the whole section.
4460 // Also do not remove here column breaks: they are treated in a different way and place.
4461 bool bIsColumnBreak = false;
4462 if (pContext && pContext->isSet(PROP_BREAK_TYPE))
4464 const uno::Any aBreakType = pContext->getProperty(PROP_BREAK_TYPE)->second;
4465 bIsColumnBreak =
4466 aBreakType == style::BreakType_COLUMN_BEFORE ||
4467 aBreakType == style::BreakType_COLUMN_AFTER ||
4468 aBreakType == style::BreakType_COLUMN_BOTH;
4471 bool bRemove = (!m_pImpl->GetParaChanged() && m_pImpl->GetRemoveThisPara()) ||
4472 (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr()
4473 && !bSingleParagraphAfterRedline
4474 && !bIsColumnBreak
4475 && !m_pImpl->GetIsLastSectionGroup() // testContSectionPageBreak
4476 && !m_pImpl->GetParaHadField()
4477 && !m_pImpl->GetIsPreviousParagraphFramed()
4478 && !m_pImpl->HasTopAnchoredObjects()
4479 && !m_pImpl->IsParaWithInlineObject());
4481 const bool bNoNumbering = bRemove || (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && bSingleParagraph);
4482 PropertyMapPtr xContext = bNoNumbering ? m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) : PropertyMapPtr();
4483 if (xContext)
4485 // tdf#97417 delete numbering of the paragraph
4486 // it will be deleted anyway, and the numbering would be copied
4487 // to the next paragraph in sw SplitNode and then be applied to
4488 // every following paragraph
4489 xContext->Erase(PROP_NUMBERING_RULES);
4490 static_cast<ParagraphPropertyMap*>(xContext.get())->props().SetListId(-1);;
4491 xContext->Erase(PROP_NUMBERING_LEVEL);
4493 finishParagraph(bRemove, bNoNumbering);
4495 m_pImpl->SetParaSectpr(false);
4497 else
4499 // GetTopContext() is changed by inserted breaks, but we want to keep the current context
4500 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4501 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
4503 auto pPara = static_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH).get());
4504 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
4506 /* If PAGEBREAK appears in first paragraph of the section or
4507 * after first run of any paragraph then need to split paragraph
4508 * to handle it properly.
4510 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
4512 m_pImpl->m_bIsSplitPara = true;
4513 finishParagraph();
4514 lcl_startParagraphGroup();
4516 else // IsFirstRun
4518 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4520 pPara->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)), true);
4523 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
4525 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
4527 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() || mbWasShapeInPara)
4529 mbIsSplitPara = true;
4530 m_pImpl->m_bIsSplitPara = true;
4531 finishParagraph();
4532 lcl_startParagraphGroup();
4534 else // IsFirstRun
4536 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4538 pPara->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4541 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
4543 m_pImpl->clearDeferredBreaks();
4546 bool bInSdtBlockText
4547 = m_pImpl->m_pSdtHelper->GetSdtType() == NS_ooxml::LN_CT_SdtBlock_sdtContent
4548 && m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText;
4549 if (pContext && pContext->GetFootnote().is())
4551 pContext->GetFootnote()->setLabel( sText );
4552 // tdf#141548 don't lose footnote/endnote text of the run with uFtnEdnRef
4553 // (i.e. when footnoteRef/endnoteRef is followed by some text in the same run)
4554 m_pImpl->appendTextPortion( sText, pContext );
4556 else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields())
4558 if (bInSdtBlockText)
4560 if (m_pImpl->m_pSdtHelper->hasUnusedText())
4561 m_pImpl->m_pSdtHelper->createPlainTextControl();
4562 else if (!m_pImpl->m_pSdtHelper->isFieldStartRangeSet())
4563 m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
4565 m_pImpl->AppendFieldCommand(sText);
4567 else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
4569 if (bInSdtBlockText)
4571 if (m_pImpl->m_pSdtHelper->hasUnusedText())
4572 m_pImpl->m_pSdtHelper->createPlainTextControl();
4573 else if (!m_pImpl->m_pSdtHelper->isFieldStartRangeSet())
4574 m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
4576 /*depending on the success of the field insert operation this result will be
4577 set at the field or directly inserted into the text*/
4578 m_pImpl->AppendFieldResult(sText);
4580 else
4582 if (pContext == nullptr)
4583 pContext = new PropertyMap();
4585 if (bInSdtBlockText && !m_pImpl->m_pSdtHelper->hasUnusedText())
4586 m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
4588 m_pImpl->appendTextPortion( sText, pContext );
4590 if (bInSdtBlockText && !sText.isEmpty())
4591 m_pImpl->m_pSdtHelper->setHasUnusedText(true);
4595 m_pImpl->SetIsFirstRun(false);
4597 catch( const uno::RuntimeException& )
4602 void DomainMapper::lcl_props(writerfilter::Reference<Properties>::Pointer_t ref)
4604 ref->resolve(*this);
4607 void DomainMapper::lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t ref)
4609 m_pImpl->SetAnyTableImport(true);
4610 switch(name)
4612 case NS_ooxml::LN_FONTTABLE:
4614 // create a font table object that listens to the attributes
4615 // each entry call inserts a new font entry
4616 ref->resolve( *m_pImpl->GetFontTable() );
4617 break;
4618 case NS_ooxml::LN_STYLESHEET:
4619 //same as above to import style sheets
4620 m_pImpl->SetStyleSheetImport( true );
4621 ref->resolve( *m_pImpl->GetStyleSheetTable() );
4622 m_pImpl->GetStyleSheetTable()->ApplyStyleSheets(m_pImpl->GetFontTable());
4623 m_pImpl->SetStyleSheetImport( false );
4624 break;
4625 case NS_ooxml::LN_NUMBERING:
4627 m_pImpl->SetNumberingImport(true);
4628 //the same for list tables
4629 ref->resolve( *m_pImpl->GetListTable() );
4630 m_pImpl->GetListTable( )->CreateNumberingRules( );
4631 m_pImpl->SetNumberingImport(false);
4633 break;
4634 case NS_ooxml::LN_settings_settings:
4635 ref->resolve ( *m_pImpl->GetSettingsTable() );
4636 m_pImpl->ApplySettingsTable();
4637 break;
4638 default:
4639 OSL_FAIL( "which table is to be filled here?");
4641 m_pImpl->SetAnyTableImport(false);
4644 void DomainMapper::lcl_substream(Id rName, ::writerfilter::Reference<Stream>::Pointer_t ref)
4646 m_pImpl->substream(rName, ref);
4649 void DomainMapper::lcl_startGlossaryEntry()
4651 uno::Reference< text::XTextRange > xTextRange = GetCurrentTextRange();
4652 m_pImpl->setGlossaryEntryStart(xTextRange);
4655 void DomainMapper::lcl_endGlossaryEntry()
4657 m_pImpl->appendGlossaryEntry();
4660 void DomainMapper::handleUnderlineType(const Id nId, const ::tools::SvRef<PropertyMap>& rContext)
4662 sal_Int16 nUnderline = awt::FontUnderline::NONE;
4664 switch (nId)
4666 case NS_ooxml::LN_Value_ST_Underline_none:
4667 nUnderline = awt::FontUnderline::NONE;
4668 break;
4669 case NS_ooxml::LN_Value_ST_Underline_words:
4670 rContext->Insert(PROP_CHAR_WORD_MODE, uno::Any(true));
4671 [[fallthrough]];
4672 case NS_ooxml::LN_Value_ST_Underline_single:
4673 nUnderline = awt::FontUnderline::SINGLE;
4674 break;
4675 case NS_ooxml::LN_Value_ST_Underline_double:
4676 nUnderline = awt::FontUnderline::DOUBLE;
4677 break;
4678 case NS_ooxml::LN_Value_ST_Underline_dotted:
4679 nUnderline = awt::FontUnderline::DOTTED;
4680 break;
4681 case NS_ooxml::LN_Value_ST_Underline_dash:
4682 nUnderline = awt::FontUnderline::DASH;
4683 break;
4684 case NS_ooxml::LN_Value_ST_Underline_dotDash:
4685 nUnderline = awt::FontUnderline::DASHDOT;
4686 break;
4687 case NS_ooxml::LN_Value_ST_Underline_dotDotDash:
4688 nUnderline = awt::FontUnderline::DASHDOTDOT;
4689 break;
4690 case NS_ooxml::LN_Value_ST_Underline_thick:
4691 nUnderline = awt::FontUnderline::BOLD;
4692 break;
4693 case NS_ooxml::LN_Value_ST_Underline_wave:
4694 nUnderline = awt::FontUnderline::WAVE;
4695 break;
4696 case NS_ooxml::LN_Value_ST_Underline_dottedHeavy:
4697 nUnderline = awt::FontUnderline::BOLDDOTTED;
4698 break;
4699 case NS_ooxml::LN_Value_ST_Underline_dashedHeavy:
4700 nUnderline = awt::FontUnderline::BOLDDASH;
4701 break;
4702 case NS_ooxml::LN_Value_ST_Underline_dashLong:
4703 nUnderline = awt::FontUnderline::LONGDASH;
4704 break;
4705 case NS_ooxml::LN_Value_ST_Underline_dashLongHeavy:
4706 nUnderline = awt::FontUnderline::BOLDLONGDASH;
4707 break;
4708 case NS_ooxml::LN_Value_ST_Underline_dashDotHeavy:
4709 nUnderline = awt::FontUnderline::BOLDDASHDOT;
4710 break;
4711 case NS_ooxml::LN_Value_ST_Underline_dashDotDotHeavy:
4712 nUnderline = awt::FontUnderline::BOLDDASHDOTDOT;
4713 break;
4714 case NS_ooxml::LN_Value_ST_Underline_wavyHeavy:
4715 nUnderline = awt::FontUnderline::BOLDWAVE;
4716 break;
4717 case NS_ooxml::LN_Value_ST_Underline_wavyDouble:
4718 nUnderline = awt::FontUnderline::DOUBLEWAVE;
4719 break;
4721 rContext->Insert(PROP_CHAR_UNDERLINE, uno::Any(nUnderline));
4724 void DomainMapper::handleParaJustification(const sal_Int32 nIntValue, const ::tools::SvRef<PropertyMap>& rContext, const bool bExchangeLeftRight)
4726 style::ParagraphAdjust nAdjust = style::ParagraphAdjust_LEFT;
4727 style::ParagraphAdjust nLastLineAdjust = style::ParagraphAdjust_LEFT;
4728 OUString aStringValue = "left";
4729 switch(nIntValue)
4731 case NS_ooxml::LN_Value_ST_Jc_center:
4732 nAdjust = style::ParagraphAdjust_CENTER;
4733 aStringValue = "center";
4734 break;
4735 case NS_ooxml::LN_Value_ST_Jc_right:
4736 case NS_ooxml::LN_Value_ST_Jc_end:
4737 nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_LEFT : style::ParagraphAdjust_RIGHT;
4738 aStringValue = "right";
4739 break;
4740 case NS_ooxml::LN_Value_ST_Jc_distribute:
4741 nLastLineAdjust = style::ParagraphAdjust_BLOCK;
4742 [[fallthrough]];
4743 case NS_ooxml::LN_Value_ST_Jc_both:
4744 nAdjust = style::ParagraphAdjust_BLOCK;
4745 aStringValue = "both";
4746 break;
4747 case NS_ooxml::LN_Value_ST_Jc_left:
4748 case NS_ooxml::LN_Value_ST_Jc_start:
4749 default:
4750 nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
4751 break;
4753 rContext->Insert( PROP_PARA_ADJUST, uno::Any( nAdjust ) );
4754 rContext->Insert( PROP_PARA_LAST_LINE_ADJUST, uno::Any( nLastLineAdjust ) );
4755 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "jc", aStringValue);
4758 bool DomainMapper::getColorFromId(const Id nId, sal_Int32 &nColor)
4760 nColor = 0;
4761 if ((nId < NS_ooxml::LN_Value_ST_HighlightColor_black) || (nId > NS_ooxml::LN_Value_ST_HighlightColor_none))
4762 return false;
4764 switch (nId)
4766 case NS_ooxml::LN_Value_ST_HighlightColor_black: nColor=0x000000; break;
4767 case NS_ooxml::LN_Value_ST_HighlightColor_blue: nColor=0x0000ff; break;
4768 case NS_ooxml::LN_Value_ST_HighlightColor_cyan: nColor=0x00ffff; break;
4769 case NS_ooxml::LN_Value_ST_HighlightColor_green: nColor=0x00ff00; break;
4770 case NS_ooxml::LN_Value_ST_HighlightColor_magenta: nColor=0xff00ff; break;
4771 case NS_ooxml::LN_Value_ST_HighlightColor_red: nColor=0xff0000; break;
4772 case NS_ooxml::LN_Value_ST_HighlightColor_yellow: nColor=0xffff00; break;
4773 case NS_ooxml::LN_Value_ST_HighlightColor_white: nColor=0xffffff; break;
4774 case NS_ooxml::LN_Value_ST_HighlightColor_darkBlue: nColor=0x000080; break;
4775 case NS_ooxml::LN_Value_ST_HighlightColor_darkCyan: nColor=0x008080; break;
4776 case NS_ooxml::LN_Value_ST_HighlightColor_darkGreen: nColor=0x008000; break;
4777 case NS_ooxml::LN_Value_ST_HighlightColor_darkMagenta: nColor=0x800080; break;
4778 case NS_ooxml::LN_Value_ST_HighlightColor_darkRed: nColor=0x800000; break;
4779 case NS_ooxml::LN_Value_ST_HighlightColor_darkYellow: nColor=0x808000; break;
4780 case NS_ooxml::LN_Value_ST_HighlightColor_darkGray: nColor=0x808080; break;
4781 case NS_ooxml::LN_Value_ST_HighlightColor_lightGray: nColor=0xC0C0C0; break;
4782 case NS_ooxml::LN_Value_ST_HighlightColor_none: nColor=0xFFFFFFFF; break; //COL_AUTO
4783 default:
4784 return false;
4786 return true;
4789 sal_Int16 DomainMapper::getEmphasisValue(const sal_Int32 nIntValue)
4791 switch (nIntValue)
4793 case NS_ooxml::LN_Value_ST_Em_dot:
4794 return text::FontEmphasis::DOT_ABOVE;
4795 case NS_ooxml::LN_Value_ST_Em_comma:
4796 return text::FontEmphasis::ACCENT_ABOVE;
4797 case NS_ooxml::LN_Value_ST_Em_circle:
4798 return text::FontEmphasis::CIRCLE_ABOVE;
4799 case NS_ooxml::LN_Value_ST_Em_underDot:
4800 return text::FontEmphasis::DOT_BELOW;
4801 default:
4802 return text::FontEmphasis::NONE;
4806 OUString DomainMapper::getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix)
4808 switch(nIntValue)
4810 case NS_ooxml::LN_Value_ST_CombineBrackets_round:
4811 if (bIsPrefix)
4812 return "(";
4813 return ")";
4815 case NS_ooxml::LN_Value_ST_CombineBrackets_square:
4816 if (bIsPrefix)
4817 return "[";
4818 return "]";
4820 case NS_ooxml::LN_Value_ST_CombineBrackets_angle:
4821 if (bIsPrefix)
4822 return "<";
4823 return ">";
4825 case NS_ooxml::LN_Value_ST_CombineBrackets_curly:
4826 if (bIsPrefix)
4827 return "{";
4828 return "}";
4830 case NS_ooxml::LN_Value_ST_CombineBrackets_none:
4831 default:
4832 return OUString();
4836 style::TabAlign DomainMapper::getTabAlignFromValue(const sal_Int32 nIntValue)
4838 switch (nIntValue)
4840 case NS_ooxml::LN_Value_ST_TabJc_start:
4841 case NS_ooxml::LN_Value_ST_TabJc_left:
4842 case NS_ooxml::LN_Value_ST_TabJc_bar: // bar not supported
4843 case NS_ooxml::LN_Value_ST_TabJc_num: // num not supported
4844 return style::TabAlign_LEFT;
4845 case NS_ooxml::LN_Value_ST_TabJc_center:
4846 return style::TabAlign_CENTER;
4847 case NS_ooxml::LN_Value_ST_TabJc_end:
4848 case NS_ooxml::LN_Value_ST_TabJc_right:
4849 return style::TabAlign_RIGHT;
4850 case NS_ooxml::LN_Value_ST_TabJc_decimal:
4851 return style::TabAlign_DECIMAL;
4853 return style::TabAlign_LEFT;
4856 sal_Unicode DomainMapper::getFillCharFromValue(const sal_Int32 nIntValue)
4858 switch (nIntValue)
4860 case NS_ooxml::LN_Value_ST_TabTlc_dot:
4861 return u'.';
4862 case NS_ooxml::LN_Value_ST_TabTlc_hyphen:
4863 return u'-';
4864 case NS_ooxml::LN_Value_ST_TabTlc_underscore:
4865 case NS_ooxml::LN_Value_ST_TabTlc_heavy: // FIXME ???
4866 return u'_';
4867 case NS_ooxml::LN_Value_ST_TabTlc_middleDot: // middleDot
4868 return u'\x00b7';
4869 case NS_ooxml::LN_Value_ST_TabTlc_none:
4870 default:
4871 return u' '; // blank space
4875 bool DomainMapper::IsOOXMLImport() const
4877 return m_pImpl->IsOOXMLImport();
4880 bool DomainMapper::IsRTFImport() const
4882 return m_pImpl->IsRTFImport();
4885 uno::Reference < lang::XMultiServiceFactory > const & DomainMapper::GetTextFactory() const
4887 return m_pImpl->GetTextFactory();
4890 uno::Reference< text::XTextRange > DomainMapper::GetCurrentTextRange()
4892 if (m_pImpl->HasTopText())
4893 return m_pImpl->GetTopTextAppend()->getEnd();
4894 return m_pImpl->m_xInsertTextRange;
4897 OUString DomainMapper::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate )
4899 StyleSheetTablePtr pStyleSheets = m_pImpl->GetStyleSheetTable();
4900 return pStyleSheets->getOrCreateCharStyle( rCharProperties, bAlwaysCreate );
4903 StyleSheetTablePtr const & DomainMapper::GetStyleSheetTable( )
4905 return m_pImpl->GetStyleSheetTable( );
4908 SettingsTablePtr const & DomainMapper::GetSettingsTable()
4910 return m_pImpl->GetSettingsTable();
4913 GraphicZOrderHelper* DomainMapper::graphicZOrderHelper()
4915 if (m_zOrderHelper == nullptr)
4916 m_zOrderHelper.reset( new GraphicZOrderHelper );
4917 return m_zOrderHelper.get();
4920 uno::Reference<drawing::XShape> DomainMapper::PopPendingShape()
4922 return m_pImpl->PopPendingShape();
4925 bool DomainMapper::IsInHeaderFooter() const
4927 return m_pImpl->IsInHeaderFooter();
4930 bool DomainMapper::IsInShape() const { return m_pImpl->IsInShape(); }
4932 bool DomainMapper::IsInTable() const
4934 return m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell();
4937 OUString DomainMapper::GetListStyleName(sal_Int32 nListId) const
4939 return m_pImpl->GetListStyleName( nListId );
4942 void DomainMapper::ValidateListLevel(const OUString& sStyleIdentifierD)
4944 m_pImpl->ValidateListLevel(sStyleIdentifierD);
4947 void DomainMapper::SetDocDefaultsImport(bool bSet)
4949 m_pImpl->SetDocDefaultsImport(bSet);
4952 bool DomainMapper::IsStyleSheetImport() const
4954 return m_pImpl->IsStyleSheetImport();
4957 bool DomainMapper::IsNumberingImport() const
4959 return m_pImpl->IsNumberingImport();
4962 void DomainMapper::enableInteropGrabBag(const OUString& aName)
4964 m_pImpl->m_aInteropGrabBagName = aName;
4967 beans::PropertyValue DomainMapper::getInteropGrabBag()
4969 beans::PropertyValue aRet;
4970 aRet.Name = m_pImpl->m_aInteropGrabBagName;
4971 aRet.Value <<= comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag);
4973 m_pImpl->m_aInteropGrabBag.clear();
4974 m_pImpl->m_aInteropGrabBagName.clear();
4975 return aRet;
4978 void DomainMapper::HandleRedline( Sprm& rSprm )
4980 sal_uInt32 nSprmId = rSprm.getId();
4982 m_pImpl->AddNewRedline( nSprmId );
4984 if (nSprmId == NS_ooxml::LN_CT_PPr_pPrChange)
4986 m_pImpl->SetCurrentRedlineToken(XML_ParagraphFormat);
4988 else if (nSprmId == NS_ooxml::LN_CT_TrPr_ins)
4990 m_pImpl->SetCurrentRedlineToken(XML_tableRowInsert);
4992 else if (nSprmId == NS_ooxml::LN_CT_TrPr_del)
4994 m_pImpl->SetCurrentRedlineToken(XML_tableRowDelete);
4996 else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellIns)
4998 m_pImpl->SetCurrentRedlineToken(XML_tableCellInsert);
5000 else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellDel)
5002 m_pImpl->SetCurrentRedlineToken(XML_tableCellDelete);
5005 resolveSprmProps(*this, rSprm );
5006 // now the properties author, date and id should be available
5007 sal_Int32 nToken = m_pImpl->GetCurrentRedlineToken();
5008 switch( nToken & 0xffff )
5010 case XML_mod:
5011 case XML_ins:
5012 case XML_del:
5013 case XML_moveTo:
5014 case XML_moveFrom:
5015 case XML_ParagraphFormat:
5016 case XML_tableRowInsert:
5017 case XML_tableRowDelete:
5018 case XML_tableCellInsert:
5019 case XML_tableCellDelete:
5020 break;
5021 default: OSL_FAIL( "redline token other than mod, ins, del, moveTo, moveFrom or table row" ); break;
5023 m_pImpl->EndParaMarkerChange( );
5024 m_pImpl->SetCurrentRedlineIsRead();
5027 void DomainMapper::finishParagraph(const bool bRemove, const bool bNoNumbering)
5029 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::datePicker)
5030 m_pImpl->m_pSdtHelper->createDateContentControl();
5031 m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), bRemove, bNoNumbering);
5032 if (bRemove || mbIsLastPara)
5033 m_pImpl->RemoveLastParagraph();
5034 mbIsLastPara = false; // handle other subdocuments
5037 void DomainMapper::commentProps(const OUString& sId, const CommentProperties& rProps)
5039 m_pImpl->commentProps(sId, rProps);
5042 css::uno::Reference<css::container::XNameContainer> const & DomainMapper::GetCharacterStyles()
5044 return m_pImpl->GetCharacterStyles();
5047 OUString DomainMapper::GetUnusedCharacterStyleName()
5049 return m_pImpl->GetUnusedCharacterStyleName();
5052 } //namespace writerfilter
5054 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */