android: Update app-specific/MIME type icons
[LibreOffice.git] / writerfilter / source / dmapper / DomainMapper.cxx
blob148bb98eaf4230f4fc6872c1f01fdb651b10c8d7
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>
35 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
36 #include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp>
37 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
38 #include <com/sun/star/table/BorderLineStyle.hpp>
39 #include <com/sun/star/table/ShadowFormat.hpp>
40 #include <com/sun/star/text/HoriOrientation.hpp>
41 #include <com/sun/star/text/RelOrientation.hpp>
42 #include <com/sun/star/text/VertOrientation.hpp>
43 #include <com/sun/star/text/WrapTextMode.hpp>
44 #include <com/sun/star/text/SizeType.hpp>
45 #include <com/sun/star/text/XEndnotesSupplier.hpp>
46 #include <com/sun/star/text/XFootnotesSupplier.hpp>
47 #include <com/sun/star/text/XLineNumberingProperties.hpp>
48 #include <com/sun/star/awt/FontRelief.hpp>
49 #include <com/sun/star/awt/FontWeight.hpp>
50 #include <com/sun/star/awt/FontUnderline.hpp>
51 #include <com/sun/star/awt/FontStrikeout.hpp>
52 #include <com/sun/star/awt/FontSlant.hpp>
53 #include <com/sun/star/document/XEventBroadcaster.hpp>
54 #include <com/sun/star/style/ParagraphAdjust.hpp>
55 #include <com/sun/star/style/BreakType.hpp>
56 #include <com/sun/star/style/CaseMap.hpp>
57 #include <com/sun/star/style/LineSpacing.hpp>
58 #include <com/sun/star/style/LineSpacingMode.hpp>
59 #include <com/sun/star/text/FootnoteNumbering.hpp>
60 #include <com/sun/star/text/TextGridMode.hpp>
61 #include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
62 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
63 #include <com/sun/star/text/WritingMode.hpp>
64 #include <com/sun/star/text/WritingMode2.hpp>
65 #include <com/sun/star/text/XFootnote.hpp>
66 #include <com/sun/star/text/XTextColumns.hpp>
67 #include <com/sun/star/text/RubyPosition.hpp>
68 #include <com/sun/star/uno/XComponentContext.hpp>
69 #include <com/sun/star/text/FontEmphasis.hpp>
70 #include <com/sun/star/awt/CharSet.hpp>
71 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
72 #include <com/sun/star/util/XComplexColor.hpp>
73 #include <comphelper/types.hxx>
74 #include <comphelper/storagehelper.hxx>
75 #include <comphelper/sequence.hxx>
76 #include <editeng/escapementitem.hxx>
77 #include <filter/msfilter/util.hxx>
78 #include <sfx2/DocumentMetadataAccess.hxx>
79 #include <unotools/localedatawrapper.hxx>
80 #include <unotools/mediadescriptor.hxx>
82 #include "TextEffectsHandler.hxx"
83 #include "ThemeColorHandler.hxx"
84 #include "CellColorHandler.hxx"
85 #include "SectionColumnHandler.hxx"
86 #include "GraphicHelpers.hxx"
87 #include <dmapper/GraphicZOrderHelper.hxx>
88 #include <comphelper/diagnose_ex.hxx>
89 #include <sal/log.hxx>
90 #include <tools/UnitConversion.hxx>
92 using namespace ::com::sun::star;
93 using namespace oox;
95 namespace writerfilter::dmapper{
97 struct
99 sal_Int32 h;
100 bool orient;
101 sal_Int32 w;
102 } CT_PageSz;
105 DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xContext,
106 uno::Reference<io::XInputStream> const& xInputStream,
107 uno::Reference<lang::XComponent> const& xModel,
108 bool bRepairStorage,
109 SourceDocumentType eDocumentType,
110 utl::MediaDescriptor const & rMediaDesc) :
111 LoggedProperties("DomainMapper"),
112 LoggedTable("DomainMapper"),
113 LoggedStream("DomainMapper"),
114 m_pImpl(new DomainMapper_Impl(*this, xContext, xModel, eDocumentType, rMediaDesc)),
115 mbIsSplitPara(false),
116 mbHasControls(false),
117 mbWasShapeInPara(false)
119 if (m_pImpl->IsNewDoc())
121 // #i24363# tab stops relative to indent
122 m_pImpl->SetDocumentSettingsProperty(
123 getPropertyName(PROP_TABS_RELATIVE_TO_INDENT),
124 uno::Any(false));
125 m_pImpl->SetDocumentSettingsProperty(
126 getPropertyName(PROP_SURROUND_TEXT_WRAP_SMALL),
127 uno::Any(true));
128 m_pImpl->SetDocumentSettingsProperty(
129 getPropertyName(PROP_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING),
130 uno::Any(true));
132 // Don't load the default style definitions to avoid weird mix
133 m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::Any(true));
134 m_pImpl->SetDocumentSettingsProperty("MsWordCompTrailingBlanks", uno::Any(true));
135 m_pImpl->SetDocumentSettingsProperty("HeaderSpacingBelowLastPara",
136 uno::Any(true));
137 m_pImpl->SetDocumentSettingsProperty("FrameAutowidthWithMorePara", uno::Any(true));
138 m_pImpl->SetDocumentSettingsProperty("FootnoteInColumnToPageEnd", uno::Any(true));
139 m_pImpl->SetDocumentSettingsProperty("TabAtLeftIndentForParagraphsInList", uno::Any(true));
141 // Enable only for new documents, since pasting from clipboard can influence existing doc
142 m_pImpl->SetDocumentSettingsProperty("NoNumberingShowFollowBy", uno::Any(true));
145 // Initialize RDF metadata, to be able to add statements during the import.
148 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY_THROW);
149 uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
150 OUString aBaseURL = rMediaDesc.getUnpackedValueOrDefault("URL", OUString());
151 const uno::Reference<frame::XModel> xModel_(xModel,
152 uno::UNO_QUERY_THROW);
153 const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xContext, xModel_, aBaseURL, u""));
154 const uno::Reference<task::XInteractionHandler> xHandler;
155 xDocumentMetadataAccess->loadMetadataFromStorage(xStorage, xBaseURI, xHandler);
157 catch (const uno::Exception&)
159 DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize RDF metadata");
162 if (eDocumentType == SourceDocumentType::OOXML) {
163 // tdf#108350
164 // In Word since version 2007, the default document font is Calibri 11 pt.
165 // If a DOCX document doesn't contain font information, we should assume
166 // the intended font to provide best layout match.
169 uno::Reference< beans::XPropertySet > xDefProps(GetTextFactory()->createInstance("com.sun.star.text.Defaults"),
170 uno::UNO_QUERY_THROW);
171 xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), css::uno::Any(OUString("Calibri")));
172 xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), css::uno::Any(double(11)));
174 catch (const uno::Exception&)
176 DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize default font");
180 //import document properties
183 m_pImpl->m_xDocumentStorage = comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(
184 OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xContext, bRepairStorage);
186 uno::Reference< uno::XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext(
187 "com.sun.star.document.OOXMLDocumentPropertiesImporter",
188 xContext);
190 uno::Reference< document::XOOXMLDocumentPropertiesImporter > xImporter( xTemp, uno::UNO_QUERY_THROW );
191 uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier( xModel, uno::UNO_QUERY_THROW);
192 xImporter->importProperties(m_pImpl->m_xDocumentStorage,
193 xPropSupplier->getDocumentProperties());
195 catch( const uno::Exception& ) {}
198 void DomainMapper::setDocumentReference(writerfilter::ooxml::OOXMLDocument* pDocument)
200 m_pImpl->setDocumentReference(pDocument);
203 DomainMapper::~DomainMapper()
207 // Remove temporary footnotes and endnotes
208 m_pImpl->RemoveTemporaryFootOrEndnotes();
210 uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
211 sal_Int32 nIndexes = 0;
212 if( xIndexesSupplier.is() )
214 uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes();
215 nIndexes = xIndexes->getCount();
217 // If we have page references, those need updating as well, similar to the indexes.
218 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
219 if(xTextFieldsSupplier.is())
221 uno::Reference<container::XEnumeration> xEnumeration = xTextFieldsSupplier->getTextFields()->createEnumeration();
222 while(xEnumeration->hasMoreElements())
224 ++nIndexes;
225 xEnumeration->nextElement();
229 mbHasControls |= m_pImpl->m_pSdtHelper->hasElements();
230 if ( nIndexes || mbHasControls )
232 //index update has to wait until first view is created
233 uno::Reference< document::XEventBroadcaster > xBroadcaster(xIndexesSupplier, uno::UNO_QUERY);
234 if (xBroadcaster.is())
235 xBroadcaster->addEventListener(uno::Reference< document::XEventListener >(new ModelEventListener(nIndexes, mbHasControls)));
239 // Apply the document settings for both DOCX and RTF after everything else
240 m_pImpl->GetSettingsTable()->ApplyProperties( m_pImpl->GetTextDocument( ) );
242 // now that importing is finished, re-enable default styles for any that were never defined/imported.
243 m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::Any(false));
245 // Grab-bag handling
246 comphelper::SequenceAsHashMap aProperties;
248 // Add the saved w:themeFontLang setting
249 aProperties["ThemeFontLangProps"] <<= m_pImpl->GetSettingsTable()->GetThemeFontLangProperties();
251 // Add the saved compat settings
252 aProperties["CompatSettings"] <<= m_pImpl->GetSettingsTable()->GetCompatSettings();
254 // Add the saved DocumentProtection settings
255 aProperties["DocumentProtection"] <<= m_pImpl->GetSettingsTable()->GetDocumentProtectionSettings();
257 // Add the saved w:doNotHyphenateCaps setting
258 aProperties["NoHyphenateCaps"] <<= m_pImpl->GetSettingsTable()->GetNoHyphenateCaps();
260 uno::Reference<beans::XPropertySet> xDocProps(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
261 if (xDocProps.is())
263 comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue("InteropGrabBag"));
264 aGrabBag.update(aProperties);
265 xDocProps->setPropertyValue("InteropGrabBag", uno::Any(aGrabBag.getAsConstPropertyValueList()));
268 // tdf#138782: for docs created in MS Word 2010 and older (compatibilityMode <= 14)
269 m_pImpl->SetDocumentSettingsProperty(
270 "AddFrameOffsets",
271 uno::Any(14 >= m_pImpl->GetSettingsTable()->GetWordCompatibilityMode()));
273 catch( const uno::Exception& ) {}
275 #ifdef DBG_UTIL
276 TagLogger::getInstance().endDocument();
277 #endif
280 void DomainMapper::lcl_attribute(Id nName, Value & val)
282 if (m_pImpl->hasTableManager() && m_pImpl->getTableManager().attribute(nName, val))
283 return;
285 static const int nSingleLineSpacing = 240;
286 sal_Int32 nIntValue = val.getInt();
287 OUString sStringValue = val.getString();
289 SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
290 switch( nName )
292 case NS_ooxml::LN_CT_Lvl_start:
293 break;
294 case NS_ooxml::LN_CT_Lvl_numFmt:
295 break;
296 case NS_ooxml::LN_CT_Lvl_isLgl:
297 break;
298 case NS_ooxml::LN_CT_Lvl_legacy:
299 break;
300 case NS_ooxml::LN_CT_AbstractNum_nsid:
301 break;
302 case NS_ooxml::LN_CT_AbstractNum_tmpl:
303 break;
304 case NS_ooxml::LN_CT_Border_sz:
305 break;
306 case NS_ooxml::LN_CT_Border_val:
307 break;
308 case NS_ooxml::LN_CT_Border_space:
309 break;
310 case NS_ooxml::LN_CT_Border_shadow:
311 break;
312 case NS_ooxml::LN_CT_Border_frame:
313 break;
314 case NS_ooxml::LN_headerr:
315 break;
316 case NS_ooxml::LN_footerr:
317 break;
318 case NS_ooxml::LN_endnote:
319 break;
320 case NS_ooxml::LN_CT_Bookmark_name:
321 m_pImpl->SetBookmarkName( sStringValue );
322 break;
323 case NS_ooxml::LN_CT_MarkupRangeBookmark_id:
324 // add a bookmark range -- this remembers a bookmark starting here
325 // or, if the bookmark was already started or, if the bookmark was
326 // already started before, writes out the bookmark
327 m_pImpl->StartOrEndBookmark( sStringValue );
328 break;
329 case NS_ooxml::LN_CT_MarkupRange_displacedByCustomXml:
330 break;
331 case NS_ooxml::LN_NUMBERING:
332 break;
333 case NS_ooxml::LN_FONTTABLE:
334 break;
335 case NS_ooxml::LN_STYLESHEET:
336 break;
338 case NS_ooxml::LN_CT_Sym_char:
339 m_pImpl->SetSymbolChar(nIntValue);
340 break;
341 case NS_ooxml::LN_CT_Sym_font:
342 m_pImpl->SetSymbolFont(sStringValue);
343 break;
344 case NS_ooxml::LN_CT_Underline_val:
345 if (m_pImpl->GetTopContext())
346 handleUnderlineType(nIntValue, m_pImpl->GetTopContext());
347 break;
348 case NS_ooxml::LN_CT_Underline_color:
349 if (m_pImpl->GetTopContext())
351 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_HAS_COLOR, uno::Any( true ) );
352 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COLOR, uno::Any( nIntValue ) );
354 break;
355 case NS_ooxml::LN_CT_Underline_themeColor:
356 case NS_ooxml::LN_CT_Underline_themeTint:
357 case NS_ooxml::LN_CT_Underline_themeShade:
358 if (m_pImpl->GetTopContext())
360 uno::Reference<util::XComplexColor> xComplexColor;
361 model::ComplexColor aComplexColor;
363 PropertyMapPtr pTopContext = m_pImpl->GetTopContext();
364 std::optional<PropertyMap::Property> aValue;
365 if (pTopContext && (aValue = pTopContext->getProperty(PROP_CHAR_UNDERLINE_COMPLEX_COLOR)))
367 aValue->second >>= xComplexColor;
368 if (xComplexColor.is())
369 aComplexColor = model::color::getFromXComplexColor(xComplexColor);
372 if (nName == NS_ooxml::LN_CT_Underline_themeColor)
374 auto eThemeColorType = TDefTableHandler::getThemeColorTypeIndex(nIntValue);
375 aComplexColor.setSchemeColor(eThemeColorType);
377 else if (nName == NS_ooxml::LN_CT_Underline_themeTint)
379 if (nIntValue > 0)
381 sal_Int16 nTransformedValue = sal_Int16((255.0 - nIntValue) * 10000.0 / 255.0);
382 aComplexColor.addTransformation({model::TransformationType::Tint, sal_Int16(nTransformedValue)});
385 else if (nName == NS_ooxml::LN_CT_Underline_themeShade)
387 if (nIntValue > 0)
389 sal_Int16 nTransformedValue = sal_Int16((255.0 - nIntValue) * 10000.0 / 255.0);
390 aComplexColor.addTransformation({model::TransformationType::Shade, sal_Int16(nTransformedValue)});
393 xComplexColor = model::color::createXComplexColor(aComplexColor);
394 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COMPLEX_COLOR, uno::Any(xComplexColor));
396 break;
398 case NS_ooxml::LN_CT_TabStop_val:
399 if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_TabJc_clear)
401 m_pImpl->m_aCurrentTabStop.bDeleted = true;
403 else
405 m_pImpl->m_aCurrentTabStop.bDeleted = false;
406 m_pImpl->m_aCurrentTabStop.Alignment = getTabAlignFromValue(nIntValue);
408 break;
409 case NS_ooxml::LN_CT_TabStop_leader:
410 m_pImpl->m_aCurrentTabStop.FillChar = getFillCharFromValue(nIntValue);
411 break;
412 case NS_ooxml::LN_CT_TabStop_pos:
413 m_pImpl->m_aCurrentTabStop.Position = ConversionHelper::convertTwipToMM100(nIntValue);
414 break;
416 case NS_ooxml::LN_CT_Fonts_ascii:
417 if (m_pImpl->GetTopContext())
419 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, uno::Any( sStringValue ));
421 break;
422 case NS_ooxml::LN_CT_Fonts_asciiTheme:
423 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeHandler::getStringForTheme(nIntValue));
424 if (m_pImpl->GetTopContext())
426 // note: overwrite Fonts_ascii with Fonts_asciiTheme *even if*
427 // theme font is empty - this is apparently what Word 2013 does
428 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
429 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, aPropValue );
430 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_ASCII, aPropValue, true, CHAR_GRAB_BAG );
431 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_ASCII, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
433 break;
434 case NS_ooxml::LN_CT_Fonts_hAnsi:
435 break;//unsupported
436 case NS_ooxml::LN_CT_Fonts_hAnsiTheme:
437 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeHandler::getStringForTheme(nIntValue));
438 if (m_pImpl->GetTopContext())
439 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_H_ANSI, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
440 break;
441 case NS_ooxml::LN_CT_Fonts_eastAsia:
442 if (m_pImpl->GetTopContext())
443 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::Any( sStringValue ));
444 break;
445 case NS_ooxml::LN_CT_Fonts_eastAsiaTheme:
446 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsiaTheme", ThemeHandler::getStringForTheme(nIntValue));
447 if (m_pImpl->GetTopContext())
449 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
450 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, aPropValue );
451 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_EAST_ASIA, aPropValue, true, CHAR_GRAB_BAG );
452 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_EAST_ASIA, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
454 break;
455 case NS_ooxml::LN_CT_Fonts_cs:
456 if (m_pImpl->GetTopContext())
457 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::Any( sStringValue ));
458 break;
459 case NS_ooxml::LN_CT_Fonts_cstheme:
460 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "cstheme", ThemeHandler::getStringForTheme(nIntValue));
461 if (m_pImpl->GetTopContext())
463 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
464 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aPropValue );
465 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_CS, aPropValue, true, CHAR_GRAB_BAG );
466 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_CS, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
468 break;
469 case NS_ooxml::LN_CT_Spacing_before:
470 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "before", OUString::number(nIntValue));
471 if (m_pImpl->GetTopContext())
472 // Don't overwrite NS_ooxml::LN_CT_Spacing_beforeAutospacing.
473 m_pImpl->GetTopContext()->Insert(
474 PROP_PARA_TOP_MARGIN,
475 uno::Any(static_cast<sal_Int32>(convertTwipToMm100(nIntValue))), false);
476 break;
477 case NS_ooxml::LN_CT_Spacing_beforeLines:
478 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "beforeLines", OUString::number(nIntValue));
479 // We would need to make sure that this doesn't overwrite any
480 // NS_ooxml::LN_CT_Spacing_before in parent styles before style
481 // sheet support can be enabled.
482 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
483 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
484 break;
485 case NS_ooxml::LN_CT_Spacing_after:
486 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "after", OUString::number(nIntValue));
487 if (m_pImpl->GetTopContext())
489 // Don't overwrite NS_ooxml::LN_CT_Spacing_afterAutospacing.
490 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
492 uno::Any aContextualSpacingFromStyle = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_CONTEXT_MARGIN);
493 if (aContextualSpacingFromStyle.hasValue())
494 // Setting "after" spacing means Writer doesn't inherit
495 // contextual spacing anymore from style, but Word does.
496 m_pImpl->GetTopContext()->Insert(PROP_PARA_CONTEXT_MARGIN, aContextualSpacingFromStyle);
498 break;
499 case NS_ooxml::LN_CT_Spacing_afterLines:
500 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "afterLines", OUString::number(nIntValue));
501 // We would need to make sure that this doesn't overwrite any
502 // NS_ooxml::LN_CT_Spacing_after in parent styles before style
503 // sheet support can be enabled.
504 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
505 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
506 break;
507 case NS_ooxml::LN_CT_Spacing_line: //91434
508 case NS_ooxml::LN_CT_Spacing_lineRule: //91435
510 style::LineSpacing aSpacing;
511 PropertyMapPtr pTopContext = m_pImpl->GetTopContext();
512 std::optional<PropertyMap::Property> aLineSpacingVal;
513 if (pTopContext && (aLineSpacingVal = pTopContext->getProperty(PROP_PARA_LINE_SPACING)) )
515 aLineSpacingVal->second >>= aSpacing;
517 else
519 //default to single line spacing
520 aSpacing.Mode = style::LineSpacingMode::FIX;
521 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
523 if( nName == NS_ooxml::LN_CT_Spacing_line )
525 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "line", OUString::number(nIntValue));
526 //now set the value depending on the Mode
527 if( aSpacing.Mode == style::LineSpacingMode::PROP )
528 aSpacing.Height = sal_Int16(nIntValue * 100 / nSingleLineSpacing );
529 else
530 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nIntValue ));
532 else //NS_ooxml::LN_CT_Spacing_lineRule:
534 // exactly, atLeast, auto
535 if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_auto)
537 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "auto");
538 if (aSpacing.Height >= 0)
540 aSpacing.Mode = style::LineSpacingMode::PROP;
541 //reinterpret the already set value
542 aSpacing.Height = sal_Int16( aSpacing.Height * 100 / ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
544 else
546 // Negative value still means a positive height,
547 // just the mode is "exact".
548 aSpacing.Mode = style::LineSpacingMode::FIX;
549 aSpacing.Height *= -1;
552 else if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast)
554 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "atLeast");
555 aSpacing.Mode = style::LineSpacingMode::MINIMUM;
557 else // NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact
559 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "exact");
560 aSpacing.Mode = style::LineSpacingMode::FIX;
563 if (pTopContext)
564 pTopContext->Insert(PROP_PARA_LINE_SPACING, uno::Any( aSpacing ));
566 break;
567 case NS_ooxml::LN_CT_Ind_start:
568 case NS_ooxml::LN_CT_Ind_left:
569 if (m_pImpl->GetTopContext())
571 // Word inherits FirstLineIndent property of the numbering, even if ParaLeftMargin is set, Writer does not.
572 // So copy it explicitly, if necessary.
573 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
574 sal_Int32 nIndentAt = m_pImpl->getCurrentNumberingProperty("IndentAt");
576 sal_Int32 nParaLeftMargin = ConversionHelper::convertTwipToMM100(nIntValue);
577 if (nParaLeftMargin != 0 && nIndentAt == nParaLeftMargin)
578 // Avoid direct left margin when it's the same as from the
579 // numbering.
580 break;
582 if (nFirstLineIndent != 0)
583 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::Any(nFirstLineIndent), /*bOverwrite=*/false);
585 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN,
586 uno::Any(nParaLeftMargin));
588 break;
589 case NS_ooxml::LN_CT_Ind_end:
590 case NS_ooxml::LN_CT_Ind_right:
591 if (m_pImpl->GetTopContext())
593 // Word inherits FirstLineIndent/ParaLeftMargin property of the numbering, even if ParaRightMargin is set, Writer does not.
594 // So copy it explicitly, if necessary.
595 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
596 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
598 if (nFirstLineIndent != 0)
599 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::Any(nFirstLineIndent), /*bOverwrite=*/false);
600 if (nParaLeftMargin != 0)
601 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::Any(nParaLeftMargin), /*bOverwrite=*/false);
603 m_pImpl->GetTopContext()->Insert(
604 PROP_PARA_RIGHT_MARGIN, uno::Any( ConversionHelper::convertTwipToMM100(nIntValue ) ));
606 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "right", OUString::number(nIntValue));
607 break;
608 case NS_ooxml::LN_CT_Ind_hanging:
609 if (m_pImpl->GetTopContext())
611 sal_Int32 nValue = ConversionHelper::convertTwipToMM100( nIntValue );
612 m_pImpl->GetTopContext()->Insert(
613 PROP_PARA_FIRST_LINE_INDENT, uno::Any( - nValue ));
615 // See above, need to inherit left margin from list style when first is set.
616 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
617 if (nParaLeftMargin != 0)
618 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::Any(nParaLeftMargin), /*bOverwrite=*/false);
620 break;
621 case NS_ooxml::LN_CT_Ind_firstLine:
622 if (m_pImpl->GetTopContext())
624 sal_Int32 nFirstLineIndent
625 = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
626 sal_Int32 nParaFirstLineIndent = ConversionHelper::convertTwipToMM100(nIntValue);
627 if (nParaFirstLineIndent != 0 && nFirstLineIndent == nParaFirstLineIndent)
628 // Avoid direct first margin when it's the same as from the
629 // numbering.
630 break;
631 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT,
632 uno::Any(nParaFirstLineIndent));
634 break;
635 case NS_ooxml::LN_CT_Ind_rightChars:
636 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "rightChars", OUString::number(nIntValue));
637 break;
639 case NS_ooxml::LN_CT_EastAsianLayout_id:
640 break;
641 case NS_ooxml::LN_CT_EastAsianLayout_combine:
642 if (m_pImpl->GetTopContext())
643 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_IS_ON, uno::Any ( nIntValue != 0 ));
644 break;
645 case NS_ooxml::LN_CT_EastAsianLayout_combineBrackets:
646 if (m_pImpl->GetTopContext())
648 OUString sCombinePrefix = getBracketStringFromEnum(nIntValue);
649 OUString sCombineSuffix = getBracketStringFromEnum(nIntValue, false);
650 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_PREFIX, uno::Any ( sCombinePrefix ));
651 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_SUFFIX, uno::Any ( sCombineSuffix ));
653 break;
654 case NS_ooxml::LN_CT_EastAsianLayout_vert:
655 if (m_pImpl->GetTopContext())
657 sal_Int16 nRotationAngle = (nIntValue ? 900 : 0);
658 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION, uno::Any ( nRotationAngle ));
660 break;
661 case NS_ooxml::LN_CT_EastAsianLayout_vertCompress:
662 if (m_pImpl->GetTopContext())
663 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION_IS_FIT_TO_LINE, uno::Any ( nIntValue != 0 ));
664 break;
666 case NS_ooxml::LN_CT_PageSz_code:
667 break;
668 case NS_ooxml::LN_CT_PageSz_h:
670 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100WithoutLimit(nIntValue);
671 CT_PageSz.h = PaperInfo::sloppyFitPageDimension(nHeight);
673 break;
674 case NS_ooxml::LN_CT_PageSz_orient:
675 CT_PageSz.orient = (nIntValue != NS_ooxml::LN_Value_ST_PageOrientation_portrait);
676 break;
677 case NS_ooxml::LN_CT_PageSz_w:
679 sal_Int32 nWidth = ConversionHelper::convertTwipToMM100WithoutLimit(nIntValue);
680 CT_PageSz.w = PaperInfo::sloppyFitPageDimension(nWidth);
682 break;
684 case NS_ooxml::LN_CT_PageMar_top:
685 m_pImpl->SetPageMarginTwip( PAGE_MAR_TOP, nIntValue );
686 break;
687 case NS_ooxml::LN_CT_PageMar_right:
688 m_pImpl->SetPageMarginTwip( PAGE_MAR_RIGHT, nIntValue );
689 break;
690 case NS_ooxml::LN_CT_PageMar_bottom:
691 m_pImpl->SetPageMarginTwip( PAGE_MAR_BOTTOM, nIntValue );
692 break;
693 case NS_ooxml::LN_CT_PageMar_left:
694 m_pImpl->SetPageMarginTwip( PAGE_MAR_LEFT, nIntValue );
695 break;
696 case NS_ooxml::LN_CT_PageMar_header:
697 m_pImpl->SetPageMarginTwip( PAGE_MAR_HEADER, nIntValue );
698 break;
699 case NS_ooxml::LN_CT_PageMar_footer:
700 m_pImpl->SetPageMarginTwip( PAGE_MAR_FOOTER, nIntValue );
701 break;
702 case NS_ooxml::LN_CT_PageMar_gutter:
703 m_pImpl->SetPageMarginTwip( PAGE_MAR_GUTTER, nIntValue );
704 break;
705 case NS_ooxml::LN_CT_Language_val: //90314
706 case NS_ooxml::LN_CT_Language_eastAsia: //90315
707 case NS_ooxml::LN_CT_Language_bidi: //90316
709 // store decimal symbol associated to the language of the document
710 if ( m_pImpl->IsDocDefaultsImport() && ( nName == NS_ooxml::LN_CT_Language_val ) )
712 LanguageTag aLanguageTag( sStringValue );
713 LocaleDataWrapper aLocaleWrapper( std::move(aLanguageTag) );
714 if ( aLocaleWrapper.getNumDecimalSep() == "," )
715 m_pImpl->SetIsDecimalComma();
718 if (nName == NS_ooxml::LN_CT_Language_eastAsia)
719 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsia", sStringValue);
720 else if (nName == NS_ooxml::LN_CT_Language_val)
721 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", sStringValue);
722 else if (nName == NS_ooxml::LN_CT_Language_bidi)
723 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "bidi", sStringValue);
724 lang::Locale aLocale;
725 if (sStringValue.getLength() <= 3 && sStringValue.getLength() >= 1)
727 // Cheesy Google Docs is known to tag language-only even for
728 // "en" or others that need some region to distinguish language
729 // variants for spell-checker and hyphenation. Obtain our known
730 // fallback to clarify and match. The original value/context is
731 // unknown anyway.
732 LanguageTag aLanguageTag( sStringValue);
733 aLanguageTag.makeFallback();
734 if (aLanguageTag.getLanguage() == sStringValue)
735 aLocale = aLanguageTag.getLocale();
736 else
738 // Do not fallback for an unknown language, which usually
739 // results in "en-US", or any other non-matching case.
740 aLocale = LanguageTag::convertToLocale( sStringValue);
743 else
745 aLocale = LanguageTag::convertToLocale( sStringValue);
747 if (m_pImpl->GetTopContext())
748 m_pImpl->GetTopContext()->Insert(NS_ooxml::LN_CT_Language_val== nName ? PROP_CHAR_LOCALE :
749 NS_ooxml::LN_CT_Language_eastAsia == nName ? PROP_CHAR_LOCALE_ASIAN : PROP_CHAR_LOCALE_COMPLEX,
750 uno::Any( aLocale ) );
752 break;
753 // See SwWW8ImplReader::GetParagraphAutoSpace() on why these are 100 and 280
754 case NS_ooxml::LN_CT_Spacing_beforeAutospacing:
756 sal_Int32 default_spacing = -1;
757 if (nIntValue)
759 m_pImpl->SetParaAutoBefore(true);
761 default_spacing = 100;
762 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
764 // 49 is just the old value that should be removed, once the
765 // root cause in SwTabFrm::MakeAll() is fixed.
766 if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
767 default_spacing = 49;
768 else
769 default_spacing = 280;
771 // required at export (here mainly for StyleSheets) to determine if the setting has changed from grab_bag
772 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(default_spacing)));
774 m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING, uno::Any( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG );
776 break;
777 case NS_ooxml::LN_CT_Spacing_afterAutospacing:
779 sal_Int32 default_spacing = -1;
780 if (nIntValue)
782 default_spacing = 100;
783 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
785 if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
786 default_spacing = 49;
787 else
788 default_spacing = 280;
790 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(default_spacing)));
792 m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING, uno::Any( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG );
794 break;
795 case NS_ooxml::LN_CT_SmartTagRun_uri:
796 m_pImpl->getSmartTagHandler().setURI(val.getString());
797 break;
798 case NS_ooxml::LN_CT_SmartTagRun_element:
799 m_pImpl->getSmartTagHandler().setElement(val.getString());
800 break;
801 case NS_ooxml::LN_CT_Br_type:
802 // Handled in the OOXMLBreakHandler dtor.
803 break;
804 case NS_ooxml::LN_CT_Br_clear:
805 m_pImpl->HandleLineBreakClear(val.getInt());
806 break;
807 case NS_ooxml::LN_CT_Fonts_hint :
808 /* assigns script type to ambiguous characters, values can be:
809 NS_ooxml::LN_Value_ST_Hint_default
810 NS_ooxml::LN_Value_ST_Hint_eastAsia
811 NS_ooxml::LN_Value_ST_Hint_cs
813 //TODO: unsupported?
814 break;
815 case NS_ooxml::LN_CT_TblBorders_right:
816 case NS_ooxml::LN_CT_TblBorders_top:
817 case NS_ooxml::LN_CT_TblBorders_left:
818 case NS_ooxml::LN_CT_TblBorders_bottom:
819 //todo: handle cell mar
820 break;
821 case NS_ooxml::LN_blip: // contains the binary graphic
822 case NS_ooxml::LN_shape:
824 //looks a bit like a hack - and it is. The graphic import is split into the inline_inline part and
825 //afterwards the adding of the binary data.
826 m_pImpl->m_eGraphicImportType = IMPORT_AS_DETECTED_INLINE; // really ???
827 m_pImpl->GetGraphicImport()->attribute(nName, val);
828 m_pImpl->ImportGraphic(val.getProperties());
830 break;
831 case NS_ooxml::LN_Value_math_ST_Jc_centerGroup:
832 case NS_ooxml::LN_Value_math_ST_Jc_center:
833 m_pImpl->appendStarMath(val);
834 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_CENTER));
835 break;
836 case NS_ooxml::LN_Value_math_ST_Jc_left:
837 m_pImpl->appendStarMath(val);
838 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_LEFT));
839 break;
840 case NS_ooxml::LN_Value_math_ST_Jc_right:
841 m_pImpl->appendStarMath(val);
842 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_RIGHT));
843 break;
844 case NS_ooxml::LN_starmath:
845 m_pImpl->appendStarMath(val);
846 break;
847 case NS_ooxml::LN_CT_FramePr_dropCap:
848 case NS_ooxml::LN_CT_FramePr_lines:
849 case NS_ooxml::LN_CT_FramePr_hAnchor:
850 case NS_ooxml::LN_CT_FramePr_vAnchor:
851 case NS_ooxml::LN_CT_FramePr_x:
852 case NS_ooxml::LN_CT_FramePr_xAlign:
853 case NS_ooxml::LN_CT_FramePr_y:
854 case NS_ooxml::LN_CT_FramePr_yAlign:
855 case NS_ooxml::LN_CT_FramePr_hRule:
856 case NS_ooxml::LN_CT_FramePr_w:
857 case NS_ooxml::LN_CT_FramePr_h:
858 case NS_ooxml::LN_CT_FramePr_wrap:
859 case NS_ooxml::LN_CT_FramePr_hSpace:
860 case NS_ooxml::LN_CT_FramePr_vSpace:
862 ParagraphPropertiesPropertyMap* pParaProperties = nullptr;
863 // handle frame properties at styles
864 if( m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET )
865 pParaProperties = dynamic_cast< ParagraphPropertiesPropertyMap*>( m_pImpl->GetTopContextOfType( CONTEXT_STYLESHEET ).get() );
866 else
867 pParaProperties = dynamic_cast< ParagraphPropertiesPropertyMap*>( m_pImpl->GetTopContextOfType( CONTEXT_PARAGRAPH ).get() );
869 if( pParaProperties )
871 switch( nName )
873 case NS_ooxml::LN_CT_FramePr_dropCap:
874 pParaProperties->props().SetDropCap( nIntValue );
875 break;
876 case NS_ooxml::LN_CT_FramePr_lines:
877 pParaProperties->props().SetLines( nIntValue );
878 break;
879 case NS_ooxml::LN_CT_FramePr_hAnchor:
880 switch(nIntValue)
882 case NS_ooxml::LN_Value_doc_ST_HAnchor_text: //relative to column
883 nIntValue = text::RelOrientation::FRAME; break;
884 case NS_ooxml::LN_Value_doc_ST_HAnchor_margin: nIntValue = text::RelOrientation::PAGE_PRINT_AREA; break;
885 case NS_ooxml::LN_Value_doc_ST_HAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
886 default:;
888 pParaProperties->props().SethAnchor( nIntValue );
889 break;
890 case NS_ooxml::LN_CT_FramePr_vAnchor:
891 switch(nIntValue)
893 case NS_ooxml::LN_Value_doc_ST_VAnchor_text: //relative to paragraph
894 nIntValue = text::RelOrientation::FRAME; break;
895 case NS_ooxml::LN_Value_doc_ST_VAnchor_margin:nIntValue = text::RelOrientation::PAGE_PRINT_AREA ; break;
896 case NS_ooxml::LN_Value_doc_ST_VAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
897 default:;
899 pParaProperties->props().SetvAnchor( nIntValue );
900 break;
901 case NS_ooxml::LN_CT_FramePr_x:
902 pParaProperties->props().Setx(
903 ConversionHelper::convertTwipToMM100(nIntValue ));
904 pParaProperties->props().SetxAlign( text::HoriOrientation::NONE );
905 break;
906 case NS_ooxml::LN_CT_FramePr_xAlign:
907 switch( nIntValue )
909 case NS_ooxml::LN_Value_doc_ST_XAlign_center : nIntValue = text::HoriOrientation::CENTER; break;
910 case NS_ooxml::LN_Value_doc_ST_XAlign_right : nIntValue = text::HoriOrientation::RIGHT; break;
911 case NS_ooxml::LN_Value_doc_ST_XAlign_inside : nIntValue = text::HoriOrientation::INSIDE; break;
912 case NS_ooxml::LN_Value_doc_ST_XAlign_outside : nIntValue = text::HoriOrientation::OUTSIDE; break;
913 case NS_ooxml::LN_Value_doc_ST_XAlign_left : nIntValue = text::HoriOrientation::LEFT; break;
914 default: nIntValue = text::HoriOrientation::NONE;
916 pParaProperties->props().SetxAlign( nIntValue );
917 break;
918 case NS_ooxml::LN_CT_FramePr_y:
919 pParaProperties->props().Sety(
920 ConversionHelper::convertTwipToMM100(nIntValue ));
921 pParaProperties->props().SetyAlign( text::VertOrientation::NONE );
922 break;
923 case NS_ooxml::LN_CT_FramePr_yAlign:
924 switch( nIntValue )
926 case NS_ooxml::LN_Value_doc_ST_YAlign_top :
927 case NS_ooxml::LN_Value_doc_ST_YAlign_inside :nIntValue = text::VertOrientation::TOP; break;
928 case NS_ooxml::LN_Value_doc_ST_YAlign_center :nIntValue = text::VertOrientation::CENTER;break;
929 case NS_ooxml::LN_Value_doc_ST_YAlign_bottom :
930 case NS_ooxml::LN_Value_doc_ST_YAlign_outside :nIntValue = text::VertOrientation::BOTTOM;break;
931 case NS_ooxml::LN_Value_doc_ST_YAlign_inline :
933 // HACK: This is for bnc#780851, where a table has one cell that has w:framePr,
934 // which causes that paragraph to be converted to a text frame, and the original
935 // paragraph object no longer exists, which makes table creation fail and furthermore
936 // it would be missing in the table layout anyway. So actually no letting that paragraph
937 // be a text frame "fixes" it. I'm not sure what "inline" is supposed to mean in practice
938 // anyway, so as long as this doesn't cause trouble elsewhere ...
939 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
940 if( pContext )
942 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
943 if (pParaContext)
944 pParaContext->props().SetFrameMode(false);
946 nIntValue = text::VertOrientation::NONE;
947 break;
949 default:
950 nIntValue = text::VertOrientation::NONE;
951 break;
953 pParaProperties->props().SetyAlign( nIntValue );
954 break;
955 case NS_ooxml::LN_CT_FramePr_hRule:
956 switch( nIntValue )
958 case NS_ooxml::LN_Value_doc_ST_HeightRule_exact:
959 nIntValue = text::SizeType::FIX;
960 break;
961 case NS_ooxml::LN_Value_doc_ST_HeightRule_atLeast:
962 nIntValue = text::SizeType::MIN;
963 break;
964 case NS_ooxml::LN_Value_doc_ST_HeightRule_auto:
965 //no break;
966 default:;
967 nIntValue = text::SizeType::VARIABLE;
969 pParaProperties->props().SethRule( nIntValue );
970 break;
971 case NS_ooxml::LN_CT_FramePr_wrap:
973 //should be either LN_Value_doc_ST_Wrap_notBeside or LN_Value_doc_ST_Wrap_around or LN_Value_doc_ST_Wrap_auto
974 OSL_ENSURE( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
975 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_notBeside ||
976 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
977 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none ||
978 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto,
979 "wrap not around, not_Beside, through, none or auto?");
980 if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
981 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto )
982 pParaProperties->props().SetWrap ( text::WrapTextMode_DYNAMIC ) ;
983 else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around)
984 pParaProperties->props().SetWrap(text::WrapTextMode_PARALLEL);
985 else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none)
986 pParaProperties->props().SetWrap ( text::WrapTextMode_THROUGH ) ;
987 else
988 pParaProperties->props().SetWrap ( text::WrapTextMode_NONE ) ;
990 break;
991 case NS_ooxml::LN_CT_FramePr_w:
992 pParaProperties->props().Setw(
993 ConversionHelper::convertTwipToMM100(nIntValue));
994 break;
995 case NS_ooxml::LN_CT_FramePr_h:
996 pParaProperties->props().Seth(
997 ConversionHelper::convertTwipToMM100(nIntValue));
998 break;
999 case NS_ooxml::LN_CT_FramePr_hSpace:
1000 pParaProperties->props().SethSpace(
1001 ConversionHelper::convertTwipToMM100(nIntValue ));
1002 break;
1003 case NS_ooxml::LN_CT_FramePr_vSpace:
1004 pParaProperties->props().SetvSpace(
1005 ConversionHelper::convertTwipToMM100(nIntValue ));
1006 break;
1007 default:;
1011 break;
1012 case NS_ooxml::LN_CT_TrackChange_author:
1013 m_pImpl->SetCurrentRedlineAuthor( sStringValue );
1014 break;
1015 case NS_ooxml::LN_CT_TrackChange_date:
1016 m_pImpl->SetCurrentRedlineDate( sStringValue );
1017 break;
1018 case NS_ooxml::LN_CT_Markup_id:
1019 m_pImpl->SetCurrentRedlineId( nIntValue );
1020 break;
1021 case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart:
1022 m_pImpl->AddAnnotationPosition( true, nIntValue );
1023 break;
1024 case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd:
1025 m_pImpl->AddAnnotationPosition( false, nIntValue );
1026 break;
1027 case NS_ooxml::LN_CT_Comment_initials:
1028 m_pImpl->SetCurrentRedlineInitials(sStringValue);
1029 break;
1030 case NS_ooxml::LN_token:
1031 m_pImpl->SetCurrentRedlineToken( nIntValue );
1032 break;
1033 case NS_ooxml::LN_CT_LineNumber_start:
1034 case NS_ooxml::LN_CT_LineNumber_distance:
1035 case NS_ooxml::LN_CT_LineNumber_countBy:
1036 case NS_ooxml::LN_CT_LineNumber_restart:
1038 //line numbering in Writer is a global document setting
1039 //in Word is a section setting
1040 //if line numbering is switched on anywhere in the document it's set at the global settings
1041 LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
1042 switch( nName )
1044 case NS_ooxml::LN_CT_LineNumber_countBy:
1045 aSettings.nInterval = nIntValue;
1046 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1047 if( pSectionContext )
1048 pSectionContext->SetLnnMod( nIntValue );
1049 break;
1050 case NS_ooxml::LN_CT_LineNumber_start:
1051 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1052 if( pSectionContext )
1053 pSectionContext->SetLnnMin( nIntValue );
1054 break;
1055 case NS_ooxml::LN_CT_LineNumber_distance:
1056 aSettings.nDistance = ConversionHelper::convertTwipToMM100( nIntValue );
1057 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1058 if( pSectionContext )
1059 pSectionContext->SetdxaLnn( nIntValue );
1060 break;
1061 case NS_ooxml::LN_CT_LineNumber_restart:
1062 aSettings.bRestartAtEachPage = nIntValue == NS_ooxml::LN_Value_ST_LineNumberRestart_newPage;
1063 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1064 if( pSectionContext )
1065 pSectionContext->SetLnc( nIntValue );
1066 break;
1067 default:;
1069 m_pImpl->SetLineNumberSettings( aSettings );
1071 break;
1072 case NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows:
1073 m_pImpl->StartCustomFootnote(m_pImpl->GetTopContext());
1074 break;
1075 case NS_ooxml::LN_CT_FtnEdnRef_id:
1076 // footnote or endnote reference id - not needed
1077 break;
1078 case NS_ooxml::LN_CT_DocGrid_linePitch:
1080 //see SwWW8ImplReader::SetDocumentGrid
1081 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1082 if(pSectionContext)
1084 pSectionContext->SetGridLinePitch( ConversionHelper::convertTwipToMM100( nIntValue ) );
1087 break;
1088 case NS_ooxml::LN_CT_DocGrid_charSpace:
1090 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1091 if(pSectionContext)
1093 pSectionContext->SetDxtCharSpace( nIntValue );
1096 break;
1097 case NS_ooxml::LN_CT_DocGrid_type:
1099 if (pSectionContext != nullptr)
1101 switch( nIntValue )
1103 case NS_ooxml::LN_Value_doc_ST_DocGrid_default:
1104 pSectionContext->SetGridType(text::TextGridMode::NONE);
1105 break;
1106 case NS_ooxml::LN_Value_doc_ST_DocGrid_lines:
1107 pSectionContext->SetGridType(text::TextGridMode::LINES);
1108 break;
1109 case NS_ooxml::LN_Value_doc_ST_DocGrid_linesAndChars:
1110 pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
1111 pSectionContext->SetGridSnapToChars( false );
1112 break;
1113 case NS_ooxml::LN_Value_doc_ST_DocGrid_snapToChars:
1114 pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
1115 pSectionContext->SetGridSnapToChars( true );
1116 break;
1117 default :
1118 OSL_FAIL("unknown SwTextGrid value");
1122 break;
1123 case NS_ooxml::LN_CT_SdtBlock_sdtContent:
1124 case NS_ooxml::LN_CT_SdtRun_sdtContent:
1126 m_pImpl->m_pSdtHelper->SetSdtType(nName);
1128 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::unknown)
1130 // Still not determined content type? and it is even not unsupported? Then it is plain text field
1131 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::plainText);
1133 if (nName == NS_ooxml::LN_CT_SdtRun_sdtContent)
1135 if (m_pImpl->GetSdtStarts().empty() && !m_pImpl->m_pSdtHelper->getSdtTexts().isEmpty())
1137 // A non-inline SDT is already started, first convert that to a field and only
1138 // then map the inline SDT to a content control.
1139 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText)
1141 m_pImpl->m_pSdtHelper->createPlainTextControl();
1145 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
1146 if (pContext && m_pImpl->isBreakDeferred(PAGE_BREAK))
1148 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape()
1149 && !m_pImpl->IsInComments())
1151 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
1153 m_pImpl->m_bIsSplitPara = true;
1154 finishParagraph();
1155 lcl_startParagraphGroup();
1157 else // IsFirstRun
1159 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
1161 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
1165 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
1166 m_pImpl->clearDeferredBreaks();
1169 else if (pContext && m_pImpl->isBreakDeferred(COLUMN_BREAK))
1171 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
1173 mbIsSplitPara = true;
1174 m_pImpl->m_bIsSplitPara = true;
1175 finishParagraph();
1176 lcl_startParagraphGroup();
1178 else // IsFirstRun
1180 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
1182 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
1186 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
1187 m_pImpl->clearDeferredBreaks();
1190 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::richText);
1191 m_pImpl->PushSdt();
1192 break;
1194 m_pImpl->SetSdt(true);
1196 break;
1197 case NS_ooxml::LN_CT_SdtBlock_sdtEndContent:
1198 case NS_ooxml::LN_CT_SdtRun_sdtEndContent:
1199 if (nName == NS_ooxml::LN_CT_SdtRun_sdtEndContent)
1201 // Inline SDT.
1202 switch (m_pImpl->m_pSdtHelper->getControlType())
1204 case SdtControlType::richText:
1205 case SdtControlType::plainText:
1206 case SdtControlType::checkBox:
1207 case SdtControlType::dropDown:
1208 case SdtControlType::comboBox:
1209 case SdtControlType::picture:
1210 case SdtControlType::datePicker:
1211 m_pImpl->PopSdt();
1212 break;
1213 default:
1214 break;
1218 m_pImpl->SetSdt(false);
1220 // It's not possible to insert the relevant property to the character context here:
1221 // the previous, already sent character context may be still active, so the property would be lost.
1222 if (m_pImpl->m_pSdtHelper->isOutsideAParagraph())
1223 m_pImpl->setParaSdtEndDeferred(true);
1224 else
1225 m_pImpl->setSdtEndDeferred(true);
1227 switch (m_pImpl->m_pSdtHelper->getControlType())
1229 case SdtControlType::dropDown:
1230 case SdtControlType::comboBox:
1231 m_pImpl->m_pSdtHelper->createDropDownControl();
1232 break;
1233 case SdtControlType::plainText:
1234 m_pImpl->m_pSdtHelper->createPlainTextControl();
1235 break;
1236 case SdtControlType::datePicker:
1237 m_pImpl->m_pSdtHelper->createDateContentControl();
1238 break;
1239 case SdtControlType::unknown:
1240 default:;
1242 break;
1243 case NS_ooxml::LN_CT_SdtListItem_displayText:
1244 m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().push_back(sStringValue);
1245 break;
1246 case NS_ooxml::LN_CT_SdtListItem_value:
1247 m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue);
1248 break;
1249 case NS_ooxml::LN_CT_SdtDate_fullDate:
1250 m_pImpl->m_pSdtHelper->getDate().append(sStringValue);
1251 break;
1252 case NS_ooxml::LN_CT_Background_color:
1253 if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape())
1254 m_pImpl->m_oBackgroundColor = nIntValue;
1255 break;
1256 case NS_ooxml::LN_CT_PageNumber_start:
1257 if (pSectionContext != nullptr && !m_pImpl->IsAltChunk())
1258 pSectionContext->SetPageNumber(nIntValue);
1259 break;
1260 case NS_ooxml::LN_CT_PageNumber_fmt:
1261 if (pSectionContext)
1263 sal_Int16 nNumberType = ConversionHelper::ConvertNumberingType(nIntValue, -1);
1264 if (nNumberType != -1)
1265 pSectionContext->SetPageNumberType(nNumberType);
1267 break;
1268 case NS_ooxml::LN_CT_FtnEdn_type:
1269 // This is the "separator" footnote, ignore its linebreaks/text.
1270 if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator)
1271 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::ON );
1272 else
1273 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
1274 break;
1275 case NS_ooxml::LN_CT_FtnEdn_id:
1277 SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
1278 if ( eSkip == SkipFootnoteSeparator::ON )
1279 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
1280 else if ( eSkip == SkipFootnoteSeparator::SKIPPING )
1281 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
1283 break;
1284 case NS_ooxml::LN_CT_DataBinding_prefixMappings:
1285 m_pImpl->m_pSdtHelper->setDataBindingPrefixMapping(sStringValue);
1286 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_prefixMappings", sStringValue);
1287 break;
1288 case NS_ooxml::LN_CT_DataBinding_xpath:
1289 m_pImpl->m_pSdtHelper->setDataBindingXPath(sStringValue);
1290 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_xpath", sStringValue);
1291 break;
1292 case NS_ooxml::LN_CT_DataBinding_storeItemID:
1293 m_pImpl->m_pSdtHelper->setDataBindingStoreItemID(sStringValue);
1294 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_storeItemID", sStringValue);
1295 break;
1296 case NS_ooxml::LN_CT_SdtPlaceholder_docPart_val:
1297 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtPlaceholder_docPart_val", sStringValue);
1298 m_pImpl->m_pSdtHelper->SetPlaceholderDocPart(sStringValue);
1299 break;
1300 case NS_ooxml::LN_CT_SdtColor_val:
1301 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtColor_val", sStringValue);
1302 m_pImpl->m_pSdtHelper->SetColor(sStringValue);
1303 break;
1304 case NS_ooxml::LN_CT_SdtAppearance_val:
1305 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtAppearance_val", sStringValue);
1306 m_pImpl->m_pSdtHelper->SetAppearance(sStringValue);
1307 break;
1308 case NS_ooxml::LN_CT_SdtText_multiLine:
1309 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtText_multiLine", sStringValue);
1310 break;
1311 case NS_ooxml::LN_CT_PTab_leader:
1312 case NS_ooxml::LN_CT_PTab_relativeTo:
1313 break;
1314 case NS_ooxml::LN_CT_PTab_alignment:
1315 m_pImpl->HandlePTab(nIntValue);
1316 break;
1317 case NS_ooxml::LN_CT_Cnf_lastRowLastColumn:
1318 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowLastColumn", OUString::number(nIntValue));
1319 break;
1320 case NS_ooxml::LN_CT_Cnf_lastRowFirstColumn:
1321 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowFirstColumn", OUString::number(nIntValue));
1322 break;
1323 case NS_ooxml::LN_CT_Cnf_firstRowLastColumn:
1324 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowLastColumn", OUString::number(nIntValue));
1325 break;
1326 case NS_ooxml::LN_CT_Cnf_oddHBand:
1327 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddHBand", OUString::number(nIntValue));
1328 break;
1329 case NS_ooxml::LN_CT_Cnf_firstRowFirstColumn:
1330 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowFirstColumn", OUString::number(nIntValue));
1331 break;
1332 case NS_ooxml::LN_CT_Cnf_evenVBand:
1333 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenVBand", OUString::number(nIntValue));
1334 break;
1335 case NS_ooxml::LN_CT_Cnf_evenHBand:
1336 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenHBand", OUString::number(nIntValue));
1337 break;
1338 case NS_ooxml::LN_CT_Cnf_lastColumn:
1339 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastColumn", OUString::number(nIntValue));
1340 break;
1341 case NS_ooxml::LN_CT_Cnf_firstColumn:
1342 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstColumn", OUString::number(nIntValue));
1343 break;
1344 case NS_ooxml::LN_CT_Cnf_oddVBand:
1345 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddVBand", OUString::number(nIntValue));
1346 break;
1347 case NS_ooxml::LN_CT_Cnf_lastRow:
1348 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRow", OUString::number(nIntValue));
1349 break;
1350 case NS_ooxml::LN_CT_Cnf_firstRow:
1351 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRow", OUString::number(nIntValue));
1352 break;
1353 case NS_ooxml::LN_CT_Cnf_val:
1354 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "val", sStringValue);
1355 break;
1356 case NS_ooxml::LN_CT_DocPartName_val:
1358 m_sGlossaryEntryName = sStringValue;
1359 break;
1361 case NS_ooxml::LN_CT_DocPartGallery_val:
1363 const OUString& sGlossaryEntryGallery = sStringValue;
1364 if(m_pImpl->GetTopContext())
1366 OUString sName = sGlossaryEntryGallery + ":" + m_sGlossaryEntryName;
1367 // Add glossary entry name as a first paragraph in section
1368 m_pImpl->appendTextPortion(sName, m_pImpl->GetTopContext());
1370 break;
1372 case NS_ooxml::LN_CT_PermStart_ed:
1374 m_pImpl->setPermissionRangeEd(sStringValue);
1375 break;
1377 case NS_ooxml::LN_CT_PermStart_edGrp:
1379 m_pImpl->setPermissionRangeEdGrp(sStringValue);
1380 break;
1382 case NS_ooxml::LN_CT_PermStart_id:
1384 m_pImpl->startOrEndPermissionRange(nIntValue);
1385 break;
1387 case NS_ooxml::LN_CT_PermEnd_id:
1389 m_pImpl->startOrEndPermissionRange(nIntValue);
1390 break;
1392 case NS_ooxml::LN_CT_NumFmt_val:
1396 uno::Reference<beans::XPropertySet> xFtnEdnSettings;
1397 if (m_pImpl->IsInFootnoteProperties())
1399 uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(
1400 m_pImpl->GetTextDocument(), uno::UNO_QUERY);
1401 if (xFootnotesSupplier.is())
1402 xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings();
1404 else
1406 uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(
1407 m_pImpl->GetTextDocument(), uno::UNO_QUERY);
1408 if (xEndnotesSupplier.is())
1409 xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings();
1411 if (xFtnEdnSettings.is())
1413 sal_Int16 nNumType = ConversionHelper::ConvertNumberingType(nIntValue);
1414 xFtnEdnSettings->setPropertyValue(getPropertyName(PROP_NUMBERING_TYPE),
1415 uno::Any(nNumType));
1418 catch (const uno::Exception&)
1422 break;
1423 case NS_ooxml::LN_CT_AltChunk:
1425 m_pImpl->HandleAltChunk(sStringValue);
1427 break;
1428 case NS_ooxml::LN_AG_Parids_paraId:
1429 if (ParagraphPropertyMap* pParaContext
1430 = dynamic_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContext().get()))
1432 pParaContext->props().SetParaId(sStringValue);
1434 break;
1435 case NS_ooxml::LN_OfficeArtExtension_Decorative_val:
1436 m_pImpl->GetGraphicImport()->attribute(nName, val);
1437 break;
1438 default:
1439 SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName);
1443 void DomainMapper::lcl_sprm(Sprm & rSprm)
1445 if (!m_pImpl->hasTableManager() || !m_pImpl->getTableManager().sprm(rSprm))
1446 sprmWithProps(rSprm, m_pImpl->GetTopContext());
1449 // In rtl-paragraphs the meaning of left/right are to be exchanged
1450 static bool ExchangeLeftRight(const PropertyMapPtr& rContext, DomainMapper_Impl& rImpl)
1452 bool bExchangeLeftRight = false;
1453 sal_Int32 aAdjust;
1454 uno::Any aPropPara = rImpl.GetAnyProperty(PROP_WRITING_MODE, rContext);
1455 if( (aPropPara >>= aAdjust) && aAdjust == text::WritingMode2::RL_TB )
1456 bExchangeLeftRight = true;
1457 return bExchangeLeftRight;
1460 void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
1462 // These SPRM's are not specific to any section, so it's expected that there is no context yet.
1463 switch (rSprm.getId())
1465 case NS_ooxml::LN_background_background:
1466 return;
1467 default:
1468 break;
1471 OSL_ENSURE(rContext, "PropertyMap has to be valid!");
1472 if(!rContext)
1473 return ;
1475 sal_uInt32 nSprmId = rSprm.getId();
1476 //needed for page properties
1477 SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
1478 Value::Pointer_t pValue = rSprm.getValue();
1479 sal_Int32 nIntValue = pValue->getInt();
1480 const OUString sStringValue = pValue->getString();
1482 switch(nSprmId)
1484 case NS_ooxml::LN_CT_PPrBase_jc:
1486 bool bExchangeLeftRight = !IsRTFImport() && !m_pImpl->IsInComments() && ExchangeLeftRight(rContext, *m_pImpl);
1487 handleParaJustification(nIntValue, rContext, bExchangeLeftRight);
1488 break;
1490 case NS_ooxml::LN_CT_PPrBase_keepLines:
1491 rContext->Insert(PROP_PARA_SPLIT, uno::Any(nIntValue == 0));
1492 break;
1493 case NS_ooxml::LN_CT_PPrBase_keepNext:
1494 rContext->Insert(PROP_PARA_KEEP_TOGETHER, uno::Any( nIntValue != 0 ) );
1495 break;
1496 case NS_ooxml::LN_CT_PPrBase_pageBreakBefore:
1497 rContext->Insert(PROP_BREAK_TYPE, uno::Any(nIntValue ? style::BreakType_PAGE_BEFORE : style::BreakType_NONE), /*bOverwrite=*/bool(nIntValue));
1498 break;
1499 case NS_ooxml::LN_CT_NumPr_ilvl:
1500 if (nIntValue < 0 || 10 <= nIntValue)
1502 SAL_INFO("writerfilter",
1503 "unsupported numbering level " << nIntValue);
1504 break;
1506 if( IsStyleSheetImport() )
1508 //style sheets cannot have a numbering rule attached
1509 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1510 if (pStyleSheetPropertyMap)
1511 pStyleSheetPropertyMap->SetListLevel( static_cast<sal_Int16>(nIntValue) );
1513 // 0-8 are the 9 levels that Microsoft supports. (LO supports 10 levels).
1514 // 9 indicates "no numbering", for which LO has no corresponding concept,
1515 // and so it will be treated as the 10th level.
1516 // finishParagraph() will convert the 9 into "no numbering" for direct formatting.
1517 // (Styles only use this PROP for round-tripping and UI, but cannot trust it for import)
1518 if (!IsStyleSheetImport() || nIntValue != 9)
1519 rContext->Insert(PROP_NUMBERING_LEVEL, uno::Any(static_cast<sal_Int16>(nIntValue)));
1520 break;
1521 case NS_ooxml::LN_CT_NumPr_numId:
1523 //convert the ListTable entry to a NumberingRules property and apply it
1524 ListsManager::Pointer pListTable = m_pImpl->GetListTable();
1525 ListDef::Pointer pList = pListTable->GetList( nIntValue );
1526 if( IsStyleSheetImport() )
1528 //style sheets cannot have a numbering rule attached
1529 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1530 if (pStyleSheetPropertyMap)
1531 pStyleSheetPropertyMap->props().SetListId( nIntValue );
1533 if( pList )
1535 if( !IsStyleSheetImport() )
1537 uno::Any aRules( pList->GetNumberingRules( ) );
1538 rContext->Insert( PROP_NUMBERING_RULES, aRules );
1539 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
1540 if (pContext)
1542 assert(dynamic_cast<ParagraphPropertyMap*>(pContext.get()));
1543 static_cast<ParagraphPropertyMap*>(pContext.get())->props().SetListId(pList->GetId());
1546 // Indentation can came from:
1547 // 1) Paragraph style's numbering's indentation: the current non-style numId has priority over it.
1548 // 2) Numbering's indentation: Writer handles that natively, so it should not be set on rContext.
1549 // 3) Paragraph style's indentation: ditto.
1550 // 4) Direct paragraph formatting: that will came later.
1551 // So no situation where keeping indentation at this point would make sense -> erase.
1552 rContext->Erase(PROP_PARA_FIRST_LINE_INDENT);
1553 rContext->Erase(PROP_PARA_LEFT_MARGIN);
1554 rContext->Erase(PROP_PARA_RIGHT_MARGIN);
1557 else
1559 if( !IsStyleSheetImport() )
1561 // eg. disabled numbering using non-existent numId "0"
1562 rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::Any( OUString() ) );
1563 // disable inheritance of indentation of parent styles
1564 rContext->Insert( PROP_PARA_LEFT_MARGIN, uno::Any( sal_Int32(0) ), /*bOverwrite=*/false);
1565 rContext->Insert( PROP_PARA_FIRST_LINE_INDENT,
1566 uno::Any( sal_Int32(0) ), /*bOverwrite=*/false);
1570 break;
1571 case NS_ooxml::LN_CT_PPrBase_suppressLineNumbers:
1572 rContext->Insert(PROP_PARA_LINE_NUMBER_COUNT, uno::Any( nIntValue == 0 ) );
1573 break;
1574 case NS_ooxml::LN_inTbl:
1575 break;
1576 case NS_ooxml::LN_tblDepth:
1577 //not handled via sprm but via text( 0x07 )
1578 break;
1579 case NS_ooxml::LN_CT_FramePr_w:
1580 break;
1581 case NS_ooxml::LN_CT_FramePr_wrap:
1582 break;
1584 case NS_ooxml::LN_CT_PrBase_pBdr: //paragraph border
1585 resolveSprmProps(*this, rSprm);
1586 break;
1587 case NS_ooxml::LN_CT_PBdr_top:
1588 case NS_ooxml::LN_CT_PBdr_left:
1589 case NS_ooxml::LN_CT_PBdr_bottom:
1590 case NS_ooxml::LN_CT_PBdr_right:
1591 case NS_ooxml::LN_CT_PBdr_between:
1593 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1594 if( pProperties )
1596 auto pBorderHandler = std::make_shared<BorderHandler>( true );
1597 pProperties->resolve(*pBorderHandler);
1598 PropertyIds eBorderId = PropertyIds::INVALID;
1599 PropertyIds eBorderComplexColorId = PropertyIds::INVALID;
1600 PropertyIds eBorderDistId = PropertyIds::INVALID;
1601 switch( nSprmId )
1603 case NS_ooxml::LN_CT_PBdr_top:
1604 eBorderId = PROP_TOP_BORDER;
1605 eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
1606 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
1607 break;
1608 case NS_ooxml::LN_CT_PBdr_left:
1609 eBorderId = PROP_LEFT_BORDER;
1610 eBorderComplexColorId = PROP_BORDER_LEFT_COMPLEX_COLOR;
1611 eBorderDistId = PROP_LEFT_BORDER_DISTANCE;
1612 break;
1613 case NS_ooxml::LN_CT_PBdr_bottom:
1614 eBorderId = PROP_BOTTOM_BORDER;
1615 eBorderComplexColorId = PROP_BORDER_BOTTOM_COMPLEX_COLOR;
1616 eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE;
1617 break;
1618 case NS_ooxml::LN_CT_PBdr_right:
1619 eBorderId = PROP_RIGHT_BORDER;
1620 eBorderComplexColorId = PROP_BORDER_RIGHT_COMPLEX_COLOR;
1621 eBorderDistId = PROP_RIGHT_BORDER_DISTANCE;
1622 break;
1623 case NS_ooxml::LN_CT_PBdr_between:
1624 if (m_pImpl->handlePreviousParagraphBorderInBetween())
1626 // If previous paragraph also had border in between property
1627 // then it is possible to emulate this border as top border
1628 // for current paragraph
1629 eBorderId = PROP_TOP_BORDER;
1630 eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
1631 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
1633 // Since there are borders in between, each paragraph will have own borders. No more joining
1634 rContext->Insert(PROP_PARA_CONNECT_BORDERS, uno::Any(false));
1635 break;
1636 default:;
1639 if (eBorderId != PropertyIds::INVALID)
1641 rContext->Insert(eBorderId, uno::Any(pBorderHandler->getBorderLine()));
1643 if (eBorderComplexColorId != PropertyIds::INVALID)
1645 auto aComplexColor = pBorderHandler->getComplexColor();
1646 auto xComplexColor = model::color::createXComplexColor(aComplexColor);
1647 rContext->Insert(eBorderComplexColorId, uno::Any(xComplexColor));
1649 if (eBorderDistId != PropertyIds::INVALID)
1651 rContext->Insert(eBorderDistId, uno::Any(pBorderHandler->getLineDistance()));
1653 if ( nSprmId == NS_ooxml::LN_CT_PBdr_right )
1655 table::ShadowFormat aFormat;
1656 // Word only allows shadows on visible borders
1657 if ( pBorderHandler->getShadow() && pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE )
1658 aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
1659 rContext->Insert(PROP_PARA_SHADOW_FORMAT, uno::Any(aFormat));
1663 break;
1664 case NS_ooxml::LN_CT_PBdr_bar:
1665 break;
1666 case NS_ooxml::LN_CT_PPrBase_suppressAutoHyphens:
1667 rContext->Insert(PROP_PARA_IS_HYPHENATION, uno::Any( nIntValue == 0 ));
1668 break;
1669 case NS_ooxml::LN_CT_FramePr_h:
1670 break;
1671 case NS_ooxml::LN_CT_PrBase_shd:
1673 //contains fore color, back color and shadow percentage, results in a brush
1674 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1675 if( pProperties )
1677 auto pCellColorHandler = std::make_shared<CellColorHandler>();
1678 pCellColorHandler->setOutputFormat( CellColorHandler::Paragraph );
1679 bool bEnableTempGrabBag = !pCellColorHandler->isInteropGrabBagEnabled();
1680 if( bEnableTempGrabBag )
1681 pCellColorHandler->enableInteropGrabBag( "TempShdPropsGrabBag" );
1683 pProperties->resolve(*pCellColorHandler);
1684 rContext->InsertProps(pCellColorHandler->getProperties().get());
1686 rContext->Insert(PROP_CHAR_THEME_FILL, pCellColorHandler->getInteropGrabBag().Value, true, PARA_GRAB_BAG);
1687 if(bEnableTempGrabBag)
1688 pCellColorHandler->disableInteropGrabBag();
1691 break;
1692 case NS_ooxml::LN_CT_FramePr_vSpace:
1693 break; // sprmPDyaFromText
1694 case NS_ooxml::LN_CT_FramePr_hSpace:
1695 break; // sprmPDxaFromText
1696 case NS_ooxml::LN_CT_FramePr_anchorLock:
1697 break;
1698 case NS_ooxml::LN_CT_PPrBase_widowControl:
1700 uno::Any aVal( uno::Any( sal_Int8(nIntValue ? 2 : 0 )));
1701 rContext->Insert( PROP_PARA_WIDOWS, aVal );
1702 rContext->Insert( PROP_PARA_ORPHANS, aVal );
1704 break; // sprmPFWidowControl
1705 case NS_ooxml::LN_CT_PPrBase_overflowPunct:
1706 rContext->Insert(PROP_PARA_IS_HANGING_PUNCTUATION, uno::Any( nIntValue == 0 ));
1707 break;
1708 case NS_ooxml::LN_CT_PPrBase_topLinePunct:
1709 break;
1710 case NS_ooxml::LN_CT_PPrBase_autoSpaceDE:
1711 break;
1712 case NS_ooxml::LN_CT_PPrBase_autoSpaceDN:
1713 break;
1714 case NS_ooxml::LN_CT_PPrBase_textAlignment:
1716 sal_Int16 nAlignment = 0;
1717 switch (nIntValue)
1719 case NS_ooxml::LN_Value_doc_ST_TextAlignment_top:
1720 nAlignment = 2;
1721 break;
1722 case NS_ooxml::LN_Value_doc_ST_TextAlignment_center:
1723 nAlignment = 3;
1724 break;
1725 case NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline:
1726 nAlignment = 1;
1727 break;
1728 case NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom:
1729 nAlignment = 4;
1730 break;
1731 case NS_ooxml::LN_Value_doc_ST_TextAlignment_auto:
1732 default:
1733 break;
1735 rContext->Insert( PROP_PARA_VERT_ALIGNMENT, uno::Any( nAlignment) );
1737 break;
1738 case NS_ooxml::LN_CT_PPrBase_textDirection:
1740 switch (nIntValue)
1742 case NS_ooxml::LN_Value_ST_TextDirection_tbRl: // ~ vert="eaVert"
1744 m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL);
1745 break;
1747 case NS_ooxml::LN_Value_ST_TextDirection_btLr: // ~ vert="vert270"
1749 m_pImpl->SetFrameDirection(text::WritingMode2::BT_LR);
1750 break;
1752 case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
1754 // East Asian character rotation is not implemented in LO, use ordinary LR_TB instead.
1755 m_pImpl->SetFrameDirection(text::WritingMode2::LR_TB);
1756 break;
1758 case NS_ooxml::LN_Value_ST_TextDirection_tbRlV: // ~ vert="vert"
1760 m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL90);
1761 break;
1763 case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
1764 // default in LO. Do not overwrite RL_TB set by bidi.
1765 break;
1766 case NS_ooxml::LN_Value_ST_TextDirection_tbLrV: // ~ vert="mongolianVert"
1768 m_pImpl->SetFrameDirection(text::WritingMode2::TB_LR);
1769 break;
1771 default:
1772 SAL_WARN("writerfilter", "DomainMapper::sprmWithProps: unhandled textDirection");
1775 break;
1776 case NS_ooxml::LN_CT_PPrBase_outlineLvl:
1778 if (nIntValue < WW_OUTLINE_MIN || nIntValue > WW_OUTLINE_MAX)
1779 break; // invalid value is ignored by MS Word
1781 if( IsStyleSheetImport() )
1783 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1784 if (pStyleSheetPropertyMap)
1785 pStyleSheetPropertyMap->SetOutlineLevel(nIntValue);
1787 else
1789 // convert MS body level (9) to LO body level (0) and equivalent outline levels
1790 sal_Int16 nLvl = nIntValue == WW_OUTLINE_MAX ? 0 : nIntValue + 1;
1791 rContext->Insert(PROP_OUTLINE_LEVEL, uno::Any ( nLvl ));
1794 break;
1795 case NS_ooxml::LN_CT_PPrBase_bidi:
1797 // Four situations to handle:
1798 // 1.) bidi same as previous setting: no adjust change
1799 // 2.) no previous adjust: set appropriate default for this bidi
1800 // 3.) previous adjust and bidi different from previous: swap adjusts
1801 // 4.) previous adjust and no previous bidi: RTL swaps adjust
1803 const sal_Int16 nWritingMode = nIntValue ? text::WritingMode2::RL_TB : text::WritingMode2::LR_TB;
1804 sal_Int16 nParentBidi = -1;
1805 m_pImpl->GetPropertyFromParaStyleSheet(PROP_WRITING_MODE) >>= nParentBidi;
1806 // Paragraph justification reverses its meaning in an RTL context.
1807 // 1. Only make adjustments if the BiDi changes.
1808 if (nParentBidi != nWritingMode && !IsRTFImport() && !m_pImpl->IsInComments())
1810 style::ParagraphAdjust eAdjust = style::ParagraphAdjust(-1);
1811 // 2. no adjust property exists yet
1812 if ( !(m_pImpl->GetAnyProperty(PROP_PARA_ADJUST, rContext) >>= eAdjust) )
1814 // RTL defaults to right adjust
1815 eAdjust = nIntValue ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
1816 rContext->Insert(PROP_PARA_ADJUST, uno::Any( eAdjust ), /*bOverwrite=*/false);
1818 // 3,4. existing adjust: if RTL, then swap. If LTR, but previous was RTL, also swap.
1819 else if ( nIntValue || nParentBidi == sal_Int16(text::WritingMode2::RL_TB) )
1821 if ( eAdjust == style::ParagraphAdjust_RIGHT )
1822 rContext->Insert(PROP_PARA_ADJUST, uno::Any( style::ParagraphAdjust_LEFT ));
1823 else if ( eAdjust == style::ParagraphAdjust_LEFT )
1824 rContext->Insert(PROP_PARA_ADJUST, uno::Any( style::ParagraphAdjust_RIGHT ));
1827 rContext->Insert(PROP_WRITING_MODE, uno::Any( nWritingMode ));
1830 break;
1831 case NS_ooxml::LN_EG_SectPrContents_bidi:
1832 if (pSectionContext != nullptr)
1834 const sal_Int16 writingMode = (nIntValue != 0) ? sal_Int16(text::WritingMode2::RL_TB) : sal_Int16(text::WritingMode2::LR_TB);
1835 pSectionContext->Insert(PROP_WRITING_MODE, uno::Any(writingMode));
1837 break;
1838 case NS_ooxml::LN_EG_SectPrContents_rtlGutter:
1839 if (pSectionContext != nullptr)
1841 bool bRtlGutter = nIntValue != 0;
1842 pSectionContext->Insert(PROP_RTL_GUTTER, uno::Any(bRtlGutter));
1844 break;
1845 case NS_ooxml::LN_EG_RPrBase_highlight:
1847 // MS Word completely ignores character highlighting in character styles.
1848 if ( IsStyleSheetImport() )
1850 const StyleSheetEntryPtr pCurrStyle = GetStyleSheetTable()->GetCurrentEntry();
1851 if ( pCurrStyle && pCurrStyle->m_nStyleTypeCode == STYLE_TYPE_CHAR )
1852 break;
1855 PropertyIds ePropertyId = m_pImpl->IsInComments() ? PROP_CHAR_BACK_COLOR : PROP_CHAR_HIGHLIGHT;
1857 // OOXML import uses an ID
1858 if( IsOOXMLImport() )
1860 sal_Int32 nColor = 0;
1861 if( getColorFromId(nIntValue, nColor) )
1862 rContext->Insert(ePropertyId, uno::Any(nColor));
1864 // RTF import uses the actual color value
1865 else if( IsRTFImport() )
1867 rContext->Insert(ePropertyId, uno::Any(nIntValue));
1870 break;
1871 case NS_ooxml::LN_EG_RPrBase_em:
1872 rContext->Insert(PROP_CHAR_EMPHASIS, uno::Any ( getEmphasisValue (nIntValue)));
1873 break;
1874 case NS_ooxml::LN_EG_RPrBase_emboss:
1875 case NS_ooxml::LN_EG_RPrBase_b:
1876 case NS_ooxml::LN_EG_RPrBase_bCs:
1877 case NS_ooxml::LN_EG_RPrBase_i:
1878 case NS_ooxml::LN_EG_RPrBase_iCs:
1879 case NS_ooxml::LN_EG_RPrBase_strike:
1880 case NS_ooxml::LN_EG_RPrBase_dstrike:
1881 case NS_ooxml::LN_EG_RPrBase_outline:
1882 case NS_ooxml::LN_EG_RPrBase_shadow:
1883 case NS_ooxml::LN_EG_RPrBase_caps:
1884 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1885 case NS_ooxml::LN_EG_RPrBase_vanish:
1886 case NS_ooxml::LN_EG_RPrBase_webHidden:
1888 PropertyIds ePropertyId = PROP_CHAR_WEIGHT; //initialized to prevent warning!
1889 switch( nSprmId )
1891 case NS_ooxml::LN_EG_RPrBase_b:
1892 case NS_ooxml::LN_EG_RPrBase_bCs:
1893 ePropertyId = nSprmId != NS_ooxml::LN_EG_RPrBase_bCs ? PROP_CHAR_WEIGHT : PROP_CHAR_WEIGHT_COMPLEX;
1894 break;
1895 case NS_ooxml::LN_EG_RPrBase_i:
1896 case NS_ooxml::LN_EG_RPrBase_iCs:
1897 ePropertyId = nSprmId == NS_ooxml::LN_EG_RPrBase_i ? PROP_CHAR_POSTURE : PROP_CHAR_POSTURE_COMPLEX;
1898 break;
1899 case NS_ooxml::LN_EG_RPrBase_strike:
1900 case NS_ooxml::LN_EG_RPrBase_dstrike:
1901 ePropertyId = PROP_CHAR_STRIKEOUT;
1902 break;
1903 case NS_ooxml::LN_EG_RPrBase_outline:
1904 ePropertyId = PROP_CHAR_CONTOURED;
1905 break;
1906 case NS_ooxml::LN_EG_RPrBase_shadow:
1907 ePropertyId = PROP_CHAR_SHADOWED;
1908 break;
1909 case NS_ooxml::LN_EG_RPrBase_caps:
1910 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1911 ePropertyId = PROP_CHAR_CASE_MAP;
1912 break;
1913 case NS_ooxml::LN_EG_RPrBase_vanish:
1914 case NS_ooxml::LN_EG_RPrBase_webHidden:
1915 ePropertyId = PROP_CHAR_HIDDEN;
1916 break;
1917 case NS_ooxml::LN_EG_RPrBase_emboss:
1918 ePropertyId = PROP_CHAR_RELIEF;
1919 break;
1921 //expected: 0,1,128,129
1922 if(nIntValue != 128) //inherited from paragraph - ignore
1924 if( nIntValue == 129) //inverted style sheet value
1926 //get value from style sheet and invert it
1927 sal_Int16 nStyleValue = 0;
1928 uno::Any aStyleVal = m_pImpl->GetPropertyFromParaStyleSheet(ePropertyId);
1929 if( !aStyleVal.hasValue() )
1931 nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
1932 4 : 1;
1934 else if(aStyleVal.getValueTypeClass() == uno::TypeClass_FLOAT )
1936 double fDoubleValue = 0;
1937 //only in case of awt::FontWeight
1938 aStyleVal >>= fDoubleValue;
1939 nIntValue = fDoubleValue > 100. ? 0 : 1;
1941 else if((aStyleVal >>= nStyleValue) ||
1942 (nStyleValue = static_cast<sal_Int16>(comphelper::getEnumAsINT32(aStyleVal))) >= 0 )
1944 nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
1945 nStyleValue ? 0 : 4 :
1946 nStyleValue ? 0 : 1;
1948 else
1950 OSL_FAIL( "what type was it");
1954 switch( nSprmId )
1956 case NS_ooxml::LN_EG_RPrBase_b:
1957 case NS_ooxml::LN_EG_RPrBase_bCs:
1959 uno::Any aBold( uno::Any( nIntValue ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL ) );
1961 rContext->Insert(ePropertyId, aBold );
1962 if( nSprmId != NS_ooxml::LN_EG_RPrBase_bCs )
1963 rContext->Insert(PROP_CHAR_WEIGHT_ASIAN, aBold );
1965 if (nSprmId == NS_ooxml::LN_EG_RPrBase_b)
1966 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "b", OUString::number(nIntValue));
1967 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_bCs)
1968 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "bCs", OUString::number(nIntValue));
1970 break;
1971 case NS_ooxml::LN_EG_RPrBase_i:
1972 case NS_ooxml::LN_EG_RPrBase_iCs:
1974 uno::Any aPosture( uno::Any( nIntValue ? awt::FontSlant_ITALIC : awt::FontSlant_NONE ) );
1975 rContext->Insert( ePropertyId, aPosture );
1976 if (nSprmId != NS_ooxml::LN_EG_RPrBase_iCs)
1977 rContext->Insert(PROP_CHAR_POSTURE_ASIAN, aPosture );
1978 if (nSprmId == NS_ooxml::LN_EG_RPrBase_i)
1979 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "i", OUString::number(nIntValue));
1981 break;
1982 case NS_ooxml::LN_EG_RPrBase_strike:
1984 const auto eStrike
1985 = nIntValue ? awt::FontStrikeout::SINGLE : awt::FontStrikeout::NONE;
1986 const bool bOverwrite(nIntValue);
1987 rContext->Insert(ePropertyId, uno::Any(eStrike), bOverwrite);
1989 break;
1990 case NS_ooxml::LN_EG_RPrBase_dstrike:
1992 const auto eStrike
1993 = nIntValue ? awt::FontStrikeout::DOUBLE : awt::FontStrikeout::NONE;
1994 const bool bOverwrite(nIntValue);
1995 rContext->Insert(ePropertyId, uno::Any(eStrike), bOverwrite);
1997 break;
1998 case NS_ooxml::LN_EG_RPrBase_outline:
1999 case NS_ooxml::LN_EG_RPrBase_shadow:
2000 case NS_ooxml::LN_EG_RPrBase_vanish:
2001 case NS_ooxml::LN_EG_RPrBase_webHidden:
2002 rContext->Insert(ePropertyId, uno::Any( nIntValue != 0 ));
2003 break;
2004 case NS_ooxml::LN_EG_RPrBase_smallCaps:
2005 // If smallcaps would be just disabled and another casemap is already inserted, don't do anything.
2006 if (nIntValue || !rContext->isSet(ePropertyId) )
2007 rContext->Insert(ePropertyId, uno::Any( nIntValue ? style::CaseMap::SMALLCAPS : style::CaseMap::NONE));
2008 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "smallCaps", OUString::number(nIntValue));
2009 break;
2010 case NS_ooxml::LN_EG_RPrBase_caps:
2011 rContext->Insert(ePropertyId,
2012 uno::Any( nIntValue ? style::CaseMap::UPPERCASE : style::CaseMap::NONE));
2013 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "caps", OUString::number(nIntValue));
2014 break;
2015 case NS_ooxml::LN_EG_RPrBase_emboss:
2016 rContext->Insert(ePropertyId,
2017 uno::Any( nIntValue ? awt::FontRelief::EMBOSSED : awt::FontRelief::NONE ));
2018 break;
2023 break;
2024 case NS_ooxml::LN_EG_RPrBase_sz:
2025 case NS_ooxml::LN_EG_RPrBase_szCs:
2027 //multiples of half points (12pt == 24)
2028 double fVal = double(nIntValue) / 2.;
2029 uno::Any aVal( fVal );
2030 if( NS_ooxml::LN_EG_RPrBase_szCs == nSprmId )
2032 rContext->Insert( PROP_CHAR_HEIGHT_COMPLEX, aVal );
2034 else
2036 const RubyInfo &aInfo = m_pImpl->GetRubyInfo();
2037 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt && aInfo.nHps > 0 )
2039 fVal = double(aInfo.nHps) / 2.;
2040 aVal <<= fVal;
2042 else if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase && aInfo.nHpsBaseText > 0 )
2044 fVal = double(aInfo.nHpsBaseText) / 2.;
2045 aVal <<= fVal;
2047 //Asian get the same value as Western
2048 rContext->Insert( PROP_CHAR_HEIGHT, aVal );
2049 rContext->Insert( PROP_CHAR_HEIGHT_ASIAN, aVal );
2051 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, (nSprmId == NS_ooxml::LN_EG_RPrBase_sz ? OUString("sz") : OUString("szCs")), OUString::number(nIntValue));
2053 break;
2054 case NS_ooxml::LN_EG_RPrBase_position:
2055 // The spec says 0 is the same as the lack of the value, so don't parse that.
2056 if ( nIntValue )
2058 if (!IsStyleSheetImport() && !IsNumberingImport())
2059 m_pImpl->deferCharacterProperty( nSprmId, uno::Any( nIntValue ));
2060 else if (!m_pImpl->IsDocDefaultsImport())
2062 // For some undocumented reason, MS Word seems to ignore this in docDefaults
2064 const StyleSheetEntryPtr pCurrStyle = GetStyleSheetTable()->GetCurrentEntry();
2065 if (pCurrStyle && pCurrStyle->m_nStyleTypeCode == STYLE_TYPE_PARA && nIntValue < 0)
2067 m_pImpl->deferCharacterProperty(nSprmId, uno::Any(nIntValue));
2068 break;
2071 // DON'T FIXME: Truly calculating this for Character Styles will be tricky,
2072 // because it depends on the final fontsize - regardless of
2073 // where it is set. So at the style level,
2074 // the escapement value would need to be grabbagged.
2075 // At appendText time the final fontsize needs to be determined, and then
2076 // the escapement can be calculated from the grabbag'd half-point value
2077 // and directly applied. Yuck.
2078 // It seems best to just treat charstyle escapement like
2079 // pre-commit e70df84352d3670508a4666c97df44f82c1ce934
2080 // which just assigned default values and ignored the actual/given escapement.
2081 sal_Int16 nEscapement = nIntValue > 0 ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB;
2082 sal_Int8 nProp = DFLT_ESC_PROP;
2083 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( nEscapement ) );
2084 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
2087 break;
2088 case NS_ooxml::LN_EG_RPrBase_spacing:
2090 //Kerning half point values
2091 //TODO: there are two kerning values -
2092 // in ww8par6.cxx NS_sprm::LN_CHpsKern is used as boolean AutoKerning
2093 sal_Int16 nResult = static_cast<sal_Int16>(ConversionHelper::convertTwipToMM100(nIntValue));
2094 if (m_pImpl->IsInComments())
2096 nResult = static_cast<sal_Int16>(nIntValue);
2098 rContext->Insert(PROP_CHAR_CHAR_KERNING, uno::Any(nResult));
2099 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", OUString::number(nIntValue));
2101 break;
2102 case NS_ooxml::LN_EG_RPrBase_kern: // auto kerning is bound to a minimum font size in Word - but not in Writer :-(
2103 rContext->Insert(PROP_CHAR_AUTO_KERNING, uno::Any( nIntValue != 0 ) );
2104 break;
2105 case NS_ooxml::LN_EG_RPrBase_w:
2106 // ST_TextScale must fall between 1% and 600% according to spec, otherwise resets to 100% according to experience
2107 if ((1 <= nIntValue) && (nIntValue <= 600))
2109 rContext->Insert(PROP_CHAR_SCALE_WIDTH,
2110 uno::Any( sal_Int16(nIntValue) ));
2112 else
2114 rContext->Insert(PROP_CHAR_SCALE_WIDTH,
2115 uno::Any( sal_Int16(100) ));
2117 break;
2118 case NS_ooxml::LN_EG_RPrBase_imprint:
2119 // FontRelief: NONE, EMBOSSED, ENGRAVED
2120 rContext->Insert(PROP_CHAR_RELIEF,
2121 uno::Any( nIntValue ? awt::FontRelief::ENGRAVED : awt::FontRelief::NONE ));
2122 break;
2123 case NS_ooxml::LN_EG_RPrBase_effect:
2124 // The file-format has many character animations. We have only
2125 // one, so we use it always. Suboptimal solution though.
2126 if (nIntValue != NS_ooxml::LN_Value_ST_TextEffect_none)
2127 rContext->Insert(PROP_CHAR_FLASH, uno::Any( true ));
2128 else
2129 rContext->Insert(PROP_CHAR_FLASH, uno::Any( false ));
2130 break;
2131 case NS_ooxml::LN_EG_RPrBase_rtl:
2132 break;
2133 case NS_ooxml::LN_EG_RPrBase_shd:
2135 //contains fore color, back color and shadow percentage, results in a brush
2136 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2137 if( pProperties )
2139 auto pCellColorHandler = std::make_shared<CellColorHandler>();
2140 pCellColorHandler->setOutputFormat( CellColorHandler::Character );
2141 pProperties->resolve(*pCellColorHandler);
2142 rContext->InsertProps(pCellColorHandler->getProperties().get());
2143 m_pImpl->GetTopContext()->Insert(PROP_CHAR_SHADING_MARKER, uno::Any(true), true, CHAR_GRAB_BAG );
2145 // EditEng doesn't have a corresponding property for Shading Value, so eliminate it.
2146 if (m_pImpl->IsInComments())
2147 rContext->Erase(PROP_CHAR_SHADING_VALUE);
2149 break;
2151 case NS_ooxml::LN_EG_SectPrContents_type:
2152 /* break type
2153 0 - No break
2154 1 - New Column
2155 2 - New page
2156 3 - Even page
2157 4 - odd page
2159 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2160 if(pSectionContext)
2162 //continuous break only allowed if it is not the only section break
2163 SectionPropertyMap* pLastContext = m_pImpl->GetLastSectionContext();
2164 if ( nIntValue != NS_ooxml::LN_Value_ST_SectionMark_continuous || pLastContext || m_pImpl->GetParaSectpr() )
2165 pSectionContext->SetBreakType( nIntValue );
2167 break;
2168 case NS_ooxml::LN_EG_SectPrContents_titlePg:
2170 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2171 if(pSectionContext)
2172 pSectionContext->SetTitlePage( nIntValue > 0 );//section has title page
2174 break;
2175 case 165:
2177 //page height, rounded to default values, default: 0x3dc0 twip
2178 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100( nIntValue );
2179 rContext->Insert( PROP_HEIGHT, uno::Any( PaperInfo::sloppyFitPageDimension( nHeight ) ) );
2181 break;
2182 case NS_ooxml::LN_EG_SectPrContents_textDirection:
2184 sal_Int16 nDirection = text::WritingMode2::LR_TB;
2185 switch( nIntValue )
2187 // East Asian 270deg rotation in lrTbV is not implemented in LO
2188 case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
2189 case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
2190 nDirection = text::WritingMode2::LR_TB; // =0
2191 break;
2192 case NS_ooxml::LN_Value_ST_TextDirection_tbRl:
2193 nDirection = text::WritingMode2::TB_RL; // =2
2194 break;
2195 // Word does not write btLr in sections, but LO would be able to use it.
2196 case NS_ooxml::LN_Value_ST_TextDirection_btLr:
2197 nDirection = text::WritingMode2::BT_LR; // =5
2198 break;
2199 // Word maps mongolian direction to tbRlV in sections in file save, as of Aug 2022.
2200 // From point of OOXML standard it would be tbLrV. Since tbRlV is currently not
2201 // implemented in LO for text direction in page styles, we follow Word here.
2202 case NS_ooxml::LN_Value_ST_TextDirection_tbRlV:
2203 case NS_ooxml::LN_Value_ST_TextDirection_tbLrV:
2204 nDirection = text::WritingMode2::TB_LR; // =3
2205 break;
2206 default:;
2209 PropertyMap * pTargetContext = rContext.get();
2211 if (pSectionContext)
2213 pTargetContext = pSectionContext;
2216 pTargetContext->Insert(PROP_WRITING_MODE, uno::Any( sal_Int16(nDirection) ) );
2218 break; // sprmSTextFlow
2219 // the following are not part of the official documentation
2220 case NS_ooxml::LN_CT_Tabs_tab:
2221 resolveSprmProps(*this, rSprm);
2222 m_pImpl->IncorporateTabStop(m_pImpl->m_aCurrentTabStop);
2223 m_pImpl->m_aCurrentTabStop = DeletableTabStop();
2224 break;
2225 case NS_ooxml::LN_CT_PPrBase_tabs:
2227 // Initialize tab stop vector from style sheet
2228 // fdo#81033: for RTF, a tab stop is inherited from the style if it
2229 // is also applied to the paragraph directly, and cleared if it is
2230 // not applied to the paragraph directly => don't InitTabStopFromStyle
2231 if ( !IsRTFImport() )
2233 uno::Any aValue = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_TAB_STOPS);
2234 uno::Sequence< style::TabStop > aStyleTabStops;
2235 if(aValue >>= aStyleTabStops)
2237 m_pImpl->InitTabStopFromStyle( aStyleTabStops );
2240 resolveSprmProps(*this, rSprm);
2241 rContext->Insert(PROP_PARA_TAB_STOPS, uno::Any( m_pImpl->GetCurrentTabStopAndClear()));
2243 break;
2245 case NS_ooxml::LN_CT_DocDefaults_pPrDefault:
2246 case NS_ooxml::LN_CT_DocDefaults_rPrDefault:
2247 GetStyleSheetTable()->sprm( rSprm );
2248 break;
2249 case NS_ooxml::LN_EG_RPrBase_bdr:
2251 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2252 if( pProperties )
2254 auto pBorderHandler = std::make_shared<BorderHandler>( true );
2255 pProperties->resolve(*pBorderHandler);
2257 rContext->Insert( PROP_CHAR_TOP_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2258 rContext->Insert( PROP_CHAR_BOTTOM_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2259 rContext->Insert( PROP_CHAR_LEFT_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2260 rContext->Insert( PROP_CHAR_RIGHT_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2262 rContext->Insert( PROP_CHAR_TOP_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2263 rContext->Insert( PROP_CHAR_BOTTOM_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2264 rContext->Insert( PROP_CHAR_LEFT_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2265 rContext->Insert( PROP_CHAR_RIGHT_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2267 auto xComplexColor = model::color::createXComplexColor(pBorderHandler->getComplexColor());
2269 rContext->Insert( PROP_CHAR_BORDER_TOP_COMPLEX_COLOR, uno::Any(xComplexColor));
2270 rContext->Insert( PROP_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, uno::Any(xComplexColor));
2271 rContext->Insert( PROP_CHAR_BORDER_LEFT_COMPLEX_COLOR, uno::Any(xComplexColor));
2272 rContext->Insert( PROP_CHAR_BORDER_RIGHT_COMPLEX_COLOR, uno::Any(xComplexColor));
2274 table::ShadowFormat aFormat;
2275 // Word only allows shadows on visible borders
2276 if ( pBorderHandler->getShadow() && pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE )
2277 aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
2278 rContext->Insert(PROP_CHAR_SHADOW_FORMAT, uno::Any(aFormat));
2281 break;
2282 case NS_ooxml::LN_EG_RPrBase_color:
2284 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2285 if (pProperties)
2287 auto pThemeColorHandler = std::make_shared<ThemeColorHandler>();
2288 pProperties->resolve(*pThemeColorHandler);
2290 uno::Any aThemeColorName(TDefTableHandler::getThemeColorTypeString(pThemeColorHandler->mnIndex));
2291 uno::Any aThemeColorTint(OUString::number(pThemeColorHandler->mnTint, 16));
2292 uno::Any aThemeColorShade(OUString::number(pThemeColorHandler->mnShade, 16));
2294 if (m_pImpl->GetTopContext())
2296 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR, uno::Any(pThemeColorHandler->mnColor));
2298 auto eType = TDefTableHandler::getThemeColorTypeIndex(pThemeColorHandler->mnIndex);
2299 if (eType != model::ThemeColorType::Unknown)
2302 model::ComplexColor aComplexColor;
2303 aComplexColor.setSchemeColor(eType);
2305 auto eUsage = TDefTableHandler::getThemeColorUsage(pThemeColorHandler->mnIndex);
2306 aComplexColor.meThemeColorUsage = eUsage;
2308 if (pThemeColorHandler->mnTint > 0 )
2310 sal_Int16 nTint = sal_Int16((255 - pThemeColorHandler->mnTint) * 10000 / 255);
2311 aComplexColor.addTransformation({model::TransformationType::Tint, nTint});
2313 if (pThemeColorHandler->mnShade > 0)
2315 sal_Int16 nShade = sal_Int16((255 - pThemeColorHandler->mnShade) * 10000 / 255);
2316 aComplexColor.addTransformation({model::TransformationType::Shade, nShade});
2319 auto xComplexColor = model::color::createXComplexColor(aComplexColor);
2320 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMPLEX_COLOR, uno::Any(xComplexColor));
2323 uno::Any aColorAny(msfilter::util::ConvertColorOU(Color(ColorTransparency, pThemeColorHandler->mnColor)));
2324 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_ORIGINAL_COLOR, aColorAny, true, CHAR_GRAB_BAG);
2326 if (pThemeColorHandler->mnIndex >= 0)
2327 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR, aThemeColorName, true, CHAR_GRAB_BAG);
2329 if (pThemeColorHandler->mnTint > 0)
2330 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_TINT, aThemeColorTint, true, CHAR_GRAB_BAG);
2332 if (pThemeColorHandler->mnShade > 0)
2333 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_SHADE, aThemeColorShade, true, CHAR_GRAB_BAG);
2336 if (pThemeColorHandler->mnIndex >= 0)
2338 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeColor", aThemeColorName.get<OUString>());
2339 if (pThemeColorHandler->mnTint > 0)
2340 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeTint", aThemeColorTint.get<OUString>());
2341 if (pThemeColorHandler->mnShade > 0)
2342 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeShade", aThemeColorShade.get<OUString>());
2344 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "color", m_pImpl->m_aSubInteropGrabBag);
2348 break;
2349 case NS_ooxml::LN_CT_PPr_sectPr:
2350 case NS_ooxml::LN_EG_RPrBase_rFonts:
2351 case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
2352 case NS_ooxml::LN_EG_RPrBase_u:
2353 case NS_ooxml::LN_EG_RPrBase_lang:
2354 case NS_ooxml::LN_CT_PPrBase_spacing:
2355 case NS_ooxml::LN_CT_PPrBase_ind:
2356 case NS_ooxml::LN_CT_RPrDefault_rPr:
2357 case NS_ooxml::LN_CT_PPrDefault_pPr:
2358 case NS_ooxml::LN_CT_Style_pPr:
2359 case NS_ooxml::LN_CT_Style_rPr:
2360 case NS_ooxml::LN_CT_PPr_rPr:
2361 case NS_ooxml::LN_CT_PPrBase_numPr:
2363 if (nSprmId == NS_ooxml::LN_CT_PPr_sectPr)
2364 m_pImpl->SetParaSectpr(true);
2365 resolveSprmProps(*this, rSprm);
2366 if (nSprmId == NS_ooxml::LN_CT_PPrBase_spacing)
2367 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", m_pImpl->m_aSubInteropGrabBag);
2368 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_rFonts)
2369 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "rFonts", m_pImpl->m_aSubInteropGrabBag);
2370 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_lang)
2371 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lang", m_pImpl->m_aSubInteropGrabBag);
2372 else if (nSprmId == NS_ooxml::LN_CT_PPrBase_ind)
2373 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ind", m_pImpl->m_aSubInteropGrabBag);
2375 break;
2376 case NS_ooxml::LN_CT_PPrBase_wordWrap:
2377 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "wordWrap", "");
2378 break;
2379 case NS_ooxml::LN_EG_SectPrContents_footnotePr:
2380 case NS_ooxml::LN_EG_SectPrContents_endnotePr:
2381 m_pImpl->SetInFootnoteProperties( NS_ooxml::LN_EG_SectPrContents_footnotePr == nSprmId );
2382 resolveSprmProps(*this, rSprm);
2383 break;
2384 case NS_ooxml::LN_EG_SectPrContents_lnNumType:
2386 resolveSprmProps(*this, rSprm);
2387 LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
2388 m_pImpl->SetLineNumberSettings( aSettings );
2389 //apply settings at XLineNumberingProperties
2392 uno::Reference< text::XLineNumberingProperties > xLineNumberingProperties( m_pImpl->GetTextDocument(), uno::UNO_QUERY_THROW );
2393 uno::Reference< beans::XPropertySet > xLineNumberingPropSet = xLineNumberingProperties->getLineNumberingProperties();
2394 if( aSettings.nInterval == 0 )
2395 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::Any(false) );
2396 else
2398 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::Any(true) );
2399 if( aSettings.nInterval )
2400 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_INTERVAL ), uno::Any(static_cast<sal_Int16>(aSettings.nInterval)) );
2401 if( aSettings.nDistance != -1 )
2402 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::Any(aSettings.nDistance) );
2403 else
2405 // set Auto value (0.5 cm)
2406 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::Any(static_cast<sal_Int32>(500)) );
2407 if( pSectionContext )
2408 pSectionContext->SetdxaLnn( static_cast<sal_Int32>(283) );
2410 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_RESTART_AT_EACH_PAGE ), uno::Any(aSettings.bRestartAtEachPage) );
2413 catch( const uno::Exception& )
2418 break;
2419 case NS_ooxml::LN_CT_PPrBase_framePr:
2420 // Avoid frames if we're inside a structured document tag, would just cause outer tables fail to create.
2421 if (!m_pImpl->GetSdt())
2423 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
2424 if( pContext )
2426 // If there is a deferred page break applied to this framed paragraph,
2427 // create a dummy paragraph without extra properties,
2428 // so that the anchored frame will be on the correct page (similar to shapes).
2429 if (pContext->isSet(PROP_BREAK_TYPE))
2431 pContext->Erase(PROP_BREAK_TYPE);
2433 lcl_startParagraphGroup();
2434 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
2435 lcl_startCharacterGroup();
2436 sal_uInt8 const sBreak[] = { 0xd };
2437 lcl_text(sBreak, 1);
2438 lcl_endCharacterGroup();
2439 lcl_endParagraphGroup();
2442 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
2443 if (pParaContext)
2444 pParaContext->props().SetFrameMode();
2446 if (!IsInHeaderFooter())
2447 m_pImpl->m_bIsActualParagraphFramed = true;
2449 else
2451 //TODO: What about style sheet import of frame properties
2453 m_pImpl->NewFrameDirection();
2454 resolveSprmProps(*this, rSprm);
2456 break;
2457 case NS_ooxml::LN_EG_SectPrContents_pgSz:
2459 PaperInfo aLetter(PAPER_LETTER);
2460 CT_PageSz.w = aLetter.getWidth();
2461 CT_PageSz.h = aLetter.getHeight();
2463 CT_PageSz.orient = false;
2464 resolveSprmProps(*this, rSprm);
2465 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2466 if(pSectionContext)
2468 if (!m_pImpl->IsAltChunk())
2470 pSectionContext->Insert(PROP_HEIGHT, uno::Any(CT_PageSz.h));
2472 pSectionContext->Insert( PROP_IS_LANDSCAPE, uno::Any( CT_PageSz.orient ));
2473 if (!m_pImpl->IsAltChunk())
2475 pSectionContext->Insert(PROP_WIDTH, uno::Any(CT_PageSz.w));
2478 break;
2480 case NS_ooxml::LN_EG_SectPrContents_pgMar:
2481 m_pImpl->InitPageMargins();
2482 resolveSprmProps(*this, rSprm);
2483 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2484 if(pSectionContext)
2486 const PageMar& rPageMar = m_pImpl->GetPageMargins();
2487 pSectionContext->SetTopMargin( rPageMar.top );
2488 pSectionContext->SetRightMargin( rPageMar.right );
2489 pSectionContext->SetBottomMargin( rPageMar.bottom );
2490 pSectionContext->SetLeftMargin( rPageMar.left );
2491 pSectionContext->SetHeaderTop( rPageMar.header );
2492 pSectionContext->SetHeaderBottom( rPageMar.footer );
2493 pSectionContext->SetGutterMargin(rPageMar.gutter);
2495 break;
2497 case NS_ooxml::LN_EG_SectPrContents_cols:
2499 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2500 if( pProperties )
2503 tools::SvRef< SectionColumnHandler > pSectHdl( new SectionColumnHandler );
2504 pProperties->resolve(*pSectHdl);
2505 if(pSectionContext && !m_pImpl->isInIndexContext())
2507 sal_Int16 nColumnCount = pSectHdl->GetNum() == 1 ? 0 : pSectHdl->GetNum();
2508 if( pSectHdl->IsEqualWidth() )
2510 pSectionContext->SetEvenlySpaced( true );
2511 pSectionContext->SetColumnCount( nColumnCount );
2512 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2513 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2515 else if( !pSectHdl->GetColumns().empty() )
2517 pSectionContext->SetEvenlySpaced( false );
2518 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2519 nColumnCount = pSectHdl->GetColumns().size();
2520 pSectionContext->SetColumnCount( nColumnCount == 1 ? 0 : nColumnCount );
2521 std::vector<Column_>::const_iterator tmpIter = pSectHdl->GetColumns().begin();
2522 for (; tmpIter != pSectHdl->GetColumns().end(); ++tmpIter)
2524 pSectionContext->AppendColumnWidth( tmpIter->nWidth );
2525 if ((tmpIter != pSectHdl->GetColumns().end() - 1) || (tmpIter->nSpace > 0))
2526 pSectionContext->AppendColumnSpacing( tmpIter->nSpace );
2528 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2530 else if( nColumnCount )
2532 pSectionContext->SetColumnCount( nColumnCount );
2533 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2534 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2538 else if ( pSectionContext )
2540 FieldContextPtr pContext = m_pImpl->GetTopFieldContext();
2541 uno::Reference< beans::XPropertySet > xTOC = pContext->GetTOC();
2542 if( xTOC.is() )
2544 uno::Reference<text::XTextColumns> xTextColumns;
2545 xTOC->getPropertyValue(getPropertyName( PROP_TEXT_COLUMNS )) >>= xTextColumns;
2546 if (xTextColumns.is())
2548 uno::Reference< beans::XPropertySet > xColumnPropSet( xTextColumns, uno::UNO_QUERY_THROW );
2549 xColumnPropSet->setPropertyValue( getPropertyName( PROP_AUTOMATIC_DISTANCE ), uno::Any( pSectHdl->GetSpace() ));
2550 xTOC->setPropertyValue( getPropertyName( PROP_TEXT_COLUMNS ), uno::Any( xTextColumns ) );
2556 break;
2557 case NS_ooxml::LN_EG_SectPrContents_docGrid:
2558 resolveSprmProps(*this, rSprm);
2559 break;
2560 case NS_ooxml::LN_EG_SectPrContents_pgBorders:
2562 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2563 if( pProperties && pSectionContext )
2565 tools::SvRef< PageBordersHandler > pHandler( new PageBordersHandler );
2566 pProperties->resolve( *pHandler );
2568 // Set the borders to the context and apply them to the styles
2569 pHandler->SetBorders( pSectionContext );
2572 break;
2574 case NS_ooxml::LN_CT_PPrBase_snapToGrid:
2575 if (!IsStyleSheetImport()||!m_pImpl->isInteropGrabBagEnabled())
2577 rContext->Insert( PROP_SNAP_TO_GRID, uno::Any(bool(nIntValue)));
2579 else
2581 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "snapToGrid", OUString::number(nIntValue));
2583 break;
2584 case NS_ooxml::LN_CT_PPrBase_pStyle:
2586 StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable();
2587 const OUString sConvertedStyleName = pStyleTable->ConvertStyleName( sStringValue, true );
2588 m_pImpl->SetCurrentParaStyleName( sConvertedStyleName );
2589 if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION)
2590 m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::Any( sConvertedStyleName ));
2592 break;
2593 case NS_ooxml::LN_EG_RPrBase_rStyle:
2595 OUString sConvertedName( m_pImpl->GetStyleSheetTable()->ConvertStyleName( sStringValue, true ) );
2596 if (m_pImpl->CheckFootnoteStyle() && m_pImpl->GetFootnoteContext())
2597 m_pImpl->SetHasFootnoteStyle(m_pImpl->GetFootnoteContext()->GetFootnoteStyle() == sConvertedName);
2599 // First check if the style exists in the document.
2600 StyleSheetEntryPtr pEntry = m_pImpl->GetStyleSheetTable( )->FindStyleSheetByConvertedStyleName( sConvertedName );
2601 bool bExists = pEntry && ( pEntry->m_nStyleTypeCode == STYLE_TYPE_CHAR );
2602 // Add the property if the style exists, but do not add it elements in TOC:
2603 // they will receive later another style references from TOC
2604 if ( bExists && m_pImpl->GetTopContext() && !m_pImpl->IsInTOC())
2605 m_pImpl->GetTopContext()->Insert( PROP_CHAR_STYLE_NAME, uno::Any( sConvertedName ) );
2607 break;
2608 case NS_ooxml::LN_CT_TblPrBase_tblCellMar: //cell margins
2610 resolveSprmProps(*this, rSprm);//contains LN_CT_TblCellMar_top, LN_CT_TblCellMar_left, LN_CT_TblCellMar_bottom, LN_CT_TblCellMar_right
2612 break;
2613 case NS_ooxml::LN_CT_TblCellMar_top:
2614 case NS_ooxml::LN_CT_TblCellMar_start:
2615 case NS_ooxml::LN_CT_TblCellMar_left:
2616 case NS_ooxml::LN_CT_TblCellMar_bottom:
2617 case NS_ooxml::LN_CT_TblCellMar_end:
2618 case NS_ooxml::LN_CT_TblCellMar_right:
2620 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2621 if( pProperties )
2623 MeasureHandlerPtr pMeasureHandler( new MeasureHandler );
2624 pProperties->resolve(*pMeasureHandler);
2625 sal_Int32 nMeasureValue = pMeasureHandler->getMeasureValue();
2626 PropertyIds eId = META_PROP_CELL_MAR_TOP;
2627 bool rtl = false; // TODO
2628 switch(nSprmId)
2630 case NS_ooxml::LN_CT_TblCellMar_top:
2631 break;
2632 case NS_ooxml::LN_CT_TblCellMar_start:
2633 eId = rtl ? META_PROP_CELL_MAR_RIGHT : META_PROP_CELL_MAR_LEFT;
2634 break;
2635 case NS_ooxml::LN_CT_TblCellMar_left:
2636 eId = META_PROP_CELL_MAR_LEFT;
2637 break;
2638 case NS_ooxml::LN_CT_TblCellMar_bottom:
2639 eId = META_PROP_CELL_MAR_BOTTOM;
2640 break;
2641 case NS_ooxml::LN_CT_TblCellMar_end:
2642 eId = rtl ? META_PROP_CELL_MAR_LEFT : META_PROP_CELL_MAR_RIGHT;
2643 break;
2644 case NS_ooxml::LN_CT_TblCellMar_right:
2645 eId = META_PROP_CELL_MAR_RIGHT;
2646 break;
2647 default:;
2649 rContext->Insert( eId, uno::Any(nMeasureValue), false);
2652 break;
2653 case NS_ooxml::LN_EG_RPrBase_noProof: // no grammar and spell checking, unsupported
2654 break;
2655 case NS_ooxml::LN_anchor_anchor: // at_character drawing
2656 case NS_ooxml::LN_inline_inline: // as_character drawing
2658 if ( m_pImpl->IsDiscardHeaderFooter() )
2659 break;
2660 //tdf112342: Break before images as well, if there are page break
2661 if (m_pImpl->isBreakDeferred(BreakType::PAGE_BREAK)
2662 && nSprmId == NS_ooxml::LN_inline_inline && !m_pImpl->IsInShape())
2664 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
2666 m_pImpl->m_bIsSplitPara = true;
2667 finishParagraph();
2668 lcl_startParagraphGroup();
2670 else
2672 m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)
2673 ->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
2674 m_pImpl->clearDeferredBreak(PAGE_BREAK);
2678 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2679 if( pProperties )
2681 m_pImpl->m_eGraphicImportType =
2682 (NS_ooxml::LN_anchor_anchor ==
2683 sal::static_int_cast<Id>(nSprmId)) ?
2684 IMPORT_AS_DETECTED_ANCHOR :
2685 IMPORT_AS_DETECTED_INLINE;
2686 GraphicImportPtr pGraphicImport = m_pImpl->GetGraphicImport();
2687 pProperties->resolve(*pGraphicImport);
2688 m_pImpl->ImportGraphic(pProperties);
2689 if( !pGraphicImport->IsGraphic() )
2691 m_pImpl->ResetGraphicImport();
2692 // todo: It's a shape, now start shape import
2696 break;
2697 case NS_ooxml::LN_EG_RPrBase_vertAlign:
2699 sal_Int16 nEscapement = 0;
2700 sal_Int8 nProp = DFLT_ESC_PROP;
2701 if ( sStringValue == "superscript" )
2702 nEscapement = DFLT_ESC_AUTO_SUPER;
2703 else if ( sStringValue == "subscript" )
2704 nEscapement = DFLT_ESC_AUTO_SUB;
2705 else
2706 nProp = 100;
2708 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( nEscapement ) );
2709 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
2711 break;
2712 case NS_ooxml::LN_CT_FtnProps_pos:
2713 //footnotes in word can be at page end or beneath text - writer supports only the first
2714 //endnotes in word can be at section end or document end - writer supports only the latter
2715 // -> so this property can be ignored
2716 break;
2717 case NS_ooxml::LN_CT_FtnProps_numFmt:
2718 case NS_ooxml::LN_CT_EdnProps_numFmt:
2720 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2721 if (pProperties)
2723 pProperties->resolve(*this);
2726 break;
2727 case NS_ooxml::LN_EG_FtnEdnNumProps_numStart:
2728 case NS_ooxml::LN_EG_FtnEdnNumProps_numRestart:
2732 uno::Reference< beans::XPropertySet > xFtnEdnSettings;
2733 if( m_pImpl->IsInFootnoteProperties() )
2735 uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2736 if (xFootnotesSupplier.is())
2737 xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings();
2739 else
2741 uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2742 if (xEndnotesSupplier.is())
2743 xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings();
2745 if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId && xFtnEdnSettings.is())
2747 xFtnEdnSettings->setPropertyValue(
2748 getPropertyName( PROP_START_AT),
2749 uno::Any( sal_Int16( nIntValue - 1 )));
2751 else if( NS_ooxml::LN_EG_FtnEdnNumProps_numRestart == nSprmId && xFtnEdnSettings.is())
2753 sal_Int16 nFootnoteCounting = 0;
2754 switch (nIntValue)
2756 case NS_ooxml::LN_Value_ST_RestartNumber_continuous: nFootnoteCounting = text::FootnoteNumbering::PER_DOCUMENT; break;
2757 case NS_ooxml::LN_Value_ST_RestartNumber_eachPage: nFootnoteCounting = text::FootnoteNumbering::PER_PAGE; break;
2758 case NS_ooxml::LN_Value_ST_RestartNumber_eachSect: nFootnoteCounting = text::FootnoteNumbering::PER_CHAPTER; break;
2759 default: break;
2761 xFtnEdnSettings->setPropertyValue(
2762 getPropertyName( PROP_FOOTNOTE_COUNTING ),
2763 uno::Any( nFootnoteCounting ));
2765 else if (xFtnEdnSettings.is())
2767 sal_Int16 nNumType = ConversionHelper::ConvertNumberingType( nIntValue );
2768 xFtnEdnSettings->setPropertyValue(
2769 getPropertyName( PROP_NUMBERING_TYPE),
2770 uno::Any( nNumType ));
2773 catch( const uno::Exception& )
2777 break;
2778 case NS_ooxml::LN_EG_RangeMarkupElements_moveFromRangeStart:
2779 m_pImpl->SetMoveBookmark(/*bIsFrom=*/true);
2780 if (m_pImpl->hasTableManager())
2781 m_pImpl->getTableManager().setMoved( getPropertyName(PROP_TABLE_ROW_DELETE) );
2782 break;
2783 case NS_ooxml::LN_EG_RangeMarkupElements_moveToRangeStart:
2784 m_pImpl->SetMoveBookmark(/*bIsFrom=*/false);
2785 if (m_pImpl->hasTableManager())
2786 m_pImpl->getTableManager().setMoved( getPropertyName(PROP_TABLE_ROW_INSERT) );
2787 break;
2788 case NS_ooxml::LN_EG_RangeMarkupElements_moveFromRangeEnd:
2789 case NS_ooxml::LN_EG_RangeMarkupElements_moveToRangeEnd:
2790 if (m_pImpl->hasTableManager())
2791 m_pImpl->getTableManager().setMoved( OUString() );
2792 break;
2793 case NS_ooxml::LN_CT_ParaRPr_moveFrom:
2794 case NS_ooxml::LN_CT_ParaRPr_moveTo:
2795 m_pImpl->StartParaMarkerMove( );
2796 break;
2797 case NS_ooxml::LN_paratrackchange:
2798 m_pImpl->StartParaMarkerChange( );
2799 [[fallthrough]];
2800 case NS_ooxml::LN_CT_PPr_pPrChange:
2801 case NS_ooxml::LN_CT_ParaRPr_rPrChange:
2802 case NS_ooxml::LN_trackchange:
2803 case NS_ooxml::LN_EG_RPrContent_rPrChange:
2804 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeStart:
2805 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeEnd:
2806 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeStart:
2807 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeEnd:
2808 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeStart:
2809 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeEnd:
2811 HandleRedline( rSprm );
2813 break;
2814 case NS_ooxml::LN_endtrackchange:
2815 m_pImpl->RemoveTopRedline();
2816 break;
2817 case NS_ooxml::LN_CT_RPrChange_rPr:
2819 // Push all the current 'Character' properties to the stack, so that we don't store them
2820 // as 'tracked changes' by mistake
2821 m_pImpl->PushProperties(CONTEXT_CHARACTER);
2823 // Resolve all the properties that are under the 'rPrChange'->'rPr' XML node
2824 resolveSprmProps(*this, rSprm );
2826 // Get all the properties that were processed in the 'rPrChange'->'rPr' XML node
2827 uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2829 // Pop back out the character properties that were on the run
2830 m_pImpl->PopProperties(CONTEXT_CHARACTER);
2832 // Store these properties in the current redline object (do it after the PopProperties() above, since
2833 // otherwise it'd be stored in the content dropped there).
2834 m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2836 break;
2837 case NS_ooxml::LN_CT_PPrChange_pPr:
2839 // Push all the current 'Paragraph' properties to the stack, so that we don't store them
2840 // as 'tracked changes' by mistake
2841 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2843 // Resolve all the properties that are under the 'pPrChange'->'pPr' XML node
2844 resolveSprmProps(*this, rSprm );
2846 // Get all the properties that were processed in the 'pPrChange'->'pPr' XML node
2847 uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2849 // Pop back out the character properties that were on the run
2850 m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
2852 // Store these properties in the current redline object (do it after the PopProperties() above, since
2853 // otherwise it'd be stored in the content dropped there).
2854 m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2856 break;
2857 case NS_ooxml::LN_object:
2859 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2860 if( pProperties )
2862 auto pOLEHandler = std::make_shared<OLEHandler>(*this);
2863 pProperties->resolve(*pOLEHandler);
2864 if ( pOLEHandler->isOLEObject( ) )
2866 OUString sStreamName = pOLEHandler->copyOLEOStream( m_pImpl->GetTextDocument() );
2867 if( !sStreamName.isEmpty() )
2869 m_pImpl->appendOLE( sStreamName, pOLEHandler );
2874 break;
2875 case NS_ooxml::LN_EG_HdrFtrReferences_headerReference: // header reference - not needed
2876 case NS_ooxml::LN_EG_HdrFtrReferences_footerReference: // footer reference - not needed
2877 break;
2878 case NS_ooxml::LN_EG_RPrBase_snapToGrid: // "Use document grid settings for inter-paragraph spacing"
2879 break;
2880 case NS_ooxml::LN_CT_PPrBase_contextualSpacing:
2881 rContext->Insert(PROP_PARA_CONTEXT_MARGIN, uno::Any( nIntValue != 0 ));
2882 break;
2883 case NS_ooxml::LN_CT_PPrBase_mirrorIndents: // mirrorIndents
2884 rContext->Insert(PROP_MIRROR_INDENTS, uno::Any( nIntValue != 0 ), true, PARA_GRAB_BAG);
2885 break;
2886 case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection
2888 if( pSectionContext )
2889 pSectionContext->Insert( PROP_IS_PROTECTED, uno::Any( bool(nIntValue) ) );
2891 break;
2892 case NS_ooxml::LN_EG_SectPrContents_vAlign:
2894 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2895 if( pSectionContext )
2897 drawing::TextVerticalAdjust nVA = drawing::TextVerticalAdjust_TOP;
2898 switch( nIntValue )
2900 case NS_ooxml::LN_Value_ST_VerticalJc_center: //92367
2901 nVA = drawing::TextVerticalAdjust_CENTER;
2902 break;
2903 case NS_ooxml::LN_Value_ST_VerticalJc_both: //92368 - justify
2904 nVA = drawing::TextVerticalAdjust_BLOCK;
2905 break;
2906 case NS_ooxml::LN_Value_ST_VerticalJc_bottom: //92369
2907 nVA = drawing::TextVerticalAdjust_BOTTOM;
2908 break;
2909 default:
2910 break;
2912 pSectionContext->Insert( PROP_TEXT_VERTICAL_ADJUST, uno::Any( nVA ), true, PARA_GRAB_BAG );
2915 break;
2916 case NS_ooxml::LN_EG_RPrBase_fitText:
2917 break;
2918 case NS_ooxml::LN_ffdata:
2920 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2921 if (pProperties)
2923 FFDataHandler::Pointer_t pFFDataHandler(new FFDataHandler());
2925 pProperties->resolve(*pFFDataHandler);
2926 m_pImpl->SetFieldFFData(pFFDataHandler);
2929 break;
2930 case NS_ooxml::LN_CT_SdtPr_comboBox:
2932 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::comboBox);
2933 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2934 if (pProperties)
2935 pProperties->resolve(*this);
2937 break;
2938 case NS_ooxml::LN_CT_SdtPr_dropDownList:
2940 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::dropDown);
2941 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2942 if (pProperties)
2943 pProperties->resolve(*this);
2945 break;
2946 case NS_ooxml::LN_CT_SdtDropDownList_listItem:
2948 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2950 size_t nDropDownDisplayTexts = m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().size();
2951 size_t nDropDownItems = m_pImpl->m_pSdtHelper->getDropDownItems().size();
2953 if (pProperties)
2954 pProperties->resolve(*this);
2956 if (m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().size() != nDropDownDisplayTexts + 1)
2958 // w:displayText="..." is optional, add empty value if it was not provided.
2959 m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().push_back(OUString());
2961 if (m_pImpl->m_pSdtHelper->getDropDownItems().size() != nDropDownItems + 1)
2963 // w:value="..." is optional, add empty value if it was not provided.
2964 m_pImpl->m_pSdtHelper->getDropDownItems().push_back(OUString());
2967 break;
2968 case NS_ooxml::LN_CT_SdtPr_placeholder:
2970 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2971 if (pProperties)
2972 pProperties->resolve(*this);
2974 break;
2975 break;
2976 case NS_ooxml::LN_CT_SdtPr_date:
2978 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::datePicker);
2979 resolveSprmProps(*this, rSprm);
2980 m_pImpl->m_pSdtHelper->setDateFieldStartRange(GetCurrentTextRange()->getEnd());
2982 break;
2983 case NS_ooxml::LN_CT_SdtDate_dateFormat:
2985 m_pImpl->m_pSdtHelper->getDateFormat().append(sStringValue);
2987 break;
2988 case NS_ooxml::LN_CT_SdtDate_storeMappedDataAs:
2991 break;
2992 case NS_ooxml::LN_CT_SdtDate_calendar:
2995 break;
2996 case NS_ooxml::LN_CT_SdtDate_lid:
2998 m_pImpl->m_pSdtHelper->getLocale().append(sStringValue);
3000 break;
3001 case NS_ooxml::LN_CT_SdtPr_text:
3003 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::plainText);
3004 if (m_pImpl->m_pSdtHelper->GetSdtType() == NS_ooxml::LN_CT_SdtRun_sdtContent)
3006 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3007 break;
3009 enableInteropGrabBag("ooxml:CT_SdtPr_text");
3010 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3011 if (pProperties)
3012 pProperties->resolve(*this);
3013 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
3014 m_pImpl->disableInteropGrabBag();
3016 break;
3017 case NS_ooxml::LN_CT_SdtPr_dataBinding:
3018 case NS_ooxml::LN_CT_SdtPr_equation:
3019 case NS_ooxml::LN_CT_SdtPr_checkbox:
3020 case NS_ooxml::LN_CT_SdtPr_docPartObj:
3021 case NS_ooxml::LN_CT_SdtPr_docPartList:
3022 case NS_ooxml::LN_CT_SdtPr_picture:
3023 case NS_ooxml::LN_CT_SdtPr_citation:
3024 case NS_ooxml::LN_CT_SdtPr_group:
3025 case NS_ooxml::LN_CT_SdtPr_id:
3026 case NS_ooxml::LN_CT_SdtPr_alias:
3027 case NS_ooxml::LN_CT_SdtPlaceholder_docPart:
3028 case NS_ooxml::LN_CT_SdtPr_showingPlcHdr:
3029 case NS_ooxml::LN_CT_SdtPr_color:
3030 case NS_ooxml::LN_CT_SdtPr_appearance:
3031 case NS_ooxml::LN_CT_SdtPr_tag:
3032 case NS_ooxml::LN_CT_SdtPr_tabIndex:
3033 case NS_ooxml::LN_CT_SdtPr_lock:
3035 if (!m_pImpl->GetSdtStarts().empty())
3037 if (nSprmId == NS_ooxml::LN_CT_SdtPr_showingPlcHdr)
3039 if (nIntValue)
3040 m_pImpl->m_pSdtHelper->SetShowingPlcHdr();
3043 if (nSprmId == NS_ooxml::LN_CT_SdtPr_color)
3045 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3046 if (pProperties)
3048 pProperties->resolve(*this);
3050 break;
3053 if (nSprmId == NS_ooxml::LN_CT_SdtPr_appearance)
3055 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3056 if (pProperties)
3058 pProperties->resolve(*this);
3060 break;
3063 if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias)
3065 m_pImpl->m_pSdtHelper->SetAlias(sStringValue);
3066 break;
3069 if (nSprmId == NS_ooxml::LN_CT_SdtPr_tag)
3071 m_pImpl->m_pSdtHelper->SetTag(sStringValue);
3072 break;
3075 if (nSprmId == NS_ooxml::LN_CT_SdtPr_id)
3077 m_pImpl->m_pSdtHelper->SetId(nIntValue);
3078 break;
3081 if (nSprmId == NS_ooxml::LN_CT_SdtPr_tabIndex)
3083 m_pImpl->m_pSdtHelper->SetTabIndex(nIntValue);
3084 break;
3087 if (nSprmId == NS_ooxml::LN_CT_SdtPr_lock)
3089 m_pImpl->m_pSdtHelper->SetLock(sStringValue);
3090 break;
3093 if (nSprmId == NS_ooxml::LN_CT_SdtPr_checkbox)
3095 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::checkBox);
3096 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3097 if (pProperties)
3099 pProperties->resolve(*this);
3101 break;
3103 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_picture)
3105 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::picture);
3106 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3107 if (pProperties)
3109 pProperties->resolve(*this);
3111 break;
3113 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_date)
3115 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::datePicker);
3116 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3117 if (pProperties)
3119 pProperties->resolve(*this);
3121 break;
3125 // this is an unsupported SDT property, create a grab bag for it
3126 OUString sName;
3127 switch (nSprmId)
3129 case NS_ooxml::LN_CT_SdtPr_dataBinding: sName = "ooxml:CT_SdtPr_dataBinding"; break;
3130 case NS_ooxml::LN_CT_SdtPr_equation: sName = "ooxml:CT_SdtPr_equation"; break;
3131 case NS_ooxml::LN_CT_SdtPr_checkbox: sName = "ooxml:CT_SdtPr_checkbox"; break;
3132 case NS_ooxml::LN_CT_SdtPr_docPartObj: sName = "ooxml:CT_SdtPr_docPartObj"; break;
3133 case NS_ooxml::LN_CT_SdtPr_docPartList: sName = "ooxml:CT_SdtPr_docPartList"; break;
3134 case NS_ooxml::LN_CT_SdtPr_picture: sName = "ooxml:CT_SdtPr_picture"; break;
3135 case NS_ooxml::LN_CT_SdtPr_citation: sName = "ooxml:CT_SdtPr_citation"; break;
3136 case NS_ooxml::LN_CT_SdtPr_group: sName = "ooxml:CT_SdtPr_group"; break;
3137 case NS_ooxml::LN_CT_SdtPr_id: sName = "ooxml:CT_SdtPr_id"; break;
3138 case NS_ooxml::LN_CT_SdtPr_alias: sName = "ooxml:CT_SdtPr_alias"; break;
3139 case NS_ooxml::LN_CT_SdtPr_tag: sName = "ooxml:CT_SdtPr_tag"; break;
3140 case NS_ooxml::LN_CT_SdtPr_tabIndex: sName = "ooxml:CT_SdtPr_tabIndex"; break;
3141 case NS_ooxml::LN_CT_SdtPr_lock: sName = "ooxml:CT_SdtPr_lock"; break;
3142 case NS_ooxml::LN_CT_SdtPlaceholder_docPart: sName = "ooxml:CT_SdtPlaceholder_docPart"; break;
3143 case NS_ooxml::LN_CT_SdtPr_showingPlcHdr: sName = "ooxml:CT_SdtPr_showingPlcHdr"; break;
3144 case NS_ooxml::LN_CT_SdtPr_color: sName = "ooxml:CT_SdtPr_color"; break;
3145 case NS_ooxml::LN_CT_SdtPr_appearance: sName = "ooxml:CT_SdtPr_appearance"; break;
3146 default: assert(false);
3148 if (
3149 nSprmId == NS_ooxml::LN_CT_SdtPr_checkbox ||
3150 nSprmId == NS_ooxml::LN_CT_SdtPr_docPartObj ||
3151 nSprmId == NS_ooxml::LN_CT_SdtPr_docPartList ||
3152 nSprmId == NS_ooxml::LN_CT_SdtPr_picture ||
3153 nSprmId == NS_ooxml::LN_CT_SdtPr_citation)
3155 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::unsupported);
3157 enableInteropGrabBag(sName);
3159 // process subitems
3160 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3161 if (pProperties)
3162 pProperties->resolve(*this);
3164 if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias || nSprmId == NS_ooxml::LN_CT_SdtPr_tag
3165 || nSprmId == NS_ooxml::LN_CT_SdtPr_lock)
3167 // Grabbag string values
3168 beans::PropertyValue aValue;
3169 aValue.Name = sName;
3170 aValue.Value <<= sStringValue;
3171 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3173 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_showingPlcHdr)
3175 // Grabbag boolean values
3176 beans::PropertyValue aValue;
3177 aValue.Name = sName;
3178 aValue.Value <<= bool(nIntValue);
3179 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3181 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_id || nSprmId == NS_ooxml::LN_CT_SdtPr_tabIndex)
3183 // Grabbag integer values
3184 beans::PropertyValue aValue;
3185 aValue.Name = sName;
3186 aValue.Value <<= nIntValue;
3187 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3189 else
3190 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
3191 m_pImpl->m_pSdtHelper->setOutsideAParagraph(m_pImpl->IsOutsideAParagraph());
3192 m_pImpl->disableInteropGrabBag();
3194 break;
3195 case NS_ooxml::LN_CT_SdtCheckbox_checked:
3196 if (!m_pImpl->GetSdtStarts().empty())
3198 // nIntValue is not just 0 or 1, because we're in the w14 namespace's ST_OnOff.
3199 if (nIntValue == NS_ooxml::LN_ST_OnOff_true || nIntValue == NS_ooxml::LN_ST_OnOff_1)
3201 m_pImpl->m_pSdtHelper->SetChecked();
3204 else
3206 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checked",
3207 TextEffectsHandler::getOnOffString(nIntValue));
3209 break;
3210 case NS_ooxml::LN_CT_SdtCheckbox_checkedState:
3211 if (!m_pImpl->GetSdtStarts().empty())
3213 m_pImpl->m_pSdtHelper->SetCheckedState(OUString(sal_Unicode(sStringValue.toInt32(16))));
3215 else
3217 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checkedState",
3218 sStringValue);
3220 break;
3221 case NS_ooxml::LN_CT_SdtCheckbox_uncheckedState:
3222 if (!m_pImpl->GetSdtStarts().empty())
3224 m_pImpl->m_pSdtHelper->SetUncheckedState(
3225 OUString(sal_Unicode(sStringValue.toInt32(16))));
3227 else
3229 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag,
3230 "ooxml:CT_SdtCheckbox_uncheckedState", sStringValue);
3232 break;
3233 case NS_ooxml::LN_CT_SdtDocPart_docPartGallery:
3234 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartGallery", sStringValue);
3235 break;
3236 case NS_ooxml::LN_CT_SdtDocPart_docPartCategory:
3237 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartCategory", sStringValue);
3238 break;
3239 case NS_ooxml::LN_CT_SdtDocPart_docPartUnique:
3240 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartUnique", sStringValue);
3241 break;
3242 case NS_ooxml::LN_EG_SectPrContents_pgNumType:
3244 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3245 if( pProperties )
3247 pProperties->resolve(*this);
3250 break;
3251 case NS_ooxml::LN_tblStart:
3254 * Hack for Importing Section Properties
3255 * LO is not able to import section properties if first element in the
3256 * section is a table. So in case first element is a table add a dummy para
3257 * and remove it again when lcl_endSectionGroup is called
3259 if(m_pImpl->m_nTableDepth == 0 && m_pImpl->GetIsFirstParagraphInSection()
3260 && !m_pImpl->GetIsDummyParaAddedForTableInSection() && !m_pImpl->GetIsTextFrameInserted()
3261 && !m_pImpl->GetIsPreviousParagraphFramed() && !IsInHeaderFooter())
3263 m_pImpl->AddDummyParaForTableInSection();
3266 // if first paragraph style in table has break-before-page, transfer that setting to the table itself.
3267 if( m_pImpl->m_nTableDepth == 0 )
3269 const uno::Any aBreakType(style::BreakType_PAGE_BEFORE);
3270 const PropertyMapPtr pParagraphProps = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3271 if( pParagraphProps && pParagraphProps->isSet(PROP_PARA_STYLE_NAME) )
3273 StyleSheetEntryPtr pStyle;
3274 OUString sStyleName;
3275 pParagraphProps->getProperty(PROP_PARA_STYLE_NAME)->second >>= sStyleName;
3276 if( !sStyleName.isEmpty() && GetStyleSheetTable() )
3277 pStyle = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( sStyleName );
3279 if( pStyle && pStyle->m_pProperties
3280 && pStyle->m_pProperties->isSet(PROP_BREAK_TYPE)
3281 && pStyle->m_pProperties->getProperty(PROP_BREAK_TYPE)->second == aBreakType )
3283 pParagraphProps->Insert(PROP_BREAK_TYPE, aBreakType);
3288 m_pImpl->m_nTableDepth++;
3290 break;
3291 case NS_ooxml::LN_tblEnd:
3292 m_pImpl->m_nTableDepth--;
3293 break;
3294 case NS_ooxml::LN_tcStart:
3295 m_pImpl->m_nTableCellDepth++;
3296 break;
3297 case NS_ooxml::LN_tcEnd:
3298 m_pImpl->m_nTableCellDepth--;
3299 m_pImpl->m_nLastTableCellParagraphDepth = 0;
3300 break;
3301 case NS_ooxml::LN_glow_glow:
3302 case NS_ooxml::LN_shadow_shadow:
3303 case NS_ooxml::LN_reflection_reflection:
3304 case NS_ooxml::LN_textOutline_textOutline:
3305 case NS_ooxml::LN_textFill_textFill:
3306 case NS_ooxml::LN_scene3d_scene3d:
3307 case NS_ooxml::LN_props3d_props3d:
3308 case NS_ooxml::LN_ligatures_ligatures:
3309 case NS_ooxml::LN_numForm_numForm:
3310 case NS_ooxml::LN_numSpacing_numSpacing:
3311 case NS_ooxml::LN_stylisticSets_stylisticSets:
3312 case NS_ooxml::LN_cntxtAlts_cntxtAlts:
3314 tools::SvRef<TextEffectsHandler> pTextEffectsHandlerPtr( new TextEffectsHandler(nSprmId) );
3315 std::optional<PropertyIds> aPropertyId = pTextEffectsHandlerPtr->getGrabBagPropertyId();
3316 if(aPropertyId)
3318 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3319 if( pProperties )
3321 pProperties->resolve(*pTextEffectsHandlerPtr);
3323 beans::PropertyValue aGrabBag = pTextEffectsHandlerPtr->getInteropGrabBag();
3324 rContext->Insert(*aPropertyId, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
3326 sal_Int16 nTransparency = TextEffectsHandler::GetTextFillSolidFillAlpha(aGrabBag);
3327 if (nTransparency != 0)
3329 rContext->Insert(PROP_CHAR_TRANSPARENCE, uno::Any(nTransparency));
3332 else if (nSprmId == NS_ooxml::LN_cntxtAlts_cntxtAlts)
3334 pTextEffectsHandlerPtr->lcl_sprm(rSprm);
3335 beans::PropertyValue aGrabBag = pTextEffectsHandlerPtr->getInteropGrabBag();
3336 rContext->Insert(*aPropertyId, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
3340 break;
3341 case NS_ooxml::LN_CT_SdtPr_rPr:
3343 // Make sure properties from a previous SDT are not merged with the current ones.
3344 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3346 break;
3347 case NS_ooxml::LN_CT_TblPrBase_tblLook:
3349 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3350 if (pProperties)
3352 pProperties->resolve(*this);
3353 m_pImpl->getTableManager().finishTableLook();
3356 break;
3357 case NS_ooxml::LN_CT_TrPrBase_cnfStyle:
3359 m_pImpl->enableInteropGrabBag("cnfStyle");
3360 resolveSprmProps(*this, rSprm);
3362 TablePropertyMapPtr pPropMap(new TablePropertyMap());
3363 pPropMap->Insert(PROP_ROW_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, ROW_GRAB_BAG);
3364 m_pImpl->getTableManager().insertRowProps(pPropMap);
3366 m_pImpl->disableInteropGrabBag();
3368 break;
3369 case NS_ooxml::LN_CT_TcPrBase_cnfStyle:
3371 m_pImpl->enableInteropGrabBag("cnfStyle");
3372 resolveSprmProps(*this, rSprm);
3374 TablePropertyMapPtr pPropMap(new TablePropertyMap());
3375 pPropMap->Insert(PROP_CELL_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, CELL_GRAB_BAG);
3376 m_pImpl->getTableManager().cellProps(pPropMap);
3378 m_pImpl->disableInteropGrabBag();
3380 break;
3381 case NS_ooxml::LN_CT_PPrBase_cnfStyle:
3383 m_pImpl->enableInteropGrabBag("cnfStyle");
3384 resolveSprmProps(*this, rSprm);
3385 rContext->Insert(PROP_PARA_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, PARA_GRAB_BAG);
3386 m_pImpl->disableInteropGrabBag();
3388 break;
3389 case NS_ooxml::LN_EG_RunInnerContent_sym:
3391 resolveSprmProps(*this, rSprm);
3392 SymbolData aSymbolData = m_pImpl->GetSymbolData();
3393 uno::Any aVal( aSymbolData.sFont );
3394 auto xFootnote = rContext->GetFootnote();
3395 if (!xFootnote.is() && m_pImpl->IsInCustomFootnote())
3396 xFootnote = m_pImpl->GetFootnoteContext()->GetFootnote();
3397 if (xFootnote.is())
3399 // DOCX can have different labels for the footnote reference and the footnote area.
3400 // This skips the one from the footnote area and just uses the reference one.
3401 if (!m_pImpl->IsInFootOrEndnote())
3403 auto xAnchorRange = xFootnote->getAnchor();
3404 auto xAnchorCursor(xAnchorRange->getText()->createTextCursorByRange(xAnchorRange));
3406 // append a dummy character, so the following properties will be set as
3407 // as SwpHints::SwTextAttr instead of the SwAttrSet of the paragraph,
3408 // which would be removed by SwXText::Impl::finishOrAppendParagraph
3409 xAnchorCursor->collapseToEnd();
3410 uno::Reference<text::XTextRange> xHackRange(xAnchorCursor, uno::UNO_QUERY);
3411 xHackRange->setString("x");
3413 uno::Reference<beans::XPropertySet> xAnchorProps(xAnchorRange, uno::UNO_QUERY);
3414 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), aVal);
3415 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_ASIAN), aVal);
3416 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_COMPLEX), aVal);
3417 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_CHAR_SET), uno::Any(awt::CharSet::SYMBOL));
3419 // remove the dummy char
3420 xHackRange->setString("");
3422 OUString sLabel = xFootnote->getLabel() + OUStringChar(aSymbolData.cSymbol);
3423 xFootnote->setLabel(sLabel);
3426 else //it's a _real_ symbol
3428 rContext->Insert(PROP_CHAR_FONT_NAME, aVal);
3429 rContext->Insert(PROP_CHAR_FONT_NAME_ASIAN, aVal);
3430 rContext->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aVal);
3431 rContext->Insert(PROP_CHAR_FONT_CHAR_SET, uno::Any(awt::CharSet::SYMBOL));
3432 utext( reinterpret_cast < const sal_uInt8 * >( &(aSymbolData.cSymbol) ), 1 );
3435 break;
3436 case NS_ooxml::LN_EG_RunInnerContent_ruby:
3438 RubyInfo aInfo ;
3439 m_pImpl->SetRubyInfo(aInfo);
3441 break;
3442 case NS_ooxml::LN_CT_RubyPr:
3443 case NS_ooxml::LN_CT_Ruby_rt:
3444 case NS_ooxml::LN_CT_Ruby_rubyBase:
3446 m_pImpl->SetRubySprmId(nSprmId);
3447 if (nSprmId == NS_ooxml::LN_CT_RubyPr)
3449 resolveSprmProps(*this, rSprm);
3452 break;
3453 case NS_ooxml::LN_EG_RubyContent_r:
3455 const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
3456 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase)
3458 rContext->Insert(PROP_RUBY_TEXT, uno::Any(aInfo.sRubyText));
3459 rContext->Insert(PROP_RUBY_STYLE, uno::Any(aInfo.sRubyStyle));
3460 rContext->Insert(PROP_RUBY_ADJUST, uno::Any(static_cast<sal_Int16>(ConversionHelper::convertRubyAlign(aInfo.nRubyAlign))));
3461 if ( aInfo.nRubyAlign == NS_ooxml::LN_Value_ST_RubyAlign_rightVertical )
3462 rContext->Insert(PROP_RUBY_POSITION, uno::Any(css::text::RubyPosition::INTER_CHARACTER));
3464 m_pImpl->SetRubySprmId(0);
3467 break;
3468 case NS_ooxml::LN_CT_RubyPr_rubyAlign:
3469 case NS_ooxml::LN_CT_RubyPr_hps:
3470 case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
3472 RubyInfo aInfo = m_pImpl->GetRubyInfo();
3473 switch(nSprmId)
3475 case NS_ooxml::LN_CT_RubyPr_rubyAlign:
3476 aInfo.nRubyAlign = nIntValue;
3477 break;
3478 case NS_ooxml::LN_CT_RubyPr_hps:
3479 aInfo.nHps= nIntValue;
3480 break;
3481 case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
3482 aInfo.nHpsBaseText = nIntValue;
3483 break;
3485 m_pImpl->SetRubyInfo(aInfo);
3487 break;
3488 case NS_ooxml::LN_CT_SmartTagRun_smartTagPr:
3490 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3491 if (pProperties && m_pImpl->GetTopContextType() == CONTEXT_PARAGRAPH)
3492 pProperties->resolve(m_pImpl->getSmartTagHandler());
3494 break;
3495 case NS_ooxml::LN_CT_DocPartPr_name:
3497 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3498 if (pProperties)
3499 pProperties->resolve(*this);
3501 break;
3502 case NS_ooxml::LN_CT_DocPartPr_category:
3504 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3505 if (pProperties)
3506 pProperties->resolve(*this);
3508 break;
3509 case NS_ooxml::LN_CT_DocPartCategory_gallery:
3511 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
3512 if (pProperties)
3513 pProperties->resolve(*this);
3515 break;
3516 case NS_ooxml::LN_EG_RunInnerContent_instrText:
3518 m_pImpl->SetIsTextDeleted(false);
3520 break;
3521 case NS_ooxml::LN_EG_RunInnerContent_delText:
3522 case NS_ooxml::LN_EG_RunInnerContent_delInstrText:
3524 m_pImpl->SetIsTextDeleted(true);
3526 break;
3527 default:
3529 #ifdef DBG_UTIL
3530 TagLogger::getInstance().startElement("unhandled");
3531 TagLogger::getInstance().attribute("id", nSprmId);
3532 TagLogger::getInstance().attribute("name", rSprm.getName());
3533 TagLogger::getInstance().endElement();
3534 #endif
3539 void DomainMapper::ProcessDeferredStyleCharacterProperties()
3541 assert(m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET);
3542 m_pImpl->processDeferredCharacterProperties(false);
3545 void DomainMapper::processDeferredCharacterProperties(
3546 const std::map<sal_Int32, uno::Any>& deferredCharacterProperties, bool bCharContext)
3548 if (bCharContext)
3550 assert(m_pImpl->GetTopContextType() == CONTEXT_CHARACTER);
3552 PropertyMapPtr rContext = m_pImpl->GetTopContext();
3553 for( const auto& rProp : deferredCharacterProperties )
3555 sal_Int32 Id = rProp.first;
3556 sal_Int32 nIntValue = 0;
3557 OUString sStringValue;
3558 rProp.second >>= nIntValue;
3559 rProp.second >>= sStringValue;
3560 switch( Id )
3562 case NS_ooxml::LN_EG_RPrBase_position:
3564 double nEscapement = 0;
3565 sal_Int8 nProp = 0;
3566 if ( nIntValue )
3568 nProp = 100;
3569 double fFontSize = 0;
3570 m_pImpl->GetAnyProperty(PROP_CHAR_HEIGHT, rContext) >>= fFontSize;
3571 if ( fFontSize )
3572 // nIntValue is in half-points, fontsize is in points, escapement is a percentage.
3573 nEscapement = round( nIntValue/2.0 / fFontSize * 100 );
3574 else
3575 nEscapement = nIntValue > 0 ? DFLT_ESC_SUPER : DFLT_ESC_SUB;
3577 if ( nEscapement > MAX_ESC_POS )
3578 nEscapement = MAX_ESC_POS;
3579 else if ( nEscapement < -MAX_ESC_POS )
3580 nEscapement = -MAX_ESC_POS;
3582 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( sal_Int16(nEscapement) ) );
3583 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
3585 break;
3586 default:
3587 SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" );
3588 break;
3593 void DomainMapper::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref)
3595 ref->resolve(*this);
3598 void DomainMapper::data(const sal_uInt8* /*buf*/, size_t /*len*/)
3602 void DomainMapper::lcl_startSectionGroup()
3604 if (!m_pImpl->isInIndexContext() && !m_pImpl->isInBibliographyContext())
3606 m_pImpl->PushProperties(CONTEXT_SECTION);
3608 m_pImpl->SetIsFirstParagraphInSection(true);
3609 m_pImpl->SetIsFirstParagraphInSectionAfterRedline(true);
3612 void DomainMapper::lcl_endSectionGroup()
3614 if (m_pImpl->isInIndexContext() || m_pImpl->isInBibliographyContext())
3615 return;
3617 m_pImpl->CheckUnregisteredFrameConversion();
3618 m_pImpl->ExecuteFrameConversion();
3619 // When pasting, it's fine to not have any paragraph inside the document at all.
3620 if (m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->IsNewDoc())
3622 // This section has no paragraph at all (e.g. they are all actually in a frame).
3623 // If this section has a page break, there would be nothing to apply to the page
3624 // style, so force a dummy paragraph.
3625 lcl_startParagraphGroup();
3626 lcl_startCharacterGroup();
3627 sal_uInt8 const sBreak[] = { 0xd };
3628 lcl_text(sBreak, 1);
3629 lcl_endCharacterGroup();
3630 lcl_endParagraphGroup();
3632 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_SECTION);
3633 SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
3634 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
3635 if(pSectionContext)
3637 pSectionContext->CloseSectionGroup( *m_pImpl );
3638 // Remove the dummy paragraph if added for
3639 // handling the section properties if section starts with a table
3640 // tdf#135786: Added annotation condition
3641 if (m_pImpl->GetIsDummyParaAddedForTableInSection() && (m_pImpl->GetAnnotationId() < 0))
3642 m_pImpl->RemoveDummyParaForTableInSection();
3644 m_pImpl->SetIsTextFrameInserted( false );
3645 m_pImpl->PopProperties(CONTEXT_SECTION);
3648 void DomainMapper::lcl_startParagraphGroup()
3650 if (m_pImpl->hasTableManager())
3651 m_pImpl->getTableManager().startParagraphGroup();
3653 * Add new para properties only if paragraph is not split
3654 * or the top context is not of paragraph properties
3655 * Set mbIsSplitPara to false as it has been handled
3657 if (!mbIsSplitPara)
3658 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
3659 mbIsSplitPara = false;
3660 if (m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) != m_pImpl->GetTopContext())
3661 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
3663 if (!m_pImpl->IsInShape() && !m_pImpl->IsInComments())
3665 if (m_pImpl->GetTopContext())
3667 const OUString& sDefaultParaStyle = m_pImpl->GetDefaultParaStyleName();
3668 auto pContext = static_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContext().get());
3669 m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::Any( sDefaultParaStyle ) );
3670 m_pImpl->SetCurrentParaStyleName( sDefaultParaStyle );
3672 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3674 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
3676 // With a w:br at the start of a paragraph, compat14 apparently doesn't apply.
3677 // It works to insert a zero margin before importing paragraph properties because
3678 // TopMargin typically imports without overwrite any existing value. Very handy.
3679 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
3681 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3683 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
3685 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
3687 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
3691 mbWasShapeInPara = false;
3693 m_pImpl->clearDeferredBreaks();
3696 if (m_pImpl->isParaSdtEndDeferred() && m_pImpl->GetTopContext())
3697 m_pImpl->GetTopContext()->Insert(PROP_PARA_SDT_END_BEFORE, uno::Any(true), true, PARA_GRAB_BAG);
3698 m_pImpl->setParaSdtEndDeferred(false);
3700 m_pImpl->SetIsFirstRun(true);
3701 m_pImpl->SetIsOutsideAParagraph(false);
3704 void DomainMapper::lcl_endParagraphGroup()
3706 if (m_pImpl->isBreakDeferred(LINE_BREAK))
3708 if (m_pImpl->GetIsLastParagraphInSection())
3709 m_pImpl->clearDeferredBreak(LINE_BREAK);
3711 while (m_pImpl->isBreakDeferred(LINE_BREAK))
3713 m_pImpl->clearDeferredBreak(LINE_BREAK);
3714 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
3718 m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
3719 if (m_pImpl->hasTableManager())
3720 m_pImpl->getTableManager().endParagraphGroup();
3721 //frame conversion has to be executed after table conversion
3722 m_pImpl->ExecuteFrameConversion();
3723 m_pImpl->SetIsOutsideAParagraph(true);
3726 void DomainMapper::markLastParagraphInSection( )
3728 m_pImpl->SetIsLastParagraphInSection( true );
3731 void DomainMapper::markLastSectionGroup( )
3733 m_pImpl->SetIsLastSectionGroup( true );
3736 void DomainMapper::lcl_startShape(uno::Reference<drawing::XShape> const& xShape)
3738 assert(xShape.is());
3740 m_pImpl->AttachTextBoxContentToShape(xShape);
3741 if (m_pImpl->GetTopContext())
3743 // If there is a deferred page break, handle it now, so that the
3744 // started shape will be on the correct page.
3745 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3747 // RTF doesn't properly report IsFirstRun, so in order to prevent regressions
3748 // always split the paragraph for RTF since that is the way it has been done lately.
3749 if (!m_pImpl->IsFirstRun() || IsRTFImport())
3751 m_pImpl->m_bIsSplitPara = true;
3752 finishParagraph();
3753 lcl_startParagraphGroup();
3756 m_pImpl->PushShapeContext( xShape );
3757 lcl_startParagraphGroup();
3759 else
3761 // No context? Then this image should not appear directly inside the
3762 // document, just save it for later usage.
3763 m_pImpl->PushPendingShape(xShape);
3766 m_pImpl->SetIsFirstParagraphInShape(true);
3767 mbWasShapeInPara = true;
3770 void DomainMapper::lcl_endShape( )
3772 if (!m_pImpl->GetTopContext())
3773 return;
3775 // End the current table, if there are any. Otherwise the unavoidable
3776 // empty paragraph at the end of the shape text will cause problems: if
3777 // the shape text ends with a table, the extra paragraph will be
3778 // handled as an additional row of the ending table.
3779 if (m_pImpl->hasTableManager())
3780 m_pImpl->getTableManager().endTable();
3782 lcl_endParagraphGroup();
3783 m_pImpl->PopShapeContext( );
3784 // A shape is always inside a paragraph (anchored or inline).
3785 m_pImpl->SetIsOutsideAParagraph(false);
3788 void DomainMapper::lcl_startTextBoxContent()
3790 m_pImpl->PushTextBoxContent();
3793 void DomainMapper::lcl_endTextBoxContent()
3795 m_pImpl->PopTextBoxContent();
3798 void DomainMapper::PushStyleSheetProperties( const PropertyMapPtr& pStyleProperties, bool bAffectTableMngr )
3800 m_pImpl->PushStyleProperties( pStyleProperties );
3801 if ( bAffectTableMngr )
3802 m_pImpl->getTableManager( ).SetStyleProperties( pStyleProperties );
3805 void DomainMapper::PopStyleSheetProperties( bool bAffectTableMngr )
3807 m_pImpl->PopProperties( CONTEXT_STYLESHEET );
3808 if ( bAffectTableMngr )
3810 PropertyMapPtr emptyPtr;
3811 m_pImpl->getTableManager( ).SetStyleProperties( emptyPtr );
3815 void DomainMapper::PushListProperties( const ::tools::SvRef<PropertyMap>& pListProperties )
3817 m_pImpl->PushListProperties( pListProperties );
3820 void DomainMapper::PopListProperties()
3822 m_pImpl->PopProperties( CONTEXT_LIST );
3825 void DomainMapper::lcl_startCharacterGroup()
3827 m_pImpl->PushProperties(CONTEXT_CHARACTER);
3828 if (m_pImpl->isSdtEndDeferred())
3830 // Fields have an empty character group before the real one, so don't
3831 // call setSdtEndDeferred(false) here, that will happen only in lcl_utext().
3832 m_pImpl->GetTopContext()->Insert(PROP_SDT_END_BEFORE, uno::Any(true), true, CHAR_GRAB_BAG);
3836 void DomainMapper::lcl_endCharacterGroup()
3838 if (m_pImpl->CheckFootnoteStyle())
3840 m_pImpl->SetCheckFootnoteStyle(m_pImpl->IsInCustomFootnote());
3841 m_pImpl->SetHasFootnoteStyle(false);
3843 m_pImpl->PopProperties(CONTEXT_CHARACTER);
3846 void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
3848 //TODO: Determine the right text encoding (FIB?)
3849 OUString sText( reinterpret_cast<const char*>(data_), len, RTL_TEXTENCODING_MS_1252 );
3850 #ifdef DBG_UTIL
3851 TagLogger::getInstance().startElement("text");
3852 TagLogger::getInstance().chars(sText);
3853 TagLogger::getInstance().endElement();
3854 #endif
3858 if(len == 1)
3860 switch(*data_)
3862 case 0x02: return; //footnote character
3863 case 0x08: // Lock field if in field context
3864 if (m_pImpl->IsOpenField())
3865 m_pImpl->SetFieldLocked();
3866 return;
3867 case 0x0c: //page break
3868 // page breaks aren't supported in footnotes and endnotes
3869 if (!m_pImpl->IsInFootOrEndnote())
3871 m_pImpl->deferBreak(PAGE_BREAK);
3872 m_pImpl->SetIsDummyParaAddedForTableInSectionPage(false);
3874 return;
3875 case 0x0e: //column break
3876 m_pImpl->deferBreak(COLUMN_BREAK);
3877 return;
3878 case 0x0a: //line break
3879 if (m_pImpl->GetIsLastParagraphInSection())
3881 m_pImpl->deferBreak(LINE_BREAK);
3882 return;
3884 break;
3885 case 0x07:
3886 m_pImpl->getTableManager().text(data_, len);
3887 return;
3888 case 0x0d:
3890 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3891 if (pContext && m_pImpl->isBreakDeferred(COLUMN_BREAK))
3893 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
3894 m_pImpl->clearDeferredBreak(COLUMN_BREAK);
3896 finishParagraph();
3897 return;
3899 case cFieldStart:
3900 m_pImpl->PushFieldContext();
3901 return;
3902 case cFieldSep:
3903 // delimiter not necessarily available
3904 // appears only if field contains further content
3905 m_pImpl->CloseFieldCommand();
3906 return;
3907 case cFieldEnd:
3908 m_pImpl->PopFieldContext();
3909 return;
3910 default:
3911 break;
3915 // GetTopContext() is changed by inserted breaks, but we want to keep the current context
3916 PropertyMapPtr pContext = m_pImpl->GetTopContext();
3918 while (m_pImpl->isBreakDeferred(LINE_BREAK))
3920 m_pImpl->clearDeferredBreak(LINE_BREAK);
3921 m_pImpl->appendTextPortion("\n", pContext);
3924 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
3926 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3927 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
3928 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3929 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
3930 m_pImpl->clearDeferredBreaks();
3933 if (pContext && pContext->GetFootnote().is() && m_pImpl->IsInCustomFootnote())
3935 pContext->GetFootnote()->setLabel(sText);
3936 m_pImpl->EndCustomFootnote();
3937 //otherwise ignore sText
3939 else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields())
3941 m_pImpl->AppendFieldCommand(sText);
3943 else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
3944 /*depending on the success of the field insert operation this result will be
3945 set at the field or directly inserted into the text*/
3946 m_pImpl->AppendFieldResult(sText);
3947 else
3949 if (pContext == nullptr)
3950 pContext = new PropertyMap();
3952 if (sText == "\n")
3954 m_pImpl->HandleLineBreak(pContext);
3956 else
3958 m_pImpl->appendTextPortion(sText, pContext);
3962 catch( const uno::RuntimeException& )
3964 TOOLS_WARN_EXCEPTION("writerfilter", "");
3968 void DomainMapper::lcl_positionOffset(const OUString& rText, bool bVertical)
3970 if (bVertical)
3971 m_pImpl->m_aPositionOffsets.second = rText;
3972 else
3973 m_pImpl->m_aPositionOffsets.first = rText;
3976 awt::Point DomainMapper::getPositionOffset()
3978 awt::Point aRet;
3979 aRet.X = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.first.toInt32());
3980 aRet.Y = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.second.toInt32());
3981 return aRet;
3984 void DomainMapper::lcl_align(const OUString& rText, bool bVertical)
3986 if (bVertical)
3987 m_pImpl->m_aAligns.second = rText;
3988 else
3989 m_pImpl->m_aAligns.first = rText;
3992 void DomainMapper::lcl_positivePercentage(const OUString& rText)
3994 m_pImpl->m_aPositivePercentages.push(rText);
3997 void DomainMapper::lcl_checkId(const sal_Int32 nId)
3999 if (m_pImpl->IsInFootnote())
4001 m_pImpl->m_aFootnoteIds.push_back(nId);
4002 // keep only the first real footnote
4003 if (m_pImpl->GetFootnoteCount() == -1 && m_pImpl->m_aFootnoteIds.size() == 2)
4004 m_pImpl->m_aFootnoteIds.pop_front();
4006 else
4008 m_pImpl->m_aEndnoteIds.push_back(nId);
4009 // keep only the first real endnote
4010 if (m_pImpl->GetEndnoteCount() == -1 && m_pImpl->m_aEndnoteIds.size() == 2)
4011 m_pImpl->m_aEndnoteIds.pop_front();
4015 void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
4017 // All these fixed values are defined as static const sal_Unicode codepoints in the fast parser,
4018 // like uFtnEdnRef = 0x2, uFtnEdnSep = 0x3, ... and have a len of 1, if they aren't valid unicode.
4020 OUString sText(reinterpret_cast<const sal_Unicode *>(data_), len);
4021 const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
4022 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt)
4024 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4025 PropertyValueVector_t aProps = comphelper::sequenceToContainer< PropertyValueVector_t >(pContext->GetPropertyValues());
4026 OUString sStyle = getOrCreateCharStyle(aProps, /*bAlwaysCreate=*/false);
4027 m_pImpl->SetRubyText(sText,sStyle);
4028 return;
4031 if (len == 1)
4033 // preload all footnotes in separated footnotes
4034 if (sText[0] == 0x5)
4036 if (m_pImpl->IsInFootnote())
4038 if (m_pImpl->GetFootnoteCount() > -1)
4040 m_pImpl->PopFootOrEndnote();
4041 m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/true);
4043 m_pImpl->IncrementFootnoteCount();
4045 else
4047 if (m_pImpl->GetEndnoteCount() > -1)
4049 m_pImpl->PopFootOrEndnote();
4050 m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/false);
4052 m_pImpl->IncrementEndnoteCount();
4056 // If the footnote contains a Footnote Reference Mark, it can't be a custom footnote
4057 // ******
4058 // This code block is wrong, as it should also be in m_pImpl->IsInFootOrEndnote().
4059 // The main problem is that
4061 // assert(len != 1 || sText[0] != 0x2)
4063 // is triggered by the unit test SwLayoutWriter::testForcepoint75, so all these pseudo
4064 // value handling is broken.
4065 // But this is just a symptom, as I guess it's possible to generate broken DOCX documents,
4066 // which might be problematic, triggering *funny* code paths left and right.
4067 // ******
4068 if (sText[0] == 0x2)
4070 m_pImpl->EndCustomFootnote();
4071 return;
4074 if (m_pImpl->IsInCustomFootnote())
4076 if (sText[0] != 0xd && sText[0] != 0x3)
4078 // DOCX can have different labels for the footnote reference and the footnote area.
4079 // This skips the one from the footnote area and just uses the reference one.
4080 if (!m_pImpl->IsInFootOrEndnote())
4082 if (PropertyMapPtr pFootnoteContext = m_pImpl->GetFootnoteContext())
4084 auto xFootnote = pFootnoteContext->GetFootnote();
4085 xFootnote->setLabel(xFootnote->getLabel() + sText);
4088 return;
4090 else
4091 m_pImpl->SetHasFootnoteStyle(true);
4095 if (m_pImpl->isSdtEndDeferred())
4097 // In case we have a field context, then save the property there, so
4098 // SDT's ending right before a field start are handled as well.
4099 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4100 if (m_pImpl->IsOpenField())
4101 pContext = m_pImpl->GetTopFieldContext()->getProperties();
4102 pContext->Insert(PROP_SDT_END_BEFORE, uno::Any(true), true, CHAR_GRAB_BAG);
4103 m_pImpl->setSdtEndDeferred(false);
4106 bool bNewLine = len == 1 && (sText[0] == 0x0d || sText[0] == 0x07);
4107 if (m_pImpl->GetSdtStarts().empty()
4108 && (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::dropDown
4109 || m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::comboBox))
4111 // Block, cell or row SDT.
4112 if (bNewLine)
4113 // Dropdown control has single-line texts, so in case of newline, create the control.
4114 m_pImpl->m_pSdtHelper->createDropDownControl();
4115 else
4117 m_pImpl->m_pSdtHelper->getSdtTexts().append(sText);
4118 return;
4121 else if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::datePicker)
4123 if (IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
4125 m_pImpl->m_pSdtHelper->getDateFormat().truncate();
4126 m_pImpl->m_pSdtHelper->getLocale().truncate();
4127 return;
4130 else if (m_pImpl->m_pSdtHelper->GetSdtType() != NS_ooxml::LN_CT_SdtRun_sdtContent && m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText)
4132 m_pImpl->m_pSdtHelper->getSdtTexts().append(sText);
4133 if (bNewLine)
4135 m_pImpl->m_pSdtHelper->createPlainTextControl();
4136 finishParagraph();
4138 return;
4140 else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty())
4142 // there are unsupported SDT properties in the document
4143 // save them in the paragraph interop grab bag
4144 if (m_pImpl->IsDiscardHeaderFooter())
4146 // Unless we're supposed to ignore this header/footer.
4147 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4148 return;
4150 if((m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") ||
4151 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") ||
4152 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") ||
4153 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") ||
4154 (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") &&
4155 m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph())
4157 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER);
4159 if (m_pImpl->IsOpenField())
4160 // We have a field, insert the SDT properties to the field's grab-bag, so they won't be lost.
4161 pContext = m_pImpl->GetTopFieldContext()->getProperties();
4163 uno::Sequence<beans::PropertyValue> aGrabBag = m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4164 if (m_pImpl->GetSdtStarts().empty()
4165 || (m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown
4166 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::comboBox))
4168 pContext->Insert(PROP_SDTPR, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
4171 else
4173 uno::Sequence<beans::PropertyValue> aGrabBag = m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4174 if (m_pImpl->GetSdtStarts().empty()
4175 || (m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown
4176 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::comboBox
4177 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::richText))
4179 m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR,
4180 uno::Any(aGrabBag), true, PARA_GRAB_BAG);
4184 else if (len == 1 && sText[0] == 0x03)
4186 // This is the uFtnEdnSep, remember that the document has a separator.
4187 m_pImpl->m_bHasFtnSep = true;
4188 return;
4190 else if (len == 1 && sText[0] == '\r')
4192 // Clear "last" one linebreak at end of section
4193 if (m_pImpl->GetIsLastParagraphInSection() && m_pImpl->isBreakDeferred(LINE_BREAK))
4194 m_pImpl->clearDeferredBreak(LINE_BREAK);
4195 // And emit all other linebreaks
4196 while (m_pImpl->isBreakDeferred(LINE_BREAK))
4198 m_pImpl->clearDeferredBreak(LINE_BREAK);
4199 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
4202 else if (len == 1 && sText[0] == '\t' )
4204 if ( m_pImpl->m_bCheckFirstFootnoteTab && m_pImpl->IsInFootOrEndnote() )
4206 // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent
4207 m_pImpl->m_bCheckFirstFootnoteTab = false;
4208 sal_Int32 nFirstLineIndent = 0;
4209 m_pImpl->GetAnyProperty(PROP_PARA_FIRST_LINE_INDENT, m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)) >>= nFirstLineIndent;
4210 if ( nFirstLineIndent < 0 )
4211 m_pImpl->m_bIgnoreNextTab = true;
4214 if ( m_pImpl->m_bIgnoreNextTab )
4216 m_pImpl->m_bIgnoreNextTab = false;
4217 return;
4220 if (!m_pImpl->hasTableManager())
4221 return;
4223 SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
4224 if ( eSkip == SkipFootnoteSeparator::ON || eSkip == SkipFootnoteSeparator::SKIPPING )
4226 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
4227 return;
4232 while (m_pImpl->isBreakDeferred(LINE_BREAK))
4234 m_pImpl->clearDeferredBreak(LINE_BREAK);
4235 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
4238 m_pImpl->getTableManager().utext(data_, len);
4240 if (bNewLine)
4242 const bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection();
4243 const bool bSingleParagraphAfterRedline = m_pImpl->GetIsFirstParagraphInSection(/*bAfterRedline=*/true) &&
4244 m_pImpl->GetIsLastParagraphInSection();
4245 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
4246 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
4248 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
4250 if (m_pImpl->GetSettingsTable()->GetSplitPgBreakAndParaMark())
4252 if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
4254 m_pImpl->m_bIsSplitPara = true;
4255 finishParagraph();
4256 lcl_startParagraphGroup();
4258 else // IsFirstRun
4260 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4262 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4266 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
4267 m_pImpl->clearDeferredBreaks();
4270 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
4272 if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
4274 mbIsSplitPara = true;
4275 m_pImpl->m_bIsSplitPara = true;
4276 finishParagraph();
4277 lcl_startParagraphGroup();
4279 else // IsFirstRun
4281 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4283 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4287 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
4288 m_pImpl->clearDeferredBreaks();
4292 // If the paragraph contains only the section properties and it has
4293 // no runs, we should not create a paragraph for it in Writer, unless that would remove the whole section.
4294 // Also do not remove here column breaks: they are treated in a different way and place.
4295 bool bIsColumnBreak = false;
4296 if (pContext->isSet(PROP_BREAK_TYPE))
4298 const uno::Any aBreakType = pContext->getProperty(PROP_BREAK_TYPE)->second;
4299 bIsColumnBreak =
4300 aBreakType == style::BreakType_COLUMN_BEFORE ||
4301 aBreakType == style::BreakType_COLUMN_AFTER ||
4302 aBreakType == style::BreakType_COLUMN_BOTH;
4305 bool bRemove = (!m_pImpl->GetParaChanged() && m_pImpl->GetRemoveThisPara()) ||
4306 (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr()
4307 && !bSingleParagraphAfterRedline
4308 && !bIsColumnBreak
4309 && !m_pImpl->GetParaHadField()
4310 && (!m_pImpl->GetIsDummyParaAddedForTableInSectionPage())
4311 && !m_pImpl->GetIsPreviousParagraphFramed()
4312 && !m_pImpl->HasTopAnchoredObjects()
4313 && !m_pImpl->IsParaWithInlineObject());
4315 const bool bNoNumbering = bRemove || (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && bSingleParagraph);
4316 PropertyMapPtr xContext = bNoNumbering ? m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) : PropertyMapPtr();
4317 if (xContext)
4319 // tdf#97417 delete numbering of the paragraph
4320 // it will be deleted anyway, and the numbering would be copied
4321 // to the next paragraph in sw SplitNode and then be applied to
4322 // every following paragraph
4323 xContext->Erase(PROP_NUMBERING_RULES);
4324 static_cast<ParagraphPropertyMap*>(xContext.get())->props().SetListId(-1);;
4325 xContext->Erase(PROP_NUMBERING_LEVEL);
4327 finishParagraph(bRemove, bNoNumbering);
4328 if (bRemove)
4329 m_pImpl->RemoveLastParagraph();
4331 // When the table is closed and the section's initial dummy paragraph has been processed
4332 // then any following sectPr paragraph in the section must be eligible for removal.
4333 if (!bRemove && m_pImpl->GetIsDummyParaAddedForTableInSectionPage() && !IsInTable()
4334 && !m_pImpl->GetFootnoteContext() && !m_pImpl->IsInComments() && !IsInHeaderFooter()
4335 && !IsInShape())
4337 m_pImpl->SetIsDummyParaAddedForTableInSectionPage(false);
4340 m_pImpl->SetParaSectpr(false);
4342 else
4344 // GetTopContext() is changed by inserted breaks, but we want to keep the current context
4345 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4346 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
4348 auto pPara = static_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH).get());
4349 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
4351 /* If PAGEBREAK appears in first paragraph of the section or
4352 * after first run of any paragraph then need to split paragraph
4353 * to handle it properly.
4355 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
4357 m_pImpl->m_bIsSplitPara = true;
4358 finishParagraph();
4359 lcl_startParagraphGroup();
4361 else // IsFirstRun
4363 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4365 pPara->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)), true);
4368 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
4370 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
4372 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() || mbWasShapeInPara)
4374 mbIsSplitPara = true;
4375 m_pImpl->m_bIsSplitPara = true;
4376 finishParagraph();
4377 lcl_startParagraphGroup();
4379 else // IsFirstRun
4381 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4383 pPara->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4386 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
4388 m_pImpl->clearDeferredBreaks();
4391 if (pContext && pContext->GetFootnote().is())
4393 pContext->GetFootnote()->setLabel( sText );
4394 // tdf#141548 don't lose footnote/endnote text of the run with uFtnEdnRef
4395 // (i.e. when footnoteRef/endnoteRef is followed by some text in the same run)
4396 m_pImpl->appendTextPortion( sText, pContext );
4398 else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields())
4400 m_pImpl->AppendFieldCommand(sText);
4402 else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
4403 /*depending on the success of the field insert operation this result will be
4404 set at the field or directly inserted into the text*/
4405 m_pImpl->AppendFieldResult(sText);
4406 else
4408 if (pContext == nullptr)
4409 pContext = new PropertyMap();
4411 m_pImpl->appendTextPortion( sText, pContext );
4415 m_pImpl->SetIsFirstRun(false);
4417 catch( const uno::RuntimeException& )
4422 void DomainMapper::lcl_props(writerfilter::Reference<Properties>::Pointer_t ref)
4424 ref->resolve(*this);
4427 void DomainMapper::lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t ref)
4429 m_pImpl->SetAnyTableImport(true);
4430 switch(name)
4432 case NS_ooxml::LN_FONTTABLE:
4434 // create a font table object that listens to the attributes
4435 // each entry call inserts a new font entry
4436 ref->resolve( *m_pImpl->GetFontTable() );
4437 break;
4438 case NS_ooxml::LN_STYLESHEET:
4439 //same as above to import style sheets
4440 m_pImpl->SetStyleSheetImport( true );
4441 ref->resolve( *m_pImpl->GetStyleSheetTable() );
4442 m_pImpl->GetStyleSheetTable()->ApplyStyleSheets(m_pImpl->GetFontTable());
4443 m_pImpl->SetStyleSheetImport( false );
4444 break;
4445 case NS_ooxml::LN_NUMBERING:
4447 m_pImpl->SetNumberingImport(true);
4448 //the same for list tables
4449 ref->resolve( *m_pImpl->GetListTable() );
4450 m_pImpl->GetListTable( )->CreateNumberingRules( );
4451 m_pImpl->SetNumberingImport(false);
4453 break;
4454 case NS_ooxml::LN_settings_settings:
4455 ref->resolve ( *m_pImpl->GetSettingsTable() );
4456 m_pImpl->ApplySettingsTable();
4457 break;
4458 default:
4459 OSL_FAIL( "which table is to be filled here?");
4461 m_pImpl->SetAnyTableImport(false);
4464 void DomainMapper::lcl_substream(Id rName, ::writerfilter::Reference<Stream>::Pointer_t ref)
4466 m_pImpl->substream(rName, ref);
4469 void DomainMapper::lcl_startGlossaryEntry()
4471 uno::Reference< text::XTextRange > xTextRange = GetCurrentTextRange();
4472 m_pImpl->setGlossaryEntryStart(xTextRange);
4475 void DomainMapper::lcl_endGlossaryEntry()
4477 m_pImpl->appendGlossaryEntry();
4480 void DomainMapper::handleUnderlineType(const Id nId, const ::tools::SvRef<PropertyMap>& rContext)
4482 sal_Int16 nUnderline = awt::FontUnderline::NONE;
4484 switch (nId)
4486 case NS_ooxml::LN_Value_ST_Underline_none:
4487 nUnderline = awt::FontUnderline::NONE;
4488 break;
4489 case NS_ooxml::LN_Value_ST_Underline_words:
4490 rContext->Insert(PROP_CHAR_WORD_MODE, uno::Any(true));
4491 [[fallthrough]];
4492 case NS_ooxml::LN_Value_ST_Underline_single:
4493 nUnderline = awt::FontUnderline::SINGLE;
4494 break;
4495 case NS_ooxml::LN_Value_ST_Underline_double:
4496 nUnderline = awt::FontUnderline::DOUBLE;
4497 break;
4498 case NS_ooxml::LN_Value_ST_Underline_dotted:
4499 nUnderline = awt::FontUnderline::DOTTED;
4500 break;
4501 case NS_ooxml::LN_Value_ST_Underline_dash:
4502 nUnderline = awt::FontUnderline::DASH;
4503 break;
4504 case NS_ooxml::LN_Value_ST_Underline_dotDash:
4505 nUnderline = awt::FontUnderline::DASHDOT;
4506 break;
4507 case NS_ooxml::LN_Value_ST_Underline_dotDotDash:
4508 nUnderline = awt::FontUnderline::DASHDOTDOT;
4509 break;
4510 case NS_ooxml::LN_Value_ST_Underline_thick:
4511 nUnderline = awt::FontUnderline::BOLD;
4512 break;
4513 case NS_ooxml::LN_Value_ST_Underline_wave:
4514 nUnderline = awt::FontUnderline::WAVE;
4515 break;
4516 case NS_ooxml::LN_Value_ST_Underline_dottedHeavy:
4517 nUnderline = awt::FontUnderline::BOLDDOTTED;
4518 break;
4519 case NS_ooxml::LN_Value_ST_Underline_dashedHeavy:
4520 nUnderline = awt::FontUnderline::BOLDDASH;
4521 break;
4522 case NS_ooxml::LN_Value_ST_Underline_dashLong:
4523 nUnderline = awt::FontUnderline::LONGDASH;
4524 break;
4525 case NS_ooxml::LN_Value_ST_Underline_dashLongHeavy:
4526 nUnderline = awt::FontUnderline::BOLDLONGDASH;
4527 break;
4528 case NS_ooxml::LN_Value_ST_Underline_dashDotHeavy:
4529 nUnderline = awt::FontUnderline::BOLDDASHDOT;
4530 break;
4531 case NS_ooxml::LN_Value_ST_Underline_dashDotDotHeavy:
4532 nUnderline = awt::FontUnderline::BOLDDASHDOTDOT;
4533 break;
4534 case NS_ooxml::LN_Value_ST_Underline_wavyHeavy:
4535 nUnderline = awt::FontUnderline::BOLDWAVE;
4536 break;
4537 case NS_ooxml::LN_Value_ST_Underline_wavyDouble:
4538 nUnderline = awt::FontUnderline::DOUBLEWAVE;
4539 break;
4541 rContext->Insert(PROP_CHAR_UNDERLINE, uno::Any(nUnderline));
4544 void DomainMapper::handleParaJustification(const sal_Int32 nIntValue, const ::tools::SvRef<PropertyMap>& rContext, const bool bExchangeLeftRight)
4546 style::ParagraphAdjust nAdjust = style::ParagraphAdjust_LEFT;
4547 style::ParagraphAdjust nLastLineAdjust = style::ParagraphAdjust_LEFT;
4548 OUString aStringValue = "left";
4549 switch(nIntValue)
4551 case NS_ooxml::LN_Value_ST_Jc_center:
4552 nAdjust = style::ParagraphAdjust_CENTER;
4553 aStringValue = "center";
4554 break;
4555 case NS_ooxml::LN_Value_ST_Jc_right:
4556 case NS_ooxml::LN_Value_ST_Jc_end:
4557 nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_LEFT : style::ParagraphAdjust_RIGHT;
4558 aStringValue = "right";
4559 break;
4560 case NS_ooxml::LN_Value_ST_Jc_distribute:
4561 nLastLineAdjust = style::ParagraphAdjust_BLOCK;
4562 [[fallthrough]];
4563 case NS_ooxml::LN_Value_ST_Jc_both:
4564 nAdjust = style::ParagraphAdjust_BLOCK;
4565 aStringValue = "both";
4566 break;
4567 case NS_ooxml::LN_Value_ST_Jc_left:
4568 case NS_ooxml::LN_Value_ST_Jc_start:
4569 default:
4570 nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
4571 break;
4573 rContext->Insert( PROP_PARA_ADJUST, uno::Any( nAdjust ) );
4574 rContext->Insert( PROP_PARA_LAST_LINE_ADJUST, uno::Any( nLastLineAdjust ) );
4575 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "jc", aStringValue);
4578 bool DomainMapper::getColorFromId(const Id nId, sal_Int32 &nColor)
4580 nColor = 0;
4581 if ((nId < NS_ooxml::LN_Value_ST_HighlightColor_black) || (nId > NS_ooxml::LN_Value_ST_HighlightColor_none))
4582 return false;
4584 switch (nId)
4586 case NS_ooxml::LN_Value_ST_HighlightColor_black: nColor=0x000000; break;
4587 case NS_ooxml::LN_Value_ST_HighlightColor_blue: nColor=0x0000ff; break;
4588 case NS_ooxml::LN_Value_ST_HighlightColor_cyan: nColor=0x00ffff; break;
4589 case NS_ooxml::LN_Value_ST_HighlightColor_green: nColor=0x00ff00; break;
4590 case NS_ooxml::LN_Value_ST_HighlightColor_magenta: nColor=0xff00ff; break;
4591 case NS_ooxml::LN_Value_ST_HighlightColor_red: nColor=0xff0000; break;
4592 case NS_ooxml::LN_Value_ST_HighlightColor_yellow: nColor=0xffff00; break;
4593 case NS_ooxml::LN_Value_ST_HighlightColor_white: nColor=0xffffff; break;
4594 case NS_ooxml::LN_Value_ST_HighlightColor_darkBlue: nColor=0x000080; break;
4595 case NS_ooxml::LN_Value_ST_HighlightColor_darkCyan: nColor=0x008080; break;
4596 case NS_ooxml::LN_Value_ST_HighlightColor_darkGreen: nColor=0x008000; break;
4597 case NS_ooxml::LN_Value_ST_HighlightColor_darkMagenta: nColor=0x800080; break;
4598 case NS_ooxml::LN_Value_ST_HighlightColor_darkRed: nColor=0x800000; break;
4599 case NS_ooxml::LN_Value_ST_HighlightColor_darkYellow: nColor=0x808000; break;
4600 case NS_ooxml::LN_Value_ST_HighlightColor_darkGray: nColor=0x808080; break;
4601 case NS_ooxml::LN_Value_ST_HighlightColor_lightGray: nColor=0xC0C0C0; break;
4602 case NS_ooxml::LN_Value_ST_HighlightColor_none: nColor=0xFFFFFFFF; break; //COL_AUTO
4603 default:
4604 return false;
4606 return true;
4609 sal_Int16 DomainMapper::getEmphasisValue(const sal_Int32 nIntValue)
4611 switch (nIntValue)
4613 case NS_ooxml::LN_Value_ST_Em_dot:
4614 return text::FontEmphasis::DOT_ABOVE;
4615 case NS_ooxml::LN_Value_ST_Em_comma:
4616 return text::FontEmphasis::ACCENT_ABOVE;
4617 case NS_ooxml::LN_Value_ST_Em_circle:
4618 return text::FontEmphasis::CIRCLE_ABOVE;
4619 case NS_ooxml::LN_Value_ST_Em_underDot:
4620 return text::FontEmphasis::DOT_BELOW;
4621 default:
4622 return text::FontEmphasis::NONE;
4626 OUString DomainMapper::getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix)
4628 switch(nIntValue)
4630 case NS_ooxml::LN_Value_ST_CombineBrackets_round:
4631 if (bIsPrefix)
4632 return "(";
4633 return ")";
4635 case NS_ooxml::LN_Value_ST_CombineBrackets_square:
4636 if (bIsPrefix)
4637 return "[";
4638 return "]";
4640 case NS_ooxml::LN_Value_ST_CombineBrackets_angle:
4641 if (bIsPrefix)
4642 return "<";
4643 return ">";
4645 case NS_ooxml::LN_Value_ST_CombineBrackets_curly:
4646 if (bIsPrefix)
4647 return "{";
4648 return "}";
4650 case NS_ooxml::LN_Value_ST_CombineBrackets_none:
4651 default:
4652 return OUString();
4656 style::TabAlign DomainMapper::getTabAlignFromValue(const sal_Int32 nIntValue)
4658 switch (nIntValue)
4660 case NS_ooxml::LN_Value_ST_TabJc_start:
4661 case NS_ooxml::LN_Value_ST_TabJc_left:
4662 case NS_ooxml::LN_Value_ST_TabJc_bar: // bar not supported
4663 case NS_ooxml::LN_Value_ST_TabJc_num: // num not supported
4664 return style::TabAlign_LEFT;
4665 case NS_ooxml::LN_Value_ST_TabJc_center:
4666 return style::TabAlign_CENTER;
4667 case NS_ooxml::LN_Value_ST_TabJc_end:
4668 case NS_ooxml::LN_Value_ST_TabJc_right:
4669 return style::TabAlign_RIGHT;
4670 case NS_ooxml::LN_Value_ST_TabJc_decimal:
4671 return style::TabAlign_DECIMAL;
4673 return style::TabAlign_LEFT;
4676 sal_Unicode DomainMapper::getFillCharFromValue(const sal_Int32 nIntValue)
4678 switch (nIntValue)
4680 case NS_ooxml::LN_Value_ST_TabTlc_dot:
4681 return u'.';
4682 case NS_ooxml::LN_Value_ST_TabTlc_hyphen:
4683 return u'-';
4684 case NS_ooxml::LN_Value_ST_TabTlc_underscore:
4685 case NS_ooxml::LN_Value_ST_TabTlc_heavy: // FIXME ???
4686 return u'_';
4687 case NS_ooxml::LN_Value_ST_TabTlc_middleDot: // middleDot
4688 return u'\x00b7';
4689 case NS_ooxml::LN_Value_ST_TabTlc_none:
4690 default:
4691 return u' '; // blank space
4695 bool DomainMapper::IsOOXMLImport() const
4697 return m_pImpl->IsOOXMLImport();
4700 bool DomainMapper::IsRTFImport() const
4702 return m_pImpl->IsRTFImport();
4705 uno::Reference < lang::XMultiServiceFactory > const & DomainMapper::GetTextFactory() const
4707 return m_pImpl->GetTextFactory();
4710 uno::Reference< text::XTextRange > DomainMapper::GetCurrentTextRange()
4712 if (m_pImpl->HasTopText())
4713 return m_pImpl->GetTopTextAppend()->getEnd();
4714 return m_pImpl->m_xInsertTextRange;
4717 OUString DomainMapper::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate )
4719 StyleSheetTablePtr pStyleSheets = m_pImpl->GetStyleSheetTable();
4720 return pStyleSheets->getOrCreateCharStyle( rCharProperties, bAlwaysCreate );
4723 StyleSheetTablePtr const & DomainMapper::GetStyleSheetTable( )
4725 return m_pImpl->GetStyleSheetTable( );
4728 SettingsTablePtr const & DomainMapper::GetSettingsTable()
4730 return m_pImpl->GetSettingsTable();
4733 GraphicZOrderHelper* DomainMapper::graphicZOrderHelper()
4735 if (m_zOrderHelper == nullptr)
4736 m_zOrderHelper.reset( new GraphicZOrderHelper );
4737 return m_zOrderHelper.get();
4740 uno::Reference<drawing::XShape> DomainMapper::PopPendingShape()
4742 return m_pImpl->PopPendingShape();
4745 bool DomainMapper::IsInHeaderFooter() const
4747 return m_pImpl->IsInHeaderFooter();
4750 bool DomainMapper::IsInShape() const { return m_pImpl->IsInShape(); }
4752 bool DomainMapper::IsInTable() const
4754 return m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell();
4757 OUString DomainMapper::GetListStyleName(sal_Int32 nListId) const
4759 return m_pImpl->GetListStyleName( nListId );
4762 void DomainMapper::ValidateListLevel(const OUString& sStyleIdentifierD)
4764 m_pImpl->ValidateListLevel(sStyleIdentifierD);
4767 void DomainMapper::SetDocDefaultsImport(bool bSet)
4769 m_pImpl->SetDocDefaultsImport(bSet);
4772 bool DomainMapper::IsStyleSheetImport() const
4774 return m_pImpl->IsStyleSheetImport();
4777 bool DomainMapper::IsNumberingImport() const
4779 return m_pImpl->IsNumberingImport();
4782 void DomainMapper::enableInteropGrabBag(const OUString& aName)
4784 m_pImpl->m_aInteropGrabBagName = aName;
4787 beans::PropertyValue DomainMapper::getInteropGrabBag()
4789 beans::PropertyValue aRet;
4790 aRet.Name = m_pImpl->m_aInteropGrabBagName;
4791 aRet.Value <<= comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag);
4793 m_pImpl->m_aInteropGrabBag.clear();
4794 m_pImpl->m_aInteropGrabBagName.clear();
4795 return aRet;
4798 void DomainMapper::HandleRedline( Sprm& rSprm )
4800 sal_uInt32 nSprmId = rSprm.getId();
4802 m_pImpl->AddNewRedline( nSprmId );
4804 if (nSprmId == NS_ooxml::LN_CT_PPr_pPrChange)
4806 m_pImpl->SetCurrentRedlineToken(XML_ParagraphFormat);
4808 else if (nSprmId == NS_ooxml::LN_CT_TrPr_ins)
4810 m_pImpl->SetCurrentRedlineToken(XML_tableRowInsert);
4812 else if (nSprmId == NS_ooxml::LN_CT_TrPr_del)
4814 m_pImpl->SetCurrentRedlineToken(XML_tableRowDelete);
4816 else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellIns)
4818 m_pImpl->SetCurrentRedlineToken(XML_tableCellInsert);
4820 else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellDel)
4822 m_pImpl->SetCurrentRedlineToken(XML_tableCellDelete);
4825 resolveSprmProps(*this, rSprm );
4826 // now the properties author, date and id should be available
4827 sal_Int32 nToken = m_pImpl->GetCurrentRedlineToken();
4828 switch( nToken & 0xffff )
4830 case XML_mod:
4831 case XML_ins:
4832 case XML_del:
4833 case XML_moveTo:
4834 case XML_moveFrom:
4835 case XML_ParagraphFormat:
4836 case XML_tableRowInsert:
4837 case XML_tableRowDelete:
4838 case XML_tableCellInsert:
4839 case XML_tableCellDelete:
4840 break;
4841 default: OSL_FAIL( "redline token other than mod, ins, del, moveTo, moveFrom or table row" ); break;
4843 m_pImpl->EndParaMarkerChange( );
4844 m_pImpl->SetCurrentRedlineIsRead();
4847 void DomainMapper::finishParagraph(const bool bRemove, const bool bNoNumbering)
4849 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::datePicker)
4850 m_pImpl->m_pSdtHelper->createDateContentControl();
4851 m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), bRemove, bNoNumbering);
4854 void DomainMapper::commentProps(const OUString& sId, const CommentProperties& rProps)
4856 m_pImpl->commentProps(sId, rProps);
4859 css::uno::Reference<css::container::XNameContainer> const & DomainMapper::GetCharacterStyles()
4861 return m_pImpl->GetCharacterStyles();
4864 OUString DomainMapper::GetUnusedCharacterStyleName()
4866 return m_pImpl->GetUnusedCharacterStyleName();
4869 } //namespace writerfilter
4871 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */