1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 #include "PageBordersHandler.hxx"
20 
21 #include "util.hxx"
22 #include "SdtHelper.hxx"
23 #include "TDefTableHandler.hxx"
24 #include "DomainMapper_Impl.hxx"
25 #include "ConversionHelper.hxx"
26 #include "ModelEventListener.hxx"
27 #include "MeasureHandler.hxx"
28 #include <i18nlangtag/languagetag.hxx>
29 #include <i18nutil/paper.hxx>
30 #include <oox/token/tokens.hxx>
31 #include <oox/drawingml/drawingmltypes.hxx>
32 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
33 #include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp>
34 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
35 #include <com/sun/star/table/ShadowFormat.hpp>
36 #include <com/sun/star/text/HoriOrientation.hpp>
37 #include <com/sun/star/text/RelOrientation.hpp>
38 #include <com/sun/star/text/VertOrientation.hpp>
39 #include <com/sun/star/text/WrapTextMode.hpp>
40 #include <com/sun/star/text/SizeType.hpp>
41 #include <com/sun/star/text/XEndnotesSupplier.hpp>
42 #include <com/sun/star/text/XFootnotesSupplier.hpp>
43 #include <com/sun/star/text/XLineNumberingProperties.hpp>
44 #include <com/sun/star/awt/FontRelief.hpp>
45 #include <com/sun/star/awt/FontWeight.hpp>
46 #include <com/sun/star/awt/FontUnderline.hpp>
47 #include <com/sun/star/awt/FontStrikeout.hpp>
48 #include <com/sun/star/awt/FontSlant.hpp>
49 #include <com/sun/star/document/XEventBroadcaster.hpp>
50 #include <com/sun/star/style/ParagraphAdjust.hpp>
51 #include <com/sun/star/style/BreakType.hpp>
52 #include <com/sun/star/style/CaseMap.hpp>
53 #include <com/sun/star/style/LineSpacing.hpp>
54 #include <com/sun/star/style/LineSpacingMode.hpp>
55 #include <com/sun/star/text/FootnoteNumbering.hpp>
56 #include <com/sun/star/text/TextGridMode.hpp>
57 #include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
58 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
59 #include <com/sun/star/text/WritingMode.hpp>
60 #include <com/sun/star/text/WritingMode2.hpp>
61 #include <com/sun/star/text/XFootnote.hpp>
62 #include <com/sun/star/text/XTextColumns.hpp>
63 #include <com/sun/star/text/RubyPosition.hpp>
64 #include <com/sun/star/uno/XComponentContext.hpp>
65 #include <com/sun/star/text/FontEmphasis.hpp>
66 #include <com/sun/star/awt/CharSet.hpp>
67 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
68 #include <comphelper/types.hxx>
69 #include <comphelper/storagehelper.hxx>
70 #include <comphelper/sequence.hxx>
71 #include <editeng/escapementitem.hxx>
72 #include <filter/msfilter/util.hxx>
73 #include <sfx2/DocumentMetadataAccess.hxx>
74 #include <unotools/mediadescriptor.hxx>
75 
76 #include "TextEffectsHandler.hxx"
77 #include "CellColorHandler.hxx"
78 #include "SectionColumnHandler.hxx"
79 #include "GraphicHelpers.hxx"
80 #include <dmapper/GraphicZOrderHelper.hxx>
81 #include <tools/diagnose_ex.h>
82 #include <sal/log.hxx>
83 #include <vcl/svapp.hxx>
84 #include <vcl/outdev.hxx>
85 #include <vcl/font.hxx>
86 
87 using namespace ::com::sun::star;
88 using namespace oox;
89 
90 namespace writerfilter {
91 
92 namespace dmapper{
93 
94 struct
95 {
96     sal_Int32 h;
97     bool      orient;
98     sal_Int32 w;
99 } CT_PageSz;
100 
101 
DomainMapper(const uno::Reference<uno::XComponentContext> & xContext,uno::Reference<io::XInputStream> const & xInputStream,uno::Reference<lang::XComponent> const & xModel,bool bRepairStorage,SourceDocumentType eDocumentType,utl::MediaDescriptor const & rMediaDesc)102 DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xContext,
103                             uno::Reference<io::XInputStream> const& xInputStream,
104                             uno::Reference<lang::XComponent> const& xModel,
105                             bool bRepairStorage,
106                             SourceDocumentType eDocumentType,
107                             utl::MediaDescriptor const & rMediaDesc) :
108     LoggedProperties("DomainMapper"),
109     LoggedTable("DomainMapper"),
110     LoggedStream("DomainMapper"),
111     m_pImpl(new DomainMapper_Impl(*this, xContext, xModel, eDocumentType, rMediaDesc)),
112     mbIsSplitPara(false)
113     ,mbHasControls(false)
114 {
115     // #i24363# tab stops relative to indent
116     m_pImpl->SetDocumentSettingsProperty(
117         getPropertyName( PROP_TABS_RELATIVE_TO_INDENT ),
118         uno::makeAny( false ) );
119     m_pImpl->SetDocumentSettingsProperty(
120         getPropertyName( PROP_SURROUND_TEXT_WRAP_SMALL ),
121         uno::makeAny( true ) );
122     m_pImpl->SetDocumentSettingsProperty(
123         getPropertyName( PROP_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING ),
124         uno::makeAny( true ) );
125 
126     // Don't load the default style definitions to avoid weird mix
127     m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::makeAny(true));
128     m_pImpl->SetDocumentSettingsProperty("HeaderSpacingBelowLastPara",
129                                          uno::makeAny(true));
130 
131     m_pImpl->SetDocumentSettingsProperty("TabAtLeftIndentForParagraphsInList", uno::makeAny(true));
132 
133     // Initialize RDF metadata, to be able to add statements during the import.
134     try
135     {
136         uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY_THROW);
137         uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
138         OUString aBaseURL = rMediaDesc.getUnpackedValueOrDefault("URL", OUString());
139         const uno::Reference<frame::XModel> xModel_(xModel,
140             uno::UNO_QUERY_THROW);
141         const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xContext, xModel_, aBaseURL, OUString()));
142         const uno::Reference<task::XInteractionHandler> xHandler;
143         xDocumentMetadataAccess->loadMetadataFromStorage(xStorage, xBaseURI, xHandler);
144     }
145     catch (const uno::Exception&)
146     {
147         DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize RDF metadata");
148     }
149 
150     if (eDocumentType == SourceDocumentType::OOXML) {
151         // tdf#108350
152         // In Word since version 2007, the default document font is Calibri 11 pt.
153         // If a DOCX document doesn't contain font information, we should assume
154         // the intended font to provide best layout match.
155         try
156         {
157             uno::Reference< beans::XPropertySet > xDefProps(GetTextFactory()->createInstance("com.sun.star.text.Defaults"),
158                 uno::UNO_QUERY_THROW);
159             xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), css::uno::Any(OUString("Calibri")));
160             xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), css::uno::Any(double(11)));
161         }
162         catch (const uno::Exception&)
163         {
164             DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize default font");
165         }
166     }
167 
168     //import document properties
169     try
170     {
171         uno::Reference< embed::XStorage > xDocumentStorage =
172             comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xContext, bRepairStorage );
173 
174         uno::Reference< uno::XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext(
175                                 "com.sun.star.document.OOXMLDocumentPropertiesImporter",
176                                 xContext);
177 
178         uno::Reference< document::XOOXMLDocumentPropertiesImporter > xImporter( xTemp, uno::UNO_QUERY_THROW );
179         uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier( xModel, uno::UNO_QUERY_THROW);
180         xImporter->importProperties( xDocumentStorage, xPropSupplier->getDocumentProperties() );
181     }
182     catch( const uno::Exception& ) {}
183 }
184 
~DomainMapper()185 DomainMapper::~DomainMapper()
186 {
187     try
188     {
189         uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
190         sal_Int32 nIndexes = 0;
191         if( xIndexesSupplier.is() )
192         {
193             uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes();
194             nIndexes = xIndexes->getCount();
195         }
196         // If we have page references, those need updating as well, similar to the indexes.
197         uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
198         if(xTextFieldsSupplier.is())
199         {
200             uno::Reference<container::XEnumeration> xEnumeration = xTextFieldsSupplier->getTextFields()->createEnumeration();
201             while(xEnumeration->hasMoreElements())
202             {
203                 ++nIndexes;
204                 xEnumeration->nextElement();
205             }
206         }
207 
208         mbHasControls |= m_pImpl->m_pSdtHelper->hasElements();
209         if ( nIndexes || mbHasControls )
210         {
211             //index update has to wait until first view is created
212             uno::Reference< document::XEventBroadcaster > xBroadcaster(xIndexesSupplier, uno::UNO_QUERY);
213             if (xBroadcaster.is())
214                 xBroadcaster->addEventListener(uno::Reference< document::XEventListener >(new ModelEventListener(nIndexes, mbHasControls)));
215         }
216 
217 
218         // Apply the document settings after everything else
219         m_pImpl->GetSettingsTable()->ApplyProperties( m_pImpl->GetTextDocument( ) );
220 
221         // now that importing is finished, re-enable default styles for any that were never defined/imported.
222         m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::makeAny(false));
223 
224         // Grab-bag handling
225         comphelper::SequenceAsHashMap aProperties;
226 
227         // Add the saved w:themeFontLang setting
228         aProperties["ThemeFontLangProps"] <<= m_pImpl->GetSettingsTable()->GetThemeFontLangProperties();
229 
230         // Add the saved compat settings
231         aProperties["CompatSettings"] <<= m_pImpl->GetSettingsTable()->GetCompatSettings();
232 
233         // Add the saved DocumentProtection settings
234         aProperties["DocumentProtection"] <<= m_pImpl->GetSettingsTable()->GetDocumentProtectionSettings();
235 
236         // Add the saved w:hypenationZone setting
237         aProperties["HyphenationZone"] <<= m_pImpl->GetSettingsTable()->GetHypenationZone();
238 
239         // Add the saved w:doNotHyphenateCaps setting
240         aProperties["NoHyphenateCaps"] <<= m_pImpl->GetSettingsTable()->GetNoHyphenateCaps();
241 
242         uno::Reference<beans::XPropertySet> xDocProps(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
243         if (xDocProps.is())
244         {
245             comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue("InteropGrabBag"));
246             aGrabBag.update(aProperties);
247             xDocProps->setPropertyValue("InteropGrabBag", uno::Any(aGrabBag.getAsConstPropertyValueList()));
248         }
249     }
250     catch( const uno::Exception& ) {}
251 
252 #ifdef DBG_UTIL
253     TagLogger::getInstance().endDocument();
254 #endif
255 }
256 
lcl_attribute(Id nName,Value & val)257 void DomainMapper::lcl_attribute(Id nName, Value & val)
258 {
259     if (m_pImpl->hasTableManager() && m_pImpl->getTableManager().attribute(nName, val))
260         return;
261 
262     static const int nSingleLineSpacing = 240;
263     sal_Int32 nIntValue = val.getInt();
264     OUString sStringValue = val.getString();
265 
266     SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
267     switch( nName )
268     {
269         case NS_ooxml::LN_CT_Lvl_start:
270             break;
271         case NS_ooxml::LN_CT_Lvl_numFmt:
272             break;
273         case NS_ooxml::LN_CT_Lvl_isLgl:
274             break;
275         case NS_ooxml::LN_CT_Lvl_legacy:
276             break;
277         case NS_ooxml::LN_CT_AbstractNum_nsid:
278             break;
279         case NS_ooxml::LN_CT_AbstractNum_tmpl:
280             break;
281         case NS_ooxml::LN_CT_Border_sz:
282             break;
283         case NS_ooxml::LN_CT_Border_val:
284             break;
285         case NS_ooxml::LN_CT_Border_space:
286             break;
287         case NS_ooxml::LN_CT_Border_shadow:
288             break;
289         case NS_ooxml::LN_CT_Border_frame:
290             break;
291         case NS_ooxml::LN_headerr:
292             break;
293         case NS_ooxml::LN_footerr:
294             break;
295         case NS_ooxml::LN_endnote:
296             break;
297         case NS_ooxml::LN_CT_Bookmark_name:
298             m_pImpl->SetBookmarkName( sStringValue );
299         break;
300         case NS_ooxml::LN_CT_MarkupRangeBookmark_id:
301             // add a bookmark range -- this remembers a bookmark starting here
302             // or, if the bookmark was already started or, if the bookmark was
303             // already started before, writes out the bookmark
304             m_pImpl->StartOrEndBookmark( sStringValue );
305         break;
306         case NS_ooxml::LN_CT_MarkupRange_displacedByCustomXml:
307             break;
308         case NS_ooxml::LN_NUMBERING:
309             break;
310         case NS_ooxml::LN_FONTTABLE:
311             break;
312         case NS_ooxml::LN_STYLESHEET:
313             break;
314 
315         case NS_ooxml::LN_CT_Sym_char:
316             m_pImpl->SetSymbolChar(nIntValue);
317         break;
318         case NS_ooxml::LN_CT_Sym_font:
319             m_pImpl->SetSymbolFont(sStringValue);
320         break;
321         case NS_ooxml::LN_CT_Underline_val:
322             if (m_pImpl->GetTopContext())
323                 handleUnderlineType(nIntValue, m_pImpl->GetTopContext());
324             break;
325         case NS_ooxml::LN_CT_Color_val:
326             if (m_pImpl->GetTopContext())
327                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR, uno::makeAny( nIntValue ) );
328             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue)));
329             break;
330         case NS_ooxml::LN_CT_Underline_color:
331             if (m_pImpl->GetTopContext())
332             {
333                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_HAS_COLOR, uno::makeAny( true ) );
334                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COLOR, uno::makeAny( nIntValue ) );
335             }
336             break;
337 
338         case NS_ooxml::LN_CT_TabStop_val:
339             if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_TabJc_clear)
340             {
341                 m_pImpl->m_aCurrentTabStop.bDeleted = true;
342             }
343             else
344             {
345                 m_pImpl->m_aCurrentTabStop.bDeleted = false;
346                 m_pImpl->m_aCurrentTabStop.Alignment = getTabAlignFromValue(nIntValue);
347             }
348             break;
349         case NS_ooxml::LN_CT_TabStop_leader:
350             m_pImpl->m_aCurrentTabStop.FillChar = getFillCharFromValue(nIntValue);
351             break;
352         case NS_ooxml::LN_CT_TabStop_pos:
353             m_pImpl->m_aCurrentTabStop.Position = ConversionHelper::convertTwipToMM100(nIntValue);
354             break;
355 
356         case NS_ooxml::LN_CT_Fonts_ascii:
357             if (m_pImpl->GetTopContext())
358             {
359                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( sStringValue ));
360                 if (m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) && m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->isSet(PROP_NUMBERING_RULES))
361                 {
362                     // Font of the paragraph mark should be used for the numbering as well.
363                     uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle());
364                     if (xCharStyle.is())
365                         xCharStyle->setPropertyValue("CharFontName", uno::makeAny(sStringValue));
366                 }
367             }
368             break;
369         case NS_ooxml::LN_CT_Fonts_asciiTheme:
370             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeTable::getStringForTheme(nIntValue));
371             if (m_pImpl->GetTopContext())
372             {
373                 uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) );
374                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, aPropValue );
375                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_ASCII, aPropValue, true, CHAR_GRAB_BAG );
376                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_ASCII, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
377             }
378             break;
379         case NS_ooxml::LN_CT_Fonts_hAnsi:
380             break;//unsupported
381         case NS_ooxml::LN_CT_Fonts_hAnsiTheme:
382             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeTable::getStringForTheme(nIntValue));
383             if (m_pImpl->GetTopContext())
384                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_H_ANSI, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
385             break;
386         case NS_ooxml::LN_CT_Fonts_eastAsia:
387             if (m_pImpl->GetTopContext())
388                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::makeAny( sStringValue ));
389             break;
390         case NS_ooxml::LN_CT_Fonts_eastAsiaTheme:
391             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsiaTheme", ThemeTable::getStringForTheme(nIntValue));
392             if (m_pImpl->GetTopContext())
393             {
394                 uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) );
395                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, aPropValue );
396                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_EAST_ASIA, aPropValue, true, CHAR_GRAB_BAG );
397                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_EAST_ASIA, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
398             }
399             break;
400         case NS_ooxml::LN_CT_Fonts_cs:
401             if (m_pImpl->GetTopContext())
402                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::makeAny( sStringValue ));
403             break;
404         case NS_ooxml::LN_CT_Fonts_cstheme:
405             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "cstheme", ThemeTable::getStringForTheme(nIntValue));
406             if (m_pImpl->GetTopContext())
407             {
408                 uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) );
409                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aPropValue );
410                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_CS, aPropValue, true, CHAR_GRAB_BAG );
411                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_CS, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
412             }
413         break;
414         case NS_ooxml::LN_CT_Spacing_before:
415             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "before", OUString::number(nIntValue));
416             if (m_pImpl->GetTopContext())
417                 // Don't overwrite NS_ooxml::LN_CT_Spacing_beforeAutospacing.
418                 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
419             break;
420         case NS_ooxml::LN_CT_Spacing_beforeLines:
421                 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "beforeLines", OUString::number(nIntValue));
422                 // We would need to make sure that this doesn't overwrite any
423                 // NS_ooxml::LN_CT_Spacing_before in parent styles before style
424                 // sheet support can be enabled.
425                 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
426                     m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
427             break;
428         case NS_ooxml::LN_CT_Spacing_after:
429             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "after", OUString::number(nIntValue));
430             if (m_pImpl->GetTopContext())
431             {
432                 // Don't overwrite NS_ooxml::LN_CT_Spacing_afterAutospacing.
433                 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
434 
435                 uno::Any aContextualSpacingFromStyle = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_CONTEXT_MARGIN);
436                 if (aContextualSpacingFromStyle.hasValue())
437                     // Setting "after" spacing means Writer doesn't inherit
438                     // contextual spacing anymore from style, but Word does.
439                     m_pImpl->GetTopContext()->Insert(PROP_PARA_CONTEXT_MARGIN, aContextualSpacingFromStyle);
440             }
441             break;
442         case NS_ooxml::LN_CT_Spacing_afterLines:
443             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "afterLines", OUString::number(nIntValue));
444             // We would need to make sure that this doesn't overwrite any
445             // NS_ooxml::LN_CT_Spacing_after in parent styles before style
446             // sheet support can be enabled.
447             if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
448                 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
449             break;
450         case NS_ooxml::LN_CT_Spacing_line: //91434
451         case NS_ooxml::LN_CT_Spacing_lineRule: //91435
452         {
453             style::LineSpacing aSpacing;
454             PropertyMapPtr pTopContext = m_pImpl->GetTopContext();
455             boost::optional<PropertyMap::Property> aLineSpacingVal;
456             if (pTopContext && (aLineSpacingVal = pTopContext->getProperty(PROP_PARA_LINE_SPACING)) )
457             {
458                 aLineSpacingVal->second >>= aSpacing;
459             }
460             else
461             {
462                 //default to single line spacing
463                 aSpacing.Mode = style::LineSpacingMode::FIX;
464                 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
465             }
466             if( nName == NS_ooxml::LN_CT_Spacing_line )
467             {
468                 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "line", OUString::number(nIntValue));
469                 //now set the value depending on the Mode
470                 if( aSpacing.Mode == style::LineSpacingMode::PROP )
471                     aSpacing.Height = sal_Int16(nIntValue * 100 / nSingleLineSpacing );
472                 else
473                     aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nIntValue ));
474             }
475             else //NS_ooxml::LN_CT_Spacing_lineRule:
476             {
477                     // exactly, atLeast, auto
478                     if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_auto)
479                     {
480                         m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "auto");
481                         if (aSpacing.Height >= 0)
482                         {
483                             aSpacing.Mode = style::LineSpacingMode::PROP;
484                             //reinterpret the already set value
485                             aSpacing.Height = sal_Int16( aSpacing.Height * 100 /  ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
486                         }
487                         else
488                         {
489                             // Negative value still means a positive height,
490                             // just the mode is "exact".
491                             aSpacing.Mode = style::LineSpacingMode::FIX;
492                             aSpacing.Height *= -1;
493                         }
494                     }
495                     else if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast)
496                     {
497                         m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "atLeast");
498                         aSpacing.Mode = style::LineSpacingMode::MINIMUM;
499                     }
500                     else // NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact
501                     {
502                         m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "exact");
503                         aSpacing.Mode = style::LineSpacingMode::FIX;
504                     }
505             }
506             if (pTopContext)
507                 pTopContext->Insert(PROP_PARA_LINE_SPACING, uno::makeAny( aSpacing ));
508         }
509         break;
510         case NS_ooxml::LN_CT_Ind_start:
511         case NS_ooxml::LN_CT_Ind_left:
512             if (m_pImpl->GetTopContext())
513             {
514                 // Word inherits FirstLineIndent property of the numbering, even if ParaLeftMargin is set, Writer does not.
515                 // So copy it explicitly, if necessary.
516                 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
517                 sal_Int32 nIndentAt = m_pImpl->getCurrentNumberingProperty("IndentAt");
518 
519                 sal_Int32 nParaLeftMargin = ConversionHelper::convertTwipToMM100(nIntValue);
520                 if (nParaLeftMargin != 0 && nIndentAt == nParaLeftMargin)
521                     // Avoid direct left margin when it's the same as from the
522                     // numbering.
523                     break;
524 
525                 if (nFirstLineIndent != 0)
526                     m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
527 
528                 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN,
529                                                  uno::makeAny(nParaLeftMargin));
530             }
531             break;
532         case NS_ooxml::LN_CT_Ind_end:
533         case NS_ooxml::LN_CT_Ind_right:
534             if (m_pImpl->GetTopContext())
535             {
536                 // Word inherits FirstLineIndent/ParaLeftMargin property of the numbering, even if ParaRightMargin is set, Writer does not.
537                 // So copy it explicitly, if necessary.
538                 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
539                 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
540 
541                 if (nFirstLineIndent != 0)
542                     m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
543                 if (nParaLeftMargin != 0)
544                     m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);
545 
546                 m_pImpl->GetTopContext()->Insert(
547                     PROP_PARA_RIGHT_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) ));
548             }
549             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "right", OUString::number(nIntValue));
550             break;
551         case NS_ooxml::LN_CT_Ind_hanging:
552             if (m_pImpl->GetTopContext())
553             {
554                 sal_Int32 nValue = ConversionHelper::convertTwipToMM100( nIntValue );
555                 m_pImpl->GetTopContext()->Insert(
556                     PROP_PARA_FIRST_LINE_INDENT, uno::makeAny( - nValue ));
557 
558                 // See above, need to inherit left margin from list style when first is set.
559                 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
560                 if (nParaLeftMargin != 0)
561                     m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);
562             }
563             break;
564         case NS_ooxml::LN_CT_Ind_firstLine:
565             if (m_pImpl->GetTopContext())
566             {
567                 sal_Int32 nFirstLineIndent
568                     = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
569                 sal_Int32 nParaFirstLineIndent = ConversionHelper::convertTwipToMM100(nIntValue);
570                 if (nParaFirstLineIndent != 0 && nFirstLineIndent == nParaFirstLineIndent)
571                     // Avoid direct first margin when it's the same as from the
572                     // numbering.
573                     break;
574                 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT,
575                                                  uno::makeAny(nParaFirstLineIndent));
576             }
577             break;
578         case NS_ooxml::LN_CT_Ind_rightChars:
579             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "rightChars", OUString::number(nIntValue));
580             break;
581 
582         case NS_ooxml::LN_CT_EastAsianLayout_id:
583             break;
584         case NS_ooxml::LN_CT_EastAsianLayout_combine:
585             if (m_pImpl->GetTopContext())
586                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_IS_ON, uno::makeAny ( nIntValue != 0 ));
587             break;
588         case NS_ooxml::LN_CT_EastAsianLayout_combineBrackets:
589             if (m_pImpl->GetTopContext())
590             {
591                 OUString sCombinePrefix = getBracketStringFromEnum(nIntValue);
592                 OUString sCombineSuffix = getBracketStringFromEnum(nIntValue, false);
593                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_PREFIX, uno::makeAny ( sCombinePrefix ));
594                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_SUFFIX, uno::makeAny ( sCombineSuffix ));
595             }
596             break;
597         case NS_ooxml::LN_CT_EastAsianLayout_vert:
598             if (m_pImpl->GetTopContext())
599             {
600                 sal_Int16 nRotationAngle = (nIntValue ? 900 : 0);
601                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION, uno::makeAny ( nRotationAngle ));
602             }
603             break;
604         case NS_ooxml::LN_CT_EastAsianLayout_vertCompress:
605             if (m_pImpl->GetTopContext())
606                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION_IS_FIT_TO_LINE, uno::makeAny ( nIntValue != 0 ));
607             break;
608 
609         case NS_ooxml::LN_CT_PageSz_code:
610             break;
611         case NS_ooxml::LN_CT_PageSz_h:
612             {
613                 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100(nIntValue);
614                 CT_PageSz.h = PaperInfo::sloppyFitPageDimension(nHeight);
615             }
616             break;
617         case NS_ooxml::LN_CT_PageSz_orient:
618             CT_PageSz.orient = (nIntValue != static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_PageOrientation_portrait));
619             break;
620         case NS_ooxml::LN_CT_PageSz_w:
621             {
622                 sal_Int32 nWidth = ConversionHelper::convertTwipToMM100(nIntValue);
623                 CT_PageSz.w = PaperInfo::sloppyFitPageDimension(nWidth);
624             }
625             break;
626 
627         case NS_ooxml::LN_CT_PageMar_top:
628             m_pImpl->SetPageMarginTwip( PAGE_MAR_TOP, nIntValue );
629         break;
630         case NS_ooxml::LN_CT_PageMar_right:
631             m_pImpl->SetPageMarginTwip( PAGE_MAR_RIGHT, nIntValue );
632         break;
633         case NS_ooxml::LN_CT_PageMar_bottom:
634             m_pImpl->SetPageMarginTwip( PAGE_MAR_BOTTOM, nIntValue );
635         break;
636         case NS_ooxml::LN_CT_PageMar_left:
637             m_pImpl->SetPageMarginTwip( PAGE_MAR_LEFT, nIntValue );
638         break;
639         case NS_ooxml::LN_CT_PageMar_header:
640             m_pImpl->SetPageMarginTwip( PAGE_MAR_HEADER, nIntValue );
641         break;
642         case NS_ooxml::LN_CT_PageMar_footer:
643             m_pImpl->SetPageMarginTwip( PAGE_MAR_FOOTER, nIntValue );
644         break;
645         case NS_ooxml::LN_CT_PageMar_gutter:
646             m_pImpl->SetPageMarginTwip( PAGE_MAR_GUTTER, nIntValue );
647         break;
648         case NS_ooxml::LN_CT_Language_val: //90314
649         case NS_ooxml::LN_CT_Language_eastAsia: //90315
650         case NS_ooxml::LN_CT_Language_bidi: //90316
651         {
652             if (nName == NS_ooxml::LN_CT_Language_eastAsia)
653                 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsia", sStringValue);
654             else if (nName == NS_ooxml::LN_CT_Language_val)
655                 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", sStringValue);
656             else if (nName == NS_ooxml::LN_CT_Language_bidi)
657                 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "bidi", sStringValue);
658             lang::Locale aLocale( LanguageTag::convertToLocale( sStringValue));
659             if (m_pImpl->GetTopContext())
660                 m_pImpl->GetTopContext()->Insert(NS_ooxml::LN_CT_Language_val== nName ? PROP_CHAR_LOCALE :
661                              NS_ooxml::LN_CT_Language_eastAsia == nName ? PROP_CHAR_LOCALE_ASIAN : PROP_CHAR_LOCALE_COMPLEX,
662                              uno::makeAny( aLocale ) );
663         }
664         break;
665         // See SwWW8ImplReader::GetParagraphAutoSpace() on why these are 100 and 280
666         case NS_ooxml::LN_CT_Spacing_beforeAutospacing:
667         {
668             sal_Int32 default_spacing = -1;
669             if (nIntValue)
670             {
671                 m_pImpl->SetParaAutoBefore(true);
672 
673                 default_spacing = 100;
674                 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
675                 {
676                     // 49 is just the old value that should be removed, once the
677                     // root cause in SwTabFrm::MakeAll() is fixed.
678                     if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
679                         default_spacing = 49;
680                     else
681                         default_spacing = 280;
682                 }
683                 // required at export (here mainly for StyleSheets) to determine if the setting has changed from grab_bag
684                 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(default_spacing)));
685             }
686             m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING, uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG );
687         }
688         break;
689         case NS_ooxml::LN_CT_Spacing_afterAutospacing:
690         {
691             sal_Int32 default_spacing = -1;
692             if  (nIntValue)
693             {
694                 default_spacing = 100;
695                 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
696                 {
697                     if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
698                         default_spacing = 49;
699                     else
700                         default_spacing = 280;
701                 }
702                 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(default_spacing)));
703             }
704             m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING, uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG );
705         }
706         break;
707         case NS_ooxml::LN_CT_SmartTagRun_uri:
708             m_pImpl->getSmartTagHandler().setURI(val.getString());
709         break;
710         case NS_ooxml::LN_CT_SmartTagRun_element:
711             m_pImpl->getSmartTagHandler().setElement(val.getString());
712         break;
713         case NS_ooxml::LN_CT_Br_type :
714             //TODO: attributes for break (0x12) are not supported
715         break;
716         case NS_ooxml::LN_CT_Fonts_hint :
717             /*  assigns script type to ambiguous characters, values can be:
718                 NS_ooxml::LN_Value_ST_Hint_default
719                 NS_ooxml::LN_Value_ST_Hint_eastAsia
720                 NS_ooxml::LN_Value_ST_Hint_cs
721              */
722             //TODO: unsupported?
723         break;
724         case NS_ooxml::LN_CT_TblBorders_right:
725         case NS_ooxml::LN_CT_TblBorders_top:
726         case NS_ooxml::LN_CT_TblBorders_left:
727         case NS_ooxml::LN_CT_TblBorders_bottom:
728         //todo: handle cell mar
729         break;
730         case NS_ooxml::LN_blip: // contains the binary graphic
731         case NS_ooxml::LN_shape:
732         {
733             //looks a bit like a hack - and it is. The graphic import is split into the inline_inline part and
734             //afterwards the adding of the binary data.
735             m_pImpl->GetGraphicImport( IMPORT_AS_DETECTED_INLINE )->attribute(nName, val);
736             m_pImpl->ImportGraphic( val.getProperties(), IMPORT_AS_DETECTED_INLINE );
737         }
738         break;
739         case NS_ooxml::LN_starmath:
740             m_pImpl->appendStarMath( val );
741             break;
742         case NS_ooxml::LN_CT_FramePr_dropCap:
743         case NS_ooxml::LN_CT_FramePr_lines:
744         case NS_ooxml::LN_CT_FramePr_hAnchor:
745         case NS_ooxml::LN_CT_FramePr_vAnchor:
746         case NS_ooxml::LN_CT_FramePr_x:
747         case NS_ooxml::LN_CT_FramePr_xAlign:
748         case NS_ooxml::LN_CT_FramePr_y:
749         case NS_ooxml::LN_CT_FramePr_yAlign:
750         case NS_ooxml::LN_CT_FramePr_hRule:
751         case NS_ooxml::LN_CT_FramePr_w:
752         case NS_ooxml::LN_CT_FramePr_h:
753         case NS_ooxml::LN_CT_FramePr_wrap:
754         case NS_ooxml::LN_CT_FramePr_hSpace:
755         case NS_ooxml::LN_CT_FramePr_vSpace:
756         {
757             ParagraphProperties* pParaProperties = nullptr;
758             // handle frame properties at styles
759             if( m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET )
760                 pParaProperties = dynamic_cast< ParagraphProperties*>( m_pImpl->GetTopContextOfType( CONTEXT_STYLESHEET ).get() );
761             else
762                 pParaProperties = dynamic_cast< ParagraphProperties*>( m_pImpl->GetTopContextOfType( CONTEXT_PARAGRAPH ).get() );
763 
764             if( pParaProperties )
765             {
766                 switch( nName )
767                 {
768                     case NS_ooxml::LN_CT_FramePr_dropCap:
769                         pParaProperties->SetDropCap( nIntValue );
770                     break;
771                     case NS_ooxml::LN_CT_FramePr_lines:
772                         pParaProperties->SetLines( nIntValue );
773                     break;
774                     case NS_ooxml::LN_CT_FramePr_hAnchor:
775                         switch(nIntValue)
776                         {
777                             case  NS_ooxml::LN_Value_doc_ST_HAnchor_text:   //relative to column
778                                 nIntValue = text::RelOrientation::FRAME; break;
779                             case  NS_ooxml::LN_Value_doc_ST_HAnchor_margin: nIntValue = text::RelOrientation::PAGE_PRINT_AREA; break;
780                             case  NS_ooxml::LN_Value_doc_ST_HAnchor_page:   nIntValue = text::RelOrientation::PAGE_FRAME; break;
781                             default:;
782                         }
783                         pParaProperties->SethAnchor( nIntValue );
784                     break;
785                     case NS_ooxml::LN_CT_FramePr_vAnchor:
786                         switch(nIntValue)
787                         {
788                             case  NS_ooxml::LN_Value_doc_ST_VAnchor_text:  //relative to paragraph
789                                     nIntValue = text::RelOrientation::FRAME; break;
790                             case  NS_ooxml::LN_Value_doc_ST_VAnchor_margin:nIntValue = text::RelOrientation::PAGE_PRINT_AREA ; break;
791                             case  NS_ooxml::LN_Value_doc_ST_VAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
792                             default:;
793                         }
794                         pParaProperties->SetvAnchor( nIntValue );
795                     break;
796                     case NS_ooxml::LN_CT_FramePr_x:
797                         pParaProperties->Setx( ConversionHelper::convertTwipToMM100(nIntValue ));
798                         pParaProperties->SetxAlign( text::HoriOrientation::NONE );
799                     break;
800                     case NS_ooxml::LN_CT_FramePr_xAlign:
801                         switch( nIntValue )
802                         {
803                             case  NS_ooxml::LN_Value_doc_ST_XAlign_center  : nIntValue = text::HoriOrientation::CENTER; break;
804                             case  NS_ooxml::LN_Value_doc_ST_XAlign_right   : nIntValue = text::HoriOrientation::RIGHT; break;
805                             case  NS_ooxml::LN_Value_doc_ST_XAlign_inside  : nIntValue = text::HoriOrientation::INSIDE; break;
806                             case  NS_ooxml::LN_Value_doc_ST_XAlign_outside : nIntValue = text::HoriOrientation::OUTSIDE; break;
807                             case  NS_ooxml::LN_Value_doc_ST_XAlign_left    : nIntValue = text::HoriOrientation::LEFT; break;
808                             default:    nIntValue = text::HoriOrientation::NONE;
809                         }
810                         pParaProperties->SetxAlign( nIntValue );
811                     break;
812                     case NS_ooxml::LN_CT_FramePr_y:
813                         pParaProperties->Sety( ConversionHelper::convertTwipToMM100(nIntValue ));
814                         pParaProperties->SetyAlign( text::VertOrientation::NONE );
815                     break;
816                     case NS_ooxml::LN_CT_FramePr_yAlign:
817                         switch( nIntValue )
818                         {
819                             case  NS_ooxml::LN_Value_doc_ST_YAlign_top     :
820                             case  NS_ooxml::LN_Value_doc_ST_YAlign_inside  :nIntValue = text::VertOrientation::TOP; break;
821                             case  NS_ooxml::LN_Value_doc_ST_YAlign_center  :nIntValue = text::VertOrientation::CENTER;break;
822                             case  NS_ooxml::LN_Value_doc_ST_YAlign_bottom  :
823                             case  NS_ooxml::LN_Value_doc_ST_YAlign_outside :nIntValue = text::VertOrientation::BOTTOM;break;
824                             case  NS_ooxml::LN_Value_doc_ST_YAlign_inline  :
825                             {
826                             // HACK: This is for bnc#780851, where a table has one cell that has w:framePr,
827                             // which causes that paragraph to be converted to a text frame, and the original
828                             // paragraph object no longer exists, which makes table creation fail and furthermore
829                             // it would be missing in the table layout anyway. So actually no letting that paragraph
830                             // be a text frame "fixes" it. I'm not sure what "inline" is supposed to mean in practice
831                             // anyway, so as long as this doesn't cause trouble elsewhere ...
832                                 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
833                                 if( pContext.get() )
834                                 {
835                                     ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
836                                     if (pParaContext)
837                                         pParaContext->SetFrameMode(false);
838                                 }
839                                 nIntValue = text::VertOrientation::NONE;
840                                 break;
841                             }
842                             default:
843                                 nIntValue = text::VertOrientation::NONE;
844                                 break;
845                         }
846                         pParaProperties->SetyAlign( nIntValue );
847                     break;
848                     case NS_ooxml::LN_CT_FramePr_hRule:
849                          switch( nIntValue )
850                          {
851                             case NS_ooxml::LN_Value_doc_ST_HeightRule_exact:
852                                 nIntValue = text::SizeType::FIX;
853                             break;
854                             case NS_ooxml::LN_Value_doc_ST_HeightRule_atLeast:
855                                 nIntValue = text::SizeType::MIN;
856                             break;
857                             case NS_ooxml::LN_Value_doc_ST_HeightRule_auto:
858                             //no break;
859                             default:;
860                                 nIntValue = text::SizeType::VARIABLE;
861                          }
862                         pParaProperties->SethRule( nIntValue );
863                     break;
864                     case NS_ooxml::LN_CT_FramePr_wrap:
865                     {
866                         //should be either LN_Value_doc_ST_Wrap_notBeside or LN_Value_doc_ST_Wrap_around or LN_Value_doc_ST_Wrap_auto
867                         OSL_ENSURE( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
868                                     sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_notBeside ||
869                                     sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
870                                     sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none ||
871                                     sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto,
872                             "wrap not around, not_Beside, through, none or auto?");
873                         if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
874                             sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
875                             sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto )
876                             pParaProperties->SetWrap ( text::WrapTextMode_DYNAMIC ) ;
877                         else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none)
878                             pParaProperties->SetWrap ( text::WrapTextMode_THROUGH ) ;
879                         else
880                             pParaProperties->SetWrap ( text::WrapTextMode_NONE ) ;
881                     }
882                     break;
883                     case NS_ooxml::LN_CT_FramePr_w:
884                         pParaProperties->Setw(ConversionHelper::convertTwipToMM100(nIntValue));
885                     break;
886                     case NS_ooxml::LN_CT_FramePr_h:
887                         pParaProperties->Seth(ConversionHelper::convertTwipToMM100(nIntValue));
888                     break;
889                     case NS_ooxml::LN_CT_FramePr_hSpace:
890                         pParaProperties->SethSpace( ConversionHelper::convertTwipToMM100(nIntValue ));
891                     break;
892                     case NS_ooxml::LN_CT_FramePr_vSpace:
893                         pParaProperties->SetvSpace( ConversionHelper::convertTwipToMM100(nIntValue ));
894                     break;
895                     default:;
896                 }
897             }
898         }
899         break;
900         case NS_ooxml::LN_CT_TrackChange_author:
901             m_pImpl->SetCurrentRedlineAuthor( sStringValue );
902         break;
903         case NS_ooxml::LN_CT_TrackChange_date:
904             m_pImpl->SetCurrentRedlineDate( sStringValue );
905         break;
906         case NS_ooxml::LN_CT_Markup_id:
907             m_pImpl->SetCurrentRedlineId( nIntValue );
908         break;
909         case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart:
910             m_pImpl->AddAnnotationPosition( true, nIntValue );
911         break;
912         case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd:
913             m_pImpl->AddAnnotationPosition( false, nIntValue );
914         break;
915         case NS_ooxml::LN_CT_Comment_initials:
916             m_pImpl->SetCurrentRedlineInitials(sStringValue);
917         break;
918         case NS_ooxml::LN_token:
919             m_pImpl->SetCurrentRedlineToken( nIntValue );
920         break;
921         case NS_ooxml::LN_CT_LineNumber_start:
922         case NS_ooxml::LN_CT_LineNumber_distance:
923         case NS_ooxml::LN_CT_LineNumber_countBy:
924         case NS_ooxml::LN_CT_LineNumber_restart:
925         {
926             //line numbering in Writer is a global document setting
927             //in Word is a section setting
928             //if line numbering is switched on anywhere in the document it's set at the global settings
929             LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
930             switch( nName )
931             {
932                 case NS_ooxml::LN_CT_LineNumber_countBy:
933                     aSettings.nInterval = nIntValue;
934                     OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
935                     if( pSectionContext )
936                         pSectionContext->SetLnnMod( nIntValue );
937                 break;
938                 case NS_ooxml::LN_CT_LineNumber_start:
939                     OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
940                     if( pSectionContext )
941                         pSectionContext->SetLnnMin( nIntValue );
942                 break;
943                 case NS_ooxml::LN_CT_LineNumber_distance:
944                     aSettings.nDistance = ConversionHelper::convertTwipToMM100( nIntValue );
945                     OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
946                     if( pSectionContext )
947                         pSectionContext->SetdxaLnn( nIntValue );
948                 break;
949                 case NS_ooxml::LN_CT_LineNumber_restart:
950                     aSettings.bRestartAtEachPage = nIntValue == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_LineNumberRestart_newPage);
951                     OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
952                     if( pSectionContext )
953                         pSectionContext->SetLnc( nIntValue );
954                 break;
955                 default:;
956             }
957             m_pImpl->SetLineNumberSettings( aSettings );
958         }
959         break;
960         case NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows:
961             m_pImpl->StartCustomFootnote(m_pImpl->GetTopContext());
962         break;
963         case NS_ooxml::LN_CT_FtnEdnRef_id:
964             // footnote or endnote reference id - not needed
965         break;
966         case NS_ooxml::LN_CT_Color_themeColor:
967             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeColor", TDefTableHandler::getThemeColorTypeString(nIntValue));
968         break;
969         case NS_ooxml::LN_CT_Color_themeTint:
970             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeTint", OUString::number(nIntValue, 16));
971         break;
972         case NS_ooxml::LN_CT_Color_themeShade:
973             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeShade", OUString::number(nIntValue, 16));
974         break;
975         case NS_ooxml::LN_CT_DocGrid_linePitch:
976         {
977             //see SwWW8ImplReader::SetDocumentGrid
978             OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
979             if(pSectionContext)
980             {
981                 pSectionContext->SetGridLinePitch( ConversionHelper::convertTwipToMM100( nIntValue ) );
982             }
983         }
984         break;
985         case NS_ooxml::LN_CT_DocGrid_charSpace:
986         {
987             OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
988             if(pSectionContext)
989             {
990                 pSectionContext->SetDxtCharSpace( nIntValue );
991             }
992         }
993         break;
994         case NS_ooxml::LN_CT_DocGrid_type:
995         {
996             if (pSectionContext != nullptr)
997             {
998                 switch( nIntValue )
999                 {
1000                     case NS_ooxml::LN_Value_doc_ST_DocGrid_default:
1001                         pSectionContext->SetGridType(text::TextGridMode::NONE);
1002                         break;
1003                     case NS_ooxml::LN_Value_doc_ST_DocGrid_lines:
1004                         pSectionContext->SetGridType(text::TextGridMode::LINES);
1005                         break;
1006                     case NS_ooxml::LN_Value_doc_ST_DocGrid_linesAndChars:
1007                         pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
1008                         pSectionContext->SetGridSnapToChars( false );
1009                         break;
1010                     case NS_ooxml::LN_Value_doc_ST_DocGrid_snapToChars:
1011                         pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
1012                         pSectionContext->SetGridSnapToChars( true );
1013                         break;
1014                     default :
1015                         OSL_FAIL("unknown SwTextGrid value");
1016                 }
1017             }
1018         }
1019         break;
1020         case NS_ooxml::LN_CT_SdtBlock_sdtContent:
1021             m_pImpl->SetSdt(true);
1022         break;
1023         case NS_ooxml::LN_CT_SdtBlock_sdtEndContent:
1024             m_pImpl->SetSdt(false);
1025 
1026             // It's not possible to insert the relevant property to the character context here:
1027             // the previous, already sent character context may be still active, so the property would be lost.
1028             if (m_pImpl->m_pSdtHelper->isOutsideAParagraph())
1029                 m_pImpl->setParaSdtEndDeferred(true);
1030             else
1031                 m_pImpl->setSdtEndDeferred(true);
1032 
1033             if (m_pImpl->m_pSdtHelper->isInsideDropDownControl())
1034                 m_pImpl->m_pSdtHelper->createDropDownControl();
1035             else if (m_pImpl->m_pSdtHelper->validateDateFormat())
1036                 m_pImpl->m_pSdtHelper->createDateContentControl();
1037         break;
1038         case NS_ooxml::LN_CT_SdtListItem_displayText:
1039             // TODO handle when this is != value
1040         break;
1041         case NS_ooxml::LN_CT_SdtListItem_value:
1042             m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue);
1043         break;
1044         case NS_ooxml::LN_CT_SdtDate_fullDate:
1045             m_pImpl->m_pSdtHelper->getDate().append(sStringValue);
1046         break;
1047         case NS_ooxml::LN_CT_Background_color:
1048             if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape())
1049                 m_pImpl->m_oBackgroundColor = nIntValue;
1050         break;
1051         case NS_ooxml::LN_CT_PageNumber_start:
1052             if (pSectionContext != nullptr)
1053                 pSectionContext->SetPageNumber(nIntValue);
1054         break;
1055         case NS_ooxml::LN_CT_PageNumber_fmt:
1056             if (pSectionContext)
1057             {
1058                 switch (nIntValue)
1059                 {
1060                 case NS_ooxml::LN_Value_ST_NumberFormat_decimal:
1061                     // 1, 2, ...
1062                     pSectionContext->SetPageNumberType(style::NumberingType::ARABIC);
1063                 break;
1064                 case NS_ooxml::LN_Value_ST_NumberFormat_upperLetter:
1065                     // A, B, ...
1066                     pSectionContext->SetPageNumberType(style::NumberingType::CHARS_UPPER_LETTER_N);
1067                 break;
1068                 case NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter:
1069                     // a, b, ...
1070                     pSectionContext->SetPageNumberType(style::NumberingType::CHARS_LOWER_LETTER_N);
1071                 break;
1072                 case NS_ooxml::LN_Value_ST_NumberFormat_upperRoman:
1073                     // I, II, ...
1074                     pSectionContext->SetPageNumberType(style::NumberingType::ROMAN_UPPER);
1075                 break;
1076                 case NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman:
1077                     // i, ii, ...
1078                     pSectionContext->SetPageNumberType(style::NumberingType::ROMAN_LOWER);
1079                 break;
1080                 }
1081             }
1082         break;
1083         case NS_ooxml::LN_CT_FtnEdn_type:
1084             // This is the "separator" footnote, ignore its linebreaks/text.
1085             if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator)
1086                 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::ON );
1087             else
1088                 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
1089         break;
1090         case NS_ooxml::LN_CT_FtnEdn_id:
1091         {
1092             SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
1093             if ( eSkip == SkipFootnoteSeparator::ON )
1094                 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
1095             else if ( eSkip == SkipFootnoteSeparator::SKIPPING )
1096                 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
1097         }
1098         break;
1099         case NS_ooxml::LN_CT_DataBinding_prefixMappings:
1100             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_prefixMappings", sStringValue);
1101             break;
1102         case NS_ooxml::LN_CT_DataBinding_xpath:
1103             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_xpath", sStringValue);
1104             break;
1105         case NS_ooxml::LN_CT_DataBinding_storeItemID:
1106             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_storeItemID", sStringValue);
1107             break;
1108         case NS_ooxml::LN_CT_PTab_leader:
1109         case NS_ooxml::LN_CT_PTab_relativeTo:
1110         case NS_ooxml::LN_CT_PTab_alignment:
1111             break;
1112         case NS_ooxml::LN_CT_Cnf_lastRowLastColumn:
1113             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowLastColumn", OUString::number(nIntValue));
1114             break;
1115         case NS_ooxml::LN_CT_Cnf_lastRowFirstColumn:
1116             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowFirstColumn", OUString::number(nIntValue));
1117             break;
1118         case NS_ooxml::LN_CT_Cnf_firstRowLastColumn:
1119             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowLastColumn", OUString::number(nIntValue));
1120             break;
1121         case NS_ooxml::LN_CT_Cnf_oddHBand:
1122             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddHBand", OUString::number(nIntValue));
1123             break;
1124         case NS_ooxml::LN_CT_Cnf_firstRowFirstColumn:
1125             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowFirstColumn", OUString::number(nIntValue));
1126             break;
1127         case NS_ooxml::LN_CT_Cnf_evenVBand:
1128             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenVBand", OUString::number(nIntValue));
1129             break;
1130         case NS_ooxml::LN_CT_Cnf_evenHBand:
1131             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenHBand", OUString::number(nIntValue));
1132             break;
1133         case NS_ooxml::LN_CT_Cnf_lastColumn:
1134             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastColumn", OUString::number(nIntValue));
1135             break;
1136         case NS_ooxml::LN_CT_Cnf_firstColumn:
1137             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstColumn", OUString::number(nIntValue));
1138             break;
1139         case NS_ooxml::LN_CT_Cnf_oddVBand:
1140             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddVBand", OUString::number(nIntValue));
1141             break;
1142         case NS_ooxml::LN_CT_Cnf_lastRow:
1143             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRow", OUString::number(nIntValue));
1144             break;
1145         case NS_ooxml::LN_CT_Cnf_firstRow:
1146             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRow", OUString::number(nIntValue));
1147             break;
1148         case NS_ooxml::LN_CT_Cnf_val:
1149             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "val", sStringValue);
1150             break;
1151         case NS_ooxml::LN_CT_DocPartName_val:
1152         {
1153             m_sGlossaryEntryName = sStringValue;
1154             break;
1155         }
1156         case NS_ooxml::LN_CT_DocPartGallery_val:
1157         {
1158             const OUString& sGlossaryEntryGallery = sStringValue;
1159             if(m_pImpl->GetTopContext().get())
1160             {
1161                 OUString sName = sGlossaryEntryGallery + ":" + m_sGlossaryEntryName;
1162                 // Add glossary entry name as a first paragraph in section
1163                 m_pImpl->appendTextPortion(sName, m_pImpl->GetTopContext());
1164             }
1165             break;
1166         }
1167         case NS_ooxml::LN_CT_PermStart_ed:
1168         {
1169             m_pImpl->setPermissionRangeEd(sStringValue);
1170             break;
1171         }
1172         case NS_ooxml::LN_CT_PermStart_edGrp:
1173         {
1174             m_pImpl->setPermissionRangeEdGrp(sStringValue);
1175             break;
1176         }
1177         case NS_ooxml::LN_CT_PermStart_id:
1178         {
1179             m_pImpl->startOrEndPermissionRange(nIntValue);
1180             break;
1181         }
1182         case NS_ooxml::LN_CT_PermEnd_id:
1183         {
1184             m_pImpl->startOrEndPermissionRange(nIntValue);
1185             break;
1186         }
1187         default:
1188             SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName);
1189     }
1190 }
1191 
lcl_sprm(Sprm & rSprm)1192 void DomainMapper::lcl_sprm(Sprm & rSprm)
1193 {
1194     if (!m_pImpl->hasTableManager() || !m_pImpl->getTableManager().sprm(rSprm))
1195         sprmWithProps(rSprm, m_pImpl->GetTopContext());
1196 }
1197 
1198 // In rtl-paragraphs the meaning of left/right are to be exchanged
ExchangeLeftRight(const PropertyMapPtr & rContext,DomainMapper_Impl & rImpl)1199 static bool ExchangeLeftRight(const PropertyMapPtr& rContext, DomainMapper_Impl& rImpl)
1200 {
1201     bool bExchangeLeftRight = false;
1202     sal_Int32 aAdjust;
1203     uno::Any aPropPara = rImpl.GetAnyProperty(PROP_WRITING_MODE, rContext);
1204     if( (aPropPara >>= aAdjust) && aAdjust == text::WritingMode2::RL_TB )
1205         bExchangeLeftRight = true;
1206     return bExchangeLeftRight;
1207 }
1208 
sprmWithProps(Sprm & rSprm,const PropertyMapPtr & rContext)1209 void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
1210 {
1211     // These SPRM's are not specific to any section, so it's expected that there is no context yet.
1212     switch (rSprm.getId())
1213     {
1214     case NS_ooxml::LN_background_background:
1215         return;
1216         break;
1217     default:
1218         break;
1219     }
1220 
1221     OSL_ENSURE(rContext.get(), "PropertyMap has to be valid!");
1222     if(!rContext.get())
1223         return ;
1224 
1225     sal_uInt32 nSprmId = rSprm.getId();
1226     //needed for page properties
1227     SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
1228     Value::Pointer_t pValue = rSprm.getValue();
1229     sal_Int32 nIntValue = pValue->getInt();
1230     const OUString sStringValue = pValue->getString();
1231 
1232     switch(nSprmId)
1233     {
1234     case NS_ooxml::LN_CT_PPrBase_jc:
1235     {
1236         bool bExchangeLeftRight = !IsRTFImport() && ExchangeLeftRight(rContext, *m_pImpl);
1237         handleParaJustification(nIntValue, rContext, bExchangeLeftRight);
1238         break;
1239     }
1240     case NS_ooxml::LN_CT_PPrBase_keepLines:
1241         rContext->Insert(PROP_PARA_SPLIT, uno::makeAny(nIntValue == 0));
1242         break;
1243     case NS_ooxml::LN_CT_PPrBase_keepNext:
1244         rContext->Insert(PROP_PARA_KEEP_TOGETHER, uno::makeAny( nIntValue != 0 ) );
1245         break;
1246     case NS_ooxml::LN_CT_PPrBase_pageBreakBefore:
1247         rContext->Insert(PROP_BREAK_TYPE, uno::makeAny(nIntValue ? style::BreakType_PAGE_BEFORE : style::BreakType_NONE));
1248     break;
1249     case NS_ooxml::LN_CT_NumPr_ilvl:
1250             if (nIntValue < 0 || 10 <= nIntValue) // Writer can't do everything
1251             {
1252                 SAL_INFO("writerfilter",
1253                         "unsupported numbering level " << nIntValue);
1254                 break;
1255             }
1256             if( IsStyleSheetImport() )
1257             {
1258                 //style sheets cannot have a numbering rule attached
1259                 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1260                 if (pStyleSheetPropertyMap)
1261                     pStyleSheetPropertyMap->SetListLevel( static_cast<sal_Int16>(nIntValue) );
1262             }
1263             else
1264                 rContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny( static_cast<sal_Int16>(nIntValue) ));
1265         break;
1266     case NS_ooxml::LN_CT_NumPr_numId:
1267         {
1268             //convert the ListTable entry to a NumberingRules property and apply it
1269             ListsManager::Pointer pListTable = m_pImpl->GetListTable();
1270             ListDef::Pointer pList = pListTable->GetList( nIntValue );
1271             if( IsStyleSheetImport() )
1272             {
1273                 //style sheets cannot have a numbering rule attached
1274                 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1275                 if (pStyleSheetPropertyMap)
1276                     pStyleSheetPropertyMap->SetListId( nIntValue );
1277             }
1278             if( pList.get( ) )
1279             {
1280                 if( !IsStyleSheetImport() )
1281                 {
1282                     uno::Any aRules = uno::makeAny( pList->GetNumberingRules( ) );
1283                     rContext->Insert( PROP_NUMBERING_RULES, aRules );
1284                     PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
1285                     if (pContext)
1286                     {
1287                         assert(dynamic_cast<ParagraphPropertyMap*>(pContext.get()));
1288                         static_cast<ParagraphPropertyMap*>(pContext.get())->SetListId(pList->GetId());
1289                     }
1290                     // erase numbering from pStyle if already set
1291                     rContext->Erase(PROP_NUMBERING_STYLE_NAME);
1292 
1293                     // Indentation can came from:
1294                     // 1) Paragraph style's numbering's indentation: the current non-style numId has priority over it.
1295                     // 2) Numbering's indentation: Writer handles that natively, so it should not be set on rContext.
1296                     // 3) Paragraph style's indentation: ditto.
1297                     // 4) Direct paragraph formatting: that will came later.
1298                     // So no situation where keeping indentation at this point would make sense -> erase.
1299                     rContext->Erase(PROP_PARA_FIRST_LINE_INDENT);
1300                     rContext->Erase(PROP_PARA_LEFT_MARGIN);
1301                     rContext->Erase(PROP_PARA_RIGHT_MARGIN);
1302                 }
1303             }
1304             else
1305             {
1306                 if( IsStyleSheetImport() )
1307                 {
1308                     // set the number id for AbstractNum references
1309                     StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1310                     if (pStyleSheetPropertyMap)
1311                         pStyleSheetPropertyMap->SetNumId( nIntValue );
1312                 }
1313                 else
1314                 {
1315                     // eg. disabled numbering using non-existent numId "0"
1316                     rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( OUString() ) );
1317                     // disable inheritance of indentation of parent styles
1318                     rContext->Insert( PROP_PARA_LEFT_MARGIN, uno::makeAny( sal_Int32(0) ), /*bOverwrite=*/false);
1319                     rContext->Insert( PROP_PARA_FIRST_LINE_INDENT,
1320                                                  uno::makeAny( sal_Int32(0) ), /*bOverwrite=*/false);
1321                 }
1322             }
1323         }
1324         break;
1325     case NS_ooxml::LN_CT_PPrBase_suppressLineNumbers:
1326         rContext->Insert(PROP_PARA_LINE_NUMBER_COUNT, uno::makeAny( nIntValue == 0 ) );
1327         break;
1328     case NS_ooxml::LN_inTbl:
1329         break;
1330     case NS_ooxml::LN_tblDepth:
1331         //not handled via sprm but via text( 0x07 )
1332     break;
1333     case NS_ooxml::LN_CT_FramePr_w:
1334         break;
1335     case NS_ooxml::LN_CT_FramePr_wrap:
1336         break;
1337 
1338     case NS_ooxml::LN_CT_PrBase_pBdr: //paragraph border
1339         resolveSprmProps(*this, rSprm);
1340     break;
1341     case NS_ooxml::LN_CT_PBdr_top:
1342     case NS_ooxml::LN_CT_PBdr_left:
1343     case NS_ooxml::LN_CT_PBdr_bottom:
1344     case NS_ooxml::LN_CT_PBdr_right:
1345     case NS_ooxml::LN_CT_PBdr_between:
1346     {
1347         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1348         if( pProperties.get())
1349         {
1350             std::shared_ptr<BorderHandler> pBorderHandler( new BorderHandler( true ) );
1351             pProperties->resolve(*pBorderHandler);
1352             PropertyIds eBorderId = PropertyIds( 0 );
1353             PropertyIds eBorderDistId = PropertyIds( 0 );
1354             switch( nSprmId )
1355             {
1356             case NS_ooxml::LN_CT_PBdr_top:
1357                 eBorderId = PROP_TOP_BORDER;
1358                 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
1359                 break;
1360             case NS_ooxml::LN_CT_PBdr_left:
1361                 eBorderId = PROP_LEFT_BORDER;
1362                 eBorderDistId = PROP_LEFT_BORDER_DISTANCE;
1363                 break;
1364             case NS_ooxml::LN_CT_PBdr_bottom:
1365                 eBorderId = PROP_BOTTOM_BORDER         ;
1366                 eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE;
1367                 break;
1368             case NS_ooxml::LN_CT_PBdr_right:
1369                 eBorderId = PROP_RIGHT_BORDER;
1370                 eBorderDistId = PROP_RIGHT_BORDER_DISTANCE ;
1371                 break;
1372             case NS_ooxml::LN_CT_PBdr_between:
1373                 //not supported
1374                 break;
1375             default:;
1376             }
1377             if( eBorderId )
1378                 rContext->Insert( eBorderId, uno::makeAny( pBorderHandler->getBorderLine()) );
1379             if(eBorderDistId)
1380                 rContext->Insert(eBorderDistId, uno::makeAny( pBorderHandler->getLineDistance()));
1381             if (nSprmId == NS_ooxml::LN_CT_PBdr_right && pBorderHandler->getShadow())
1382             {
1383                 table::ShadowFormat aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
1384                 rContext->Insert(PROP_PARA_SHADOW_FORMAT, uno::makeAny(aFormat));
1385             }
1386         }
1387     }
1388     break;
1389     case NS_ooxml::LN_CT_PBdr_bar:
1390         break;
1391     case NS_ooxml::LN_CT_PPrBase_suppressAutoHyphens:
1392         rContext->Insert(PROP_PARA_IS_HYPHENATION, uno::makeAny( nIntValue == 0 ));
1393         break;
1394     case NS_ooxml::LN_CT_FramePr_h:
1395         break;
1396     case NS_ooxml::LN_CT_PrBase_shd:
1397     {
1398         //contains fore color, back color and shadow percentage, results in a brush
1399         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1400         if( pProperties.get())
1401         {
1402             std::shared_ptr<CellColorHandler> pCellColorHandler( new CellColorHandler );
1403             pCellColorHandler->setOutputFormat( CellColorHandler::Paragraph );
1404             bool bEnableTempGrabBag = !pCellColorHandler->isInteropGrabBagEnabled();
1405             if( bEnableTempGrabBag )
1406                 pCellColorHandler->enableInteropGrabBag( "TempShdPropsGrabBag" );
1407 
1408             pProperties->resolve(*pCellColorHandler);
1409             rContext->InsertProps(pCellColorHandler->getProperties().get());
1410 
1411             rContext->Insert(PROP_CHAR_THEME_FILL,  pCellColorHandler->getInteropGrabBag().Value, true, PARA_GRAB_BAG);
1412             if(bEnableTempGrabBag)
1413                 pCellColorHandler->disableInteropGrabBag();
1414         }
1415     }
1416     break;
1417     case NS_ooxml::LN_CT_FramePr_vSpace:
1418         break;  // sprmPDyaFromText
1419     case NS_ooxml::LN_CT_FramePr_hSpace:
1420         break;  // sprmPDxaFromText
1421     case NS_ooxml::LN_CT_FramePr_anchorLock:
1422         break;
1423     case NS_ooxml::LN_CT_PPrBase_widowControl:
1424     {
1425         uno::Any aVal( uno::makeAny( sal_Int8(nIntValue ? 2 : 0 )));
1426         rContext->Insert( PROP_PARA_WIDOWS, aVal );
1427         rContext->Insert( PROP_PARA_ORPHANS, aVal );
1428     }
1429     break;  // sprmPFWidowControl
1430     case NS_ooxml::LN_CT_PPrBase_overflowPunct:
1431         rContext->Insert(PROP_PARA_IS_HANGING_PUNCTUATION, uno::makeAny( nIntValue == 0 ));
1432         break;
1433     case NS_ooxml::LN_CT_PPrBase_topLinePunct:
1434         break;
1435     case NS_ooxml::LN_CT_PPrBase_autoSpaceDE:
1436         break;
1437     case NS_ooxml::LN_CT_PPrBase_autoSpaceDN:
1438         break;
1439     case NS_ooxml::LN_CT_PPrBase_textAlignment:
1440         {
1441             sal_Int16 nAlignment = 0;
1442             switch (nIntValue)
1443             {
1444                 case NS_ooxml::LN_Value_doc_ST_TextAlignment_top:
1445                     nAlignment = 2;
1446                     break;
1447                 case NS_ooxml::LN_Value_doc_ST_TextAlignment_center:
1448                     nAlignment = 3;
1449                     break;
1450                 case NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline:
1451                     nAlignment = 1;
1452                     break;
1453                 case NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom:
1454                     nAlignment = 4;
1455                     break;
1456                 case NS_ooxml::LN_Value_doc_ST_TextAlignment_auto:
1457                 default:
1458                     break;
1459             }
1460             rContext->Insert( PROP_PARA_VERT_ALIGNMENT, uno::makeAny( nAlignment) );
1461         }
1462         break;
1463     case NS_ooxml::LN_CT_PPrBase_textDirection:
1464         break;
1465     case NS_ooxml::LN_CT_PPrBase_outlineLvl:
1466         {
1467             sal_Int16 nLvl = static_cast< sal_Int16 >( nIntValue );
1468             if( IsStyleSheetImport() )
1469             {
1470 
1471                 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1472                 if (pStyleSheetPropertyMap)
1473                     pStyleSheetPropertyMap->SetOutlineLevel( nLvl );
1474             }
1475             else
1476             {
1477                 nLvl = nLvl >= WW_OUTLINE_MIN && nLvl < WW_OUTLINE_MAX? nLvl+1 : 0; //0 means no outline level set on
1478                 rContext->Insert(PROP_OUTLINE_LEVEL, uno::makeAny ( nLvl ));
1479             }
1480         }
1481         break;
1482     case NS_ooxml::LN_CT_PPrBase_bidi:
1483         {
1484             // Four situations to handle:
1485             // 1.) bidi same as previous setting: no adjust change
1486             // 2.) no previous adjust: set appropriate default for this bidi
1487             // 3.) previous adjust and bidi different from previous: swap adjusts
1488             // 4.) previous adjust and no previous bidi: RTL swaps adjust
1489 
1490             const sal_Int16 nWritingMode = nIntValue ? text::WritingMode2::RL_TB : text::WritingMode2::LR_TB;
1491             sal_Int16 nParentBidi = -1;
1492             m_pImpl->GetPropertyFromParaStyleSheet(PROP_WRITING_MODE) >>= nParentBidi;
1493             // Paragraph justification reverses its meaning in an RTL context.
1494             // 1. Only make adjustments if the BiDi changes.
1495             if ( nParentBidi != nWritingMode && !IsRTFImport() )
1496             {
1497                 style::ParagraphAdjust eAdjust = style::ParagraphAdjust(-1);
1498                 // 2. no adjust property exists yet
1499                 if ( !(m_pImpl->GetAnyProperty(PROP_PARA_ADJUST, rContext) >>= eAdjust) )
1500                 {
1501                     // RTL defaults to right adjust
1502                     eAdjust = nIntValue ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
1503                     rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( eAdjust ), /*bOverwrite=*/false);
1504                 }
1505                 // 3,4. existing adjust: if RTL, then swap. If LTR, but previous was RTL, also swap.
1506                 else if ( nIntValue || nParentBidi == sal_Int16(text::WritingMode2::RL_TB) )
1507                 {
1508                     if ( eAdjust == style::ParagraphAdjust_RIGHT )
1509                         rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( style::ParagraphAdjust_LEFT ));
1510                     else if ( eAdjust == style::ParagraphAdjust_LEFT )
1511                         rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( style::ParagraphAdjust_RIGHT ));
1512                 }
1513             }
1514             rContext->Insert(PROP_WRITING_MODE, uno::makeAny( nWritingMode ));
1515         }
1516 
1517         break;
1518     case NS_ooxml::LN_EG_SectPrContents_bidi:
1519         if (pSectionContext != nullptr)
1520         {
1521             const sal_Int16 writingMode = (nIntValue != 0) ? sal_Int16(text::WritingMode2::RL_TB) : sal_Int16(text::WritingMode2::LR_TB);
1522             pSectionContext->Insert(PROP_WRITING_MODE, uno::makeAny(writingMode));
1523         }
1524         break;
1525     case NS_ooxml::LN_EG_RPrBase_highlight:
1526         {
1527             // OOXML import uses an ID
1528             if( IsOOXMLImport() )
1529             {
1530                 sal_Int32 nColor = 0;
1531                 if( getColorFromId(nIntValue, nColor) )
1532                     rContext->Insert(PROP_CHAR_HIGHLIGHT, uno::makeAny( nColor ));
1533             }
1534             // RTF import uses the actual color value
1535             else if( IsRTFImport() )
1536             {
1537                 rContext->Insert(PROP_CHAR_HIGHLIGHT, uno::makeAny( nIntValue ));
1538             }
1539         }
1540         break;
1541     case NS_ooxml::LN_EG_RPrBase_em:
1542         rContext->Insert(PROP_CHAR_EMPHASIS, uno::makeAny ( getEmphasisValue (nIntValue)));
1543         break;
1544     case NS_ooxml::LN_EG_RPrBase_emboss:
1545     case NS_ooxml::LN_EG_RPrBase_b:
1546     case NS_ooxml::LN_EG_RPrBase_bCs:
1547     case NS_ooxml::LN_EG_RPrBase_i:
1548     case NS_ooxml::LN_EG_RPrBase_iCs:
1549     case NS_ooxml::LN_EG_RPrBase_strike:
1550     case NS_ooxml::LN_EG_RPrBase_dstrike:
1551     case NS_ooxml::LN_EG_RPrBase_outline:
1552     case NS_ooxml::LN_EG_RPrBase_shadow:
1553     case NS_ooxml::LN_EG_RPrBase_caps:
1554     case NS_ooxml::LN_EG_RPrBase_smallCaps:
1555     case NS_ooxml::LN_EG_RPrBase_vanish:
1556     case NS_ooxml::LN_EG_RPrBase_webHidden:
1557         {
1558             PropertyIds ePropertyId = PROP_CHAR_WEIGHT; //initialized to prevent warning!
1559             switch( nSprmId )
1560             {
1561             case NS_ooxml::LN_EG_RPrBase_b:
1562             case NS_ooxml::LN_EG_RPrBase_bCs:
1563                 ePropertyId = nSprmId != NS_ooxml::LN_EG_RPrBase_bCs ? PROP_CHAR_WEIGHT : PROP_CHAR_WEIGHT_COMPLEX;
1564                 break;
1565             case NS_ooxml::LN_EG_RPrBase_i:
1566             case NS_ooxml::LN_EG_RPrBase_iCs:
1567                 ePropertyId = nSprmId == NS_ooxml::LN_EG_RPrBase_i ? PROP_CHAR_POSTURE : PROP_CHAR_POSTURE_COMPLEX;
1568                 break;
1569             case NS_ooxml::LN_EG_RPrBase_strike:
1570             case NS_ooxml::LN_EG_RPrBase_dstrike:
1571                 ePropertyId = PROP_CHAR_STRIKEOUT;
1572                 break;
1573             case NS_ooxml::LN_EG_RPrBase_outline:
1574                 ePropertyId = PROP_CHAR_CONTOURED;
1575                 break;
1576             case NS_ooxml::LN_EG_RPrBase_shadow:
1577                 ePropertyId = PROP_CHAR_SHADOWED;
1578                 break;
1579             case NS_ooxml::LN_EG_RPrBase_caps:
1580             case NS_ooxml::LN_EG_RPrBase_smallCaps:
1581                 ePropertyId = PROP_CHAR_CASE_MAP;
1582                 break;
1583             case NS_ooxml::LN_EG_RPrBase_vanish:
1584             case NS_ooxml::LN_EG_RPrBase_webHidden:
1585                 ePropertyId = PROP_CHAR_HIDDEN;
1586                 break;
1587             case NS_ooxml::LN_EG_RPrBase_emboss:
1588                 ePropertyId = PROP_CHAR_RELIEF;
1589                 break;
1590             }
1591             //expected: 0,1,128,129
1592             if(nIntValue != 128) //inherited from paragraph - ignore
1593             {
1594                 if( nIntValue == 129) //inverted style sheet value
1595                 {
1596                     //get value from style sheet and invert it
1597                     sal_Int16 nStyleValue = 0;
1598                     uno::Any aStyleVal = m_pImpl->GetPropertyFromParaStyleSheet(ePropertyId);
1599                     if( !aStyleVal.hasValue() )
1600                     {
1601                         nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
1602                             4 : 1;
1603                     }
1604                     else if(aStyleVal.getValueTypeClass() == uno::TypeClass_FLOAT )
1605                     {
1606                         double fDoubleValue = 0;
1607                         //only in case of awt::FontWeight
1608                         aStyleVal >>= fDoubleValue;
1609                         nIntValue = fDoubleValue  > 100. ?  0 : 1;
1610                     }
1611                     else if((aStyleVal >>= nStyleValue) ||
1612                             (nStyleValue = static_cast<sal_Int16>(comphelper::getEnumAsINT32(aStyleVal))) >= 0 )
1613                     {
1614                         nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
1615                             nStyleValue ? 0 : 4 :
1616                             nStyleValue ? 0 : 1;
1617                     }
1618                     else
1619                     {
1620                         OSL_FAIL( "what type was it");
1621                     }
1622                 }
1623 
1624                 switch( nSprmId )
1625                 {
1626                     case NS_ooxml::LN_EG_RPrBase_b:
1627                     case NS_ooxml::LN_EG_RPrBase_bCs:
1628                     {
1629                         uno::Any aBold( uno::makeAny( nIntValue ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL ) );
1630 
1631                         rContext->Insert(ePropertyId, aBold );
1632                         if( nSprmId != NS_ooxml::LN_EG_RPrBase_bCs )
1633                             rContext->Insert(PROP_CHAR_WEIGHT_ASIAN, aBold );
1634 
1635                         uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle());
1636                         if (xCharStyle.is())
1637                             xCharStyle->setPropertyValue(getPropertyName(PROP_CHAR_WEIGHT), aBold);
1638                         if (nSprmId == NS_ooxml::LN_EG_RPrBase_b)
1639                             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "b", OUString::number(nIntValue));
1640                         else if (nSprmId == NS_ooxml::LN_EG_RPrBase_bCs)
1641                             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "bCs", OUString::number(nIntValue));
1642                     }
1643                     break;
1644                     case NS_ooxml::LN_EG_RPrBase_i:
1645                     case NS_ooxml::LN_EG_RPrBase_iCs:
1646                     {
1647                         uno::Any aPosture( uno::makeAny( nIntValue ? awt::FontSlant_ITALIC : awt::FontSlant_NONE ) );
1648                         rContext->Insert( ePropertyId, aPosture );
1649                         if (nSprmId != NS_ooxml::LN_EG_RPrBase_iCs)
1650                             rContext->Insert(PROP_CHAR_POSTURE_ASIAN, aPosture );
1651                         if (nSprmId == NS_ooxml::LN_EG_RPrBase_i)
1652                             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "i", OUString::number(nIntValue));
1653                     }
1654                     break;
1655                     case NS_ooxml::LN_EG_RPrBase_strike:
1656                         rContext->Insert(ePropertyId,
1657                                          uno::makeAny( nIntValue ? awt::FontStrikeout::SINGLE : awt::FontStrikeout::NONE ) );
1658                     break;
1659                     case NS_ooxml::LN_EG_RPrBase_dstrike:
1660                         rContext->Insert(ePropertyId,
1661                                          uno::makeAny( nIntValue ? awt::FontStrikeout::DOUBLE : awt::FontStrikeout::NONE ) );
1662                     break;
1663                     case NS_ooxml::LN_EG_RPrBase_outline:
1664                     case NS_ooxml::LN_EG_RPrBase_shadow:
1665                     case NS_ooxml::LN_EG_RPrBase_vanish:
1666                     case NS_ooxml::LN_EG_RPrBase_webHidden:
1667                         rContext->Insert(ePropertyId, uno::makeAny( nIntValue != 0 ));
1668                     break;
1669                     case NS_ooxml::LN_EG_RPrBase_smallCaps:
1670                         // If smallcaps would be just disabled and another casemap is already inserted, don't do anything.
1671                         if (nIntValue || !rContext->isSet(ePropertyId) )
1672                             rContext->Insert(ePropertyId, uno::makeAny( nIntValue ? style::CaseMap::SMALLCAPS : style::CaseMap::NONE));
1673                         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "smallCaps", OUString::number(nIntValue));
1674                     break;
1675                     case NS_ooxml::LN_EG_RPrBase_caps:
1676                         rContext->Insert(ePropertyId,
1677                                          uno::makeAny( nIntValue ? style::CaseMap::UPPERCASE : style::CaseMap::NONE));
1678                         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "caps", OUString::number(nIntValue));
1679                     break;
1680                     case NS_ooxml::LN_EG_RPrBase_emboss:
1681                         rContext->Insert(ePropertyId,
1682                                          uno::makeAny( nIntValue ? awt::FontRelief::EMBOSSED : awt::FontRelief::NONE ));
1683                     break;
1684 
1685                 }
1686             }
1687         }
1688         break;
1689     case NS_ooxml::LN_EG_RPrBase_sz:
1690     case NS_ooxml::LN_EG_RPrBase_szCs:
1691         {
1692             //multiples of half points (12pt == 24)
1693             double fVal = double(nIntValue) / 2.;
1694             uno::Any aVal = uno::makeAny( fVal );
1695             if( NS_ooxml::LN_EG_RPrBase_szCs == nSprmId )
1696             {
1697                 rContext->Insert( PROP_CHAR_HEIGHT_COMPLEX, aVal );
1698             }
1699             else
1700             {
1701                 bool bIgnore = false;
1702                 const   RubyInfo    &aInfo = m_pImpl->GetRubyInfo();
1703                 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt && aInfo.nHps > 0 )
1704                 {
1705                     fVal = double(aInfo.nHps) / 2.;
1706                     aVal <<= fVal;
1707                 }
1708                 else if (aInfo.nSprmId  == NS_ooxml::LN_CT_Ruby_rubyBase && aInfo.nHpsBaseText > 0 )
1709                 {
1710                     fVal = double(aInfo.nHpsBaseText) / 2.;
1711                     aVal <<= fVal;
1712                 }
1713                 else if (m_pImpl->m_bInTableStyleRunProps)
1714                 {
1715                     // If the default para style contains PROP_CHAR_HEIGHT, that should have priority over the table style.
1716                     StyleSheetEntryPtr pTable = m_pImpl->GetStyleSheetTable()->FindDefaultParaStyle();
1717                     if (pTable && pTable->pProperties->isSet(PROP_CHAR_HEIGHT) )
1718                         bIgnore = true;
1719                 }
1720                 if (!bIgnore)
1721                 {
1722                     //Asian get the same value as Western
1723                     rContext->Insert( PROP_CHAR_HEIGHT, aVal );
1724                     rContext->Insert( PROP_CHAR_HEIGHT_ASIAN, aVal );
1725 
1726                     uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle());
1727                     if (xCharStyle.is())
1728                         xCharStyle->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), aVal);
1729                 }
1730             }
1731             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, (nSprmId == NS_ooxml::LN_EG_RPrBase_sz ? OUString("sz") : OUString("szCs")), OUString::number(nIntValue));
1732         }
1733         break;
1734     case NS_ooxml::LN_EG_RPrBase_position:
1735         // The spec says 0 is the same as the lack of the value, so don't parse that.
1736         if ( nIntValue )
1737         {
1738             if ( !IsStyleSheetImport() )
1739                 m_pImpl->deferCharacterProperty( nSprmId, uno::makeAny( nIntValue ));
1740             else
1741             {
1742                 // DON'T FIXME: Truly calculating this for Character Styles will be tricky,
1743                 // because it depends on the final fontsize - regardless of
1744                 // where it is set. So at the style level,
1745                 // the escapement value would need to be grabbagged.
1746                 // At appendText time the final fontsize needs to be determined, and then
1747                 // the escapement can be calculated from the grabbag'd half-point value
1748                 // and directly applied. Yuck.
1749                 // It seems best to just treat charstyle escapement like
1750                 // pre-commit e70df84352d3670508a4666c97df44f82c1ce934
1751                 // which just assigned default values and ignored the actual/given escapement.
1752                 sal_Int16 nEscapement = nIntValue > 0 ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB;
1753                 sal_Int8 nProp = DFLT_ESC_PROP;
1754                 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( nEscapement ) );
1755                 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::makeAny( nProp ) );
1756             }
1757         }
1758         break;
1759     case NS_ooxml::LN_EG_RPrBase_spacing:
1760         {
1761             //Kerning half point values
1762             //TODO: there are two kerning values -
1763             // in ww8par6.cxx NS_sprm::LN_CHpsKern is used as boolean AutoKerning
1764             sal_Int16 nResult = static_cast<sal_Int16>(ConversionHelper::convertTwipToMM100(nIntValue));
1765             if (m_pImpl->IsInComments())
1766             {
1767                 nResult = static_cast<sal_Int16>(nIntValue);
1768             }
1769             rContext->Insert(PROP_CHAR_CHAR_KERNING, uno::makeAny(nResult));
1770             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", OUString::number(nIntValue));
1771         }
1772         break;
1773     case NS_ooxml::LN_EG_RPrBase_kern: // auto kerning is bound to a minimum font size in Word - but not in Writer :-(
1774         rContext->Insert(PROP_CHAR_AUTO_KERNING, uno::makeAny( nIntValue != 0 ) );
1775         break;
1776     case NS_ooxml::LN_EG_RPrBase_w:
1777         // ST_TextScale must fall between 1% and 600% according to spec, otherwise resets to 100% according to experience
1778         if ((1 <= nIntValue) && (nIntValue <= 600))
1779         {
1780             rContext->Insert(PROP_CHAR_SCALE_WIDTH,
1781                              uno::makeAny( sal_Int16(nIntValue) ));
1782         }
1783         else
1784         {
1785             rContext->Insert(PROP_CHAR_SCALE_WIDTH,
1786                              uno::makeAny( sal_Int16(100) ));
1787         }
1788         break;
1789     case NS_ooxml::LN_EG_RPrBase_imprint:
1790         // FontRelief: NONE, EMBOSSED, ENGRAVED
1791         rContext->Insert(PROP_CHAR_RELIEF,
1792                          uno::makeAny( nIntValue ? awt::FontRelief::ENGRAVED : awt::FontRelief::NONE ));
1793         break;
1794     case NS_ooxml::LN_EG_RPrBase_effect:
1795         // The file-format has many character animations. We have only
1796         // one, so we use it always. Suboptimal solution though.
1797         if (nIntValue != NS_ooxml::LN_Value_ST_TextEffect_none)
1798             rContext->Insert(PROP_CHAR_FLASH, uno::makeAny( true ));
1799         else
1800             rContext->Insert(PROP_CHAR_FLASH, uno::makeAny( false ));
1801         break;
1802     case NS_ooxml::LN_EG_RPrBase_rtl:
1803         break;
1804     case NS_ooxml::LN_EG_RPrBase_shd:
1805         {
1806             //contains fore color, back color and shadow percentage, results in a brush
1807             writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1808             if( pProperties.get())
1809             {
1810                 std::shared_ptr<CellColorHandler> pCellColorHandler( new CellColorHandler );
1811                 pCellColorHandler->setOutputFormat( CellColorHandler::Character );
1812                 pProperties->resolve(*pCellColorHandler);
1813                 rContext->InsertProps(pCellColorHandler->getProperties().get());
1814                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_SHADING_MARKER, uno::makeAny(true), true, CHAR_GRAB_BAG );
1815             }
1816             break;
1817         }
1818     case NS_ooxml::LN_EG_SectPrContents_type:
1819         /* break type
1820           0 - No break
1821           1 - New Column
1822           2 - New page
1823           3 - Even page
1824           4 - odd page
1825         */
1826         OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1827         if(pSectionContext)
1828         {
1829             //continuous break only allowed if it is not the only section break
1830             SectionPropertyMap* pLastContext = m_pImpl->GetLastSectionContext();
1831             if ( nIntValue != static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous) || pLastContext || m_pImpl->GetParaSectpr() )
1832                 pSectionContext->SetBreakType( nIntValue );
1833         }
1834         break;
1835     case NS_ooxml::LN_EG_SectPrContents_titlePg:
1836     {
1837         OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1838         if(pSectionContext)
1839             pSectionContext->SetTitlePage( nIntValue > 0 );//section has title page
1840     }
1841     break;
1842     case 165:
1843     {
1844         //page height, rounded to default values, default: 0x3dc0 twip
1845         sal_Int32 nHeight = ConversionHelper::convertTwipToMM100( nIntValue );
1846         rContext->Insert( PROP_HEIGHT, uno::makeAny( PaperInfo::sloppyFitPageDimension( nHeight ) ) );
1847     }
1848     break;
1849     case NS_ooxml::LN_EG_SectPrContents_textDirection:
1850     {
1851         /* 0 HoriLR 1 Vert TR 2 Vert TR 3 Vert TT 4 HoriLT
1852             only 0 and 1 can be imported correctly
1853           */
1854         text::WritingMode nDirection = text::WritingMode_LR_TB;
1855         switch( nIntValue )
1856         {
1857             case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
1858             case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
1859                 nDirection = text::WritingMode_LR_TB;
1860             break;
1861             case NS_ooxml::LN_Value_ST_TextDirection_tbRl:
1862             case NS_ooxml::LN_Value_ST_TextDirection_btLr:
1863                 nDirection = text::WritingMode_TB_RL;
1864             break;
1865             default:;
1866         }
1867 
1868         PropertyMap * pTargetContext = rContext.get();
1869 
1870         if (pSectionContext)
1871         {
1872             pTargetContext = pSectionContext;
1873         }
1874 
1875         pTargetContext->Insert(PROP_WRITING_MODE, uno::makeAny( sal_Int16(nDirection) ) );
1876     }
1877     break;  // sprmSTextFlow
1878         // the following are not part of the official documentation
1879     case NS_ooxml::LN_CT_Tabs_tab:
1880         resolveSprmProps(*this, rSprm);
1881         m_pImpl->IncorporateTabStop(m_pImpl->m_aCurrentTabStop);
1882         m_pImpl->m_aCurrentTabStop = DeletableTabStop();
1883     break;
1884     case NS_ooxml::LN_CT_PPrBase_tabs:
1885     {
1886         // Initialize tab stop vector from style sheet
1887         // fdo#81033: for RTF, a tab stop is inherited from the style if it
1888         // is also applied to the paragraph directly, and cleared if it is
1889         // not applied to the paragraph directly => don't InitTabStopFromStyle
1890         if ( !IsRTFImport() )
1891         {
1892             uno::Any aValue = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_TAB_STOPS);
1893             uno::Sequence< style::TabStop > aStyleTabStops;
1894             if(aValue >>= aStyleTabStops)
1895             {
1896                 m_pImpl->InitTabStopFromStyle( aStyleTabStops );
1897             }
1898         }
1899         resolveSprmProps(*this, rSprm);
1900         rContext->Insert(PROP_PARA_TAB_STOPS, uno::makeAny( m_pImpl->GetCurrentTabStopAndClear()));
1901     }
1902     break;
1903 
1904     case NS_ooxml::LN_CT_DocDefaults_pPrDefault:
1905     case NS_ooxml::LN_CT_DocDefaults_rPrDefault:
1906         GetStyleSheetTable()->sprm( rSprm );
1907     break;
1908     case NS_ooxml::LN_EG_RPrBase_bdr:
1909         {
1910             writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1911             if( pProperties.get())
1912             {
1913                 std::shared_ptr<BorderHandler> pBorderHandler( new BorderHandler( true ) );
1914                 pProperties->resolve(*pBorderHandler);
1915 
1916                 rContext->Insert( PROP_CHAR_TOP_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
1917                 rContext->Insert( PROP_CHAR_BOTTOM_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
1918                 rContext->Insert( PROP_CHAR_LEFT_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
1919                 rContext->Insert( PROP_CHAR_RIGHT_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
1920 
1921                 rContext->Insert( PROP_CHAR_TOP_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
1922                 rContext->Insert( PROP_CHAR_BOTTOM_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
1923                 rContext->Insert( PROP_CHAR_LEFT_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
1924                 rContext->Insert( PROP_CHAR_RIGHT_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
1925 
1926                 if( pBorderHandler->getShadow() )
1927                 {
1928                     table::ShadowFormat aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
1929                     rContext->Insert(PROP_CHAR_SHADOW_FORMAT, uno::makeAny(aFormat));
1930                 }
1931             }
1932         }
1933         break;
1934     case NS_ooxml::LN_CT_PPr_sectPr:
1935     case NS_ooxml::LN_EG_RPrBase_color:
1936     case NS_ooxml::LN_EG_RPrBase_rFonts:
1937     case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
1938     case NS_ooxml::LN_EG_RPrBase_u:
1939     case NS_ooxml::LN_EG_RPrBase_lang:
1940     case NS_ooxml::LN_CT_PPrBase_spacing:
1941     case NS_ooxml::LN_CT_PPrBase_ind:
1942     case NS_ooxml::LN_CT_RPrDefault_rPr:
1943     case NS_ooxml::LN_CT_PPrDefault_pPr:
1944     case NS_ooxml::LN_CT_Style_pPr:
1945     case NS_ooxml::LN_CT_Style_rPr:
1946     case NS_ooxml::LN_CT_PPr_rPr:
1947     case NS_ooxml::LN_CT_PPrBase_numPr:
1948     {
1949         bool bTempGrabBag = !m_pImpl->isInteropGrabBagEnabled();
1950         if (nSprmId == NS_ooxml::LN_CT_PPr_sectPr)
1951             m_pImpl->SetParaSectpr(true);
1952         else if (nSprmId == NS_ooxml::LN_EG_RPrBase_color && bTempGrabBag)
1953             // if DomainMapper grab bag is not enabled, enable it temporarily
1954             m_pImpl->enableInteropGrabBag("TempColorPropsGrabBag");
1955         resolveSprmProps(*this, rSprm);
1956         if (nSprmId == NS_ooxml::LN_CT_PPrBase_spacing)
1957             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", m_pImpl->m_aSubInteropGrabBag);
1958         else if (nSprmId == NS_ooxml::LN_EG_RPrBase_rFonts)
1959             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "rFonts", m_pImpl->m_aSubInteropGrabBag);
1960         else if (nSprmId == NS_ooxml::LN_EG_RPrBase_lang)
1961             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lang", m_pImpl->m_aSubInteropGrabBag);
1962         else if (nSprmId == NS_ooxml::LN_EG_RPrBase_color)
1963         {
1964             for (const auto& rItem : m_pImpl->m_aSubInteropGrabBag)
1965             {
1966                 if (rItem.Name == "val")
1967                     m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_ORIGINAL_COLOR, rItem.Value, true, CHAR_GRAB_BAG);
1968                 else if (rItem.Name == "themeColor")
1969                     m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR, rItem.Value, true, CHAR_GRAB_BAG);
1970                 else if (rItem.Name == "themeShade")
1971                     m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_SHADE, rItem.Value, true, CHAR_GRAB_BAG);
1972                 else if (rItem.Name == "themeTint")
1973                     m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_TINT, rItem.Value, true, CHAR_GRAB_BAG);
1974             }
1975             if (bTempGrabBag)
1976                 //disable and clear DomainMapper grab bag if it wasn't enabled before
1977                 m_pImpl->disableInteropGrabBag();
1978 
1979             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "color", m_pImpl->m_aSubInteropGrabBag);
1980         }
1981         else if (nSprmId == NS_ooxml::LN_CT_PPrBase_ind)
1982             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ind", m_pImpl->m_aSubInteropGrabBag);
1983     }
1984     break;
1985     case NS_ooxml::LN_CT_PPrBase_wordWrap:
1986         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "wordWrap", "");
1987     break;
1988     case NS_ooxml::LN_EG_SectPrContents_footnotePr:
1989     case NS_ooxml::LN_EG_SectPrContents_endnotePr:
1990         m_pImpl->SetInFootnoteProperties( NS_ooxml::LN_EG_SectPrContents_footnotePr == nSprmId );
1991         resolveSprmProps(*this, rSprm);
1992     break;
1993     case NS_ooxml::LN_EG_SectPrContents_lnNumType:
1994     {
1995         resolveSprmProps(*this, rSprm);
1996         LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
1997         m_pImpl->SetLineNumberSettings( aSettings );
1998         //apply settings at XLineNumberingProperties
1999         try
2000         {
2001             uno::Reference< text::XLineNumberingProperties > xLineNumberingProperties( m_pImpl->GetTextDocument(), uno::UNO_QUERY_THROW );
2002             uno::Reference< beans::XPropertySet > xLineNumberingPropSet = xLineNumberingProperties->getLineNumberingProperties();
2003             if( aSettings.nInterval == 0 )
2004                 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::makeAny(false) );
2005             else
2006             {
2007                 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::makeAny(true) );
2008                 if( aSettings.nInterval )
2009                     xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_INTERVAL ), uno::makeAny(static_cast<sal_Int16>(aSettings.nInterval)) );
2010                 if( aSettings.nDistance != -1 )
2011                     xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::makeAny(aSettings.nDistance) );
2012                 else
2013                 {
2014                     // set Auto value (0.5 cm)
2015                     xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::makeAny(static_cast<sal_Int32>(500)) );
2016                     if( pSectionContext )
2017                         pSectionContext->SetdxaLnn( static_cast<sal_Int32>(283) );
2018                 }
2019                 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny(aSettings.bRestartAtEachPage) );
2020             }
2021         }
2022         catch( const uno::Exception& )
2023         {
2024         }
2025 
2026     }
2027     break;
2028     case NS_ooxml::LN_CT_PPrBase_framePr:
2029     // Avoid frames if we're inside a structured document tag, would just cause outer tables fail to create.
2030     if (!m_pImpl->GetSdt())
2031     {
2032         PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
2033         if( pContext.get() )
2034         {
2035             // If there is a deferred page break applied to this framed paragraph,
2036             // create a dummy paragraph without extra properties,
2037             // so that the anchored frame will be on the correct page (similar to shapes).
2038             if (pContext->isSet(PROP_BREAK_TYPE))
2039             {
2040                 pContext->Erase(PROP_BREAK_TYPE);
2041 
2042                 lcl_startParagraphGroup();
2043                 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
2044                 lcl_startCharacterGroup();
2045                 sal_uInt8 const sBreak[] = { 0xd };
2046                 lcl_text(sBreak, 1);
2047                 lcl_endCharacterGroup();
2048                 lcl_endParagraphGroup();
2049             }
2050 
2051             ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
2052             if (pParaContext)
2053                 pParaContext->SetFrameMode();
2054 
2055             if (!IsInHeaderFooter())
2056                 m_pImpl->m_bIsActualParagraphFramed = true;
2057         }
2058         else
2059         {
2060             //TODO: What about style sheet import of frame properties
2061         }
2062         resolveSprmProps(*this, rSprm);
2063     }
2064     break;
2065     case NS_ooxml::LN_EG_SectPrContents_pgSz:
2066         {
2067             PaperInfo aLetter(PAPER_LETTER);
2068             CT_PageSz.w = aLetter.getWidth();
2069             CT_PageSz.h = aLetter.getHeight();
2070         }
2071         CT_PageSz.orient = false;
2072         resolveSprmProps(*this, rSprm);
2073         OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2074         if(pSectionContext)
2075         {
2076             pSectionContext->Insert( PROP_HEIGHT, uno::makeAny( CT_PageSz.h ) );
2077             pSectionContext->Insert( PROP_IS_LANDSCAPE, uno::makeAny( CT_PageSz.orient ));
2078             pSectionContext->Insert( PROP_WIDTH, uno::makeAny( CT_PageSz.w ) );
2079         }
2080         break;
2081 
2082     case NS_ooxml::LN_EG_SectPrContents_pgMar:
2083         m_pImpl->InitPageMargins();
2084         resolveSprmProps(*this, rSprm);
2085         OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2086         if(pSectionContext)
2087         {
2088             const PageMar& rPageMar = m_pImpl->GetPageMargins();
2089             pSectionContext->SetTopMargin( rPageMar.top );
2090             pSectionContext->SetRightMargin( rPageMar.right );
2091             pSectionContext->SetBottomMargin( rPageMar.bottom );
2092             pSectionContext->SetLeftMargin( rPageMar.left );
2093             pSectionContext->SetHeaderTop( rPageMar.header );
2094             pSectionContext->SetHeaderBottom( rPageMar.footer );
2095         }
2096         break;
2097 
2098     case NS_ooxml::LN_EG_SectPrContents_cols:
2099     {
2100         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2101         if( pProperties.get())
2102         {
2103 
2104             tools::SvRef< SectionColumnHandler > pSectHdl( new SectionColumnHandler );
2105             pProperties->resolve(*pSectHdl);
2106             if(pSectionContext && !m_pImpl->isInIndexContext())
2107             {
2108                 if( pSectHdl->IsEqualWidth() )
2109                 {
2110                     pSectionContext->SetEvenlySpaced( true );
2111                     pSectionContext->SetColumnCount( static_cast<sal_Int16>(pSectHdl->GetNum() - 1) );
2112                     pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2113                     pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2114                 }
2115                 else if( !pSectHdl->GetColumns().empty() )
2116                 {
2117                     pSectionContext->SetEvenlySpaced( false );
2118                     pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2119                     pSectionContext->SetColumnCount( static_cast<sal_Int16>(pSectHdl->GetColumns().size() -1));
2120                     std::vector<Column_>::const_iterator tmpIter = pSectHdl->GetColumns().begin();
2121                     for (; tmpIter != pSectHdl->GetColumns().end(); ++tmpIter)
2122                     {
2123                         pSectionContext->AppendColumnWidth( tmpIter->nWidth );
2124                         if ((tmpIter != pSectHdl->GetColumns().end() - 1) || (tmpIter->nSpace > 0))
2125                             pSectionContext->AppendColumnSpacing( tmpIter->nSpace );
2126                     }
2127                     pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2128                 }
2129                 else if( pSectHdl->GetNum() > 0 )
2130                 {
2131                     pSectionContext->SetColumnCount( static_cast<sal_Int16>(pSectHdl->GetNum()) - 1 );
2132                     pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2133                     pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2134                 }
2135             }
2136 
2137             else if ( pSectionContext )
2138             {
2139                 FieldContextPtr pContext = m_pImpl->GetTopFieldContext();
2140                 uno::Reference< beans::XPropertySet > xTOC = pContext->GetTOC();
2141                 if( xTOC.is() )
2142                 {
2143                     uno::Reference<text::XTextColumns> xTextColumns;
2144                     xTOC->getPropertyValue(getPropertyName( PROP_TEXT_COLUMNS )) >>= xTextColumns;
2145                     if (xTextColumns.is())
2146                     {
2147                         uno::Reference< beans::XPropertySet > xColumnPropSet( xTextColumns, uno::UNO_QUERY_THROW );
2148                         xColumnPropSet->setPropertyValue( getPropertyName( PROP_AUTOMATIC_DISTANCE ), uno::makeAny( pSectHdl->GetSpace() ));
2149                         xTOC->setPropertyValue( getPropertyName( PROP_TEXT_COLUMNS ), uno::makeAny( xTextColumns ) );
2150                     }
2151                 }
2152             }
2153         }
2154     }
2155     break;
2156     case NS_ooxml::LN_EG_SectPrContents_docGrid:
2157         resolveSprmProps(*this, rSprm);
2158     break;
2159     case NS_ooxml::LN_EG_SectPrContents_pgBorders:
2160     {
2161         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2162         if( pProperties.get( ) && pSectionContext )
2163         {
2164             tools::SvRef< PageBordersHandler > pHandler( new PageBordersHandler );
2165             pProperties->resolve( *pHandler );
2166 
2167             // Set the borders to the context and apply them to the styles
2168             pHandler->SetBorders( pSectionContext );
2169         }
2170     }
2171     break;
2172 
2173     case NS_ooxml::LN_CT_PPrBase_snapToGrid:
2174         if (!IsStyleSheetImport()||!m_pImpl->isInteropGrabBagEnabled())
2175         {
2176             rContext->Insert( PROP_SNAP_TO_GRID, uno::makeAny(bool(nIntValue)));
2177         }
2178         else
2179         {
2180             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "snapToGrid", OUString::number(nIntValue));
2181         }
2182     break;
2183     case NS_ooxml::LN_CT_PPrBase_pStyle:
2184     {
2185         StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable();
2186         const OUString sConvertedStyleName = pStyleTable->ConvertStyleName( sStringValue, true );
2187         m_pImpl->SetCurrentParaStyleName( sConvertedStyleName );
2188         if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION)
2189             m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::makeAny( sConvertedStyleName ));
2190     }
2191     break;
2192     case NS_ooxml::LN_EG_RPrBase_rStyle:
2193         {
2194             OUString sConvertedName( m_pImpl->GetStyleSheetTable()->ConvertStyleName( sStringValue, true ) );
2195             if (m_pImpl->CheckFootnoteStyle())
2196                 m_pImpl->SetHasFootnoteStyle(m_pImpl->GetFootnoteContext()->GetFootnoteStyle() == sConvertedName);
2197 
2198             // First check if the style exists in the document.
2199             StyleSheetEntryPtr pEntry = m_pImpl->GetStyleSheetTable( )->FindStyleSheetByConvertedStyleName( sConvertedName );
2200             bool bExists = pEntry.get( ) && ( pEntry->nStyleTypeCode == STYLE_TYPE_CHAR );
2201             // Add the property if the style exists, but do not add it elements in TOC:
2202             // they will receive later another style references from TOC
2203             if ( bExists && m_pImpl->GetTopContext() && !m_pImpl->IsInTOC())
2204                 m_pImpl->GetTopContext()->Insert( PROP_CHAR_STYLE_NAME, uno::makeAny( sConvertedName ) );
2205         }
2206     break;
2207     case NS_ooxml::LN_CT_TblPrBase_tblCellMar: //cell margins
2208     {
2209         resolveSprmProps(*this, rSprm);//contains LN_CT_TblCellMar_top, LN_CT_TblCellMar_left, LN_CT_TblCellMar_bottom, LN_CT_TblCellMar_right
2210     }
2211     break;
2212     case NS_ooxml::LN_CT_TblCellMar_top:
2213     case NS_ooxml::LN_CT_TblCellMar_start:
2214     case NS_ooxml::LN_CT_TblCellMar_left:
2215     case NS_ooxml::LN_CT_TblCellMar_bottom:
2216     case NS_ooxml::LN_CT_TblCellMar_end:
2217     case NS_ooxml::LN_CT_TblCellMar_right:
2218     {
2219         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2220         if( pProperties.get())
2221         {
2222             MeasureHandlerPtr pMeasureHandler( new MeasureHandler );
2223             pProperties->resolve(*pMeasureHandler);
2224             sal_Int32 nMeasureValue = pMeasureHandler->getMeasureValue();
2225             PropertyIds eId = META_PROP_CELL_MAR_TOP;
2226             bool rtl = false; // TODO
2227             switch(nSprmId)
2228             {
2229                 case NS_ooxml::LN_CT_TblCellMar_top:
2230                 break;
2231                 case NS_ooxml::LN_CT_TblCellMar_start:
2232                     eId = rtl ? META_PROP_CELL_MAR_RIGHT : META_PROP_CELL_MAR_LEFT;
2233                 break;
2234                 case NS_ooxml::LN_CT_TblCellMar_left:
2235                     eId = META_PROP_CELL_MAR_LEFT;
2236                 break;
2237                 case NS_ooxml::LN_CT_TblCellMar_bottom:
2238                     eId = META_PROP_CELL_MAR_BOTTOM;
2239                 break;
2240                 case NS_ooxml::LN_CT_TblCellMar_end:
2241                     eId = rtl ? META_PROP_CELL_MAR_LEFT : META_PROP_CELL_MAR_RIGHT;
2242                 break;
2243                 case NS_ooxml::LN_CT_TblCellMar_right:
2244                     eId = META_PROP_CELL_MAR_RIGHT;
2245                 break;
2246                 default:;
2247             }
2248             rContext->Insert( eId, uno::makeAny(nMeasureValue), false);
2249         }
2250     }
2251     break;
2252     case NS_ooxml::LN_EG_RPrBase_noProof: // no grammar and spell checking, unsupported
2253     break;
2254     case NS_ooxml::LN_anchor_anchor: // at_character drawing
2255     case NS_ooxml::LN_inline_inline: // as_character drawing
2256     {
2257         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2258         if( pProperties.get())
2259         {
2260             GraphicImportType eGraphicType =
2261                 (NS_ooxml::LN_anchor_anchor ==
2262                  sal::static_int_cast<Id>(nSprmId)) ?
2263                 IMPORT_AS_DETECTED_ANCHOR :
2264                 IMPORT_AS_DETECTED_INLINE;
2265             GraphicImportPtr pGraphicImport =
2266                 m_pImpl->GetGraphicImport(eGraphicType);
2267             pProperties->resolve(*pGraphicImport);
2268             m_pImpl->ImportGraphic(pProperties, eGraphicType);
2269             if( !pGraphicImport->IsGraphic() )
2270             {
2271                 m_pImpl->ResetGraphicImport();
2272                 // todo: It's a shape, now start shape import
2273             }
2274         }
2275     }
2276     break;
2277     case NS_ooxml::LN_EG_RPrBase_vertAlign:
2278     {
2279         sal_Int16 nEscapement = 0;
2280         sal_Int8 nProp  = 58;
2281         if ( sStringValue == "superscript" )
2282                 nEscapement = DFLT_ESC_AUTO_SUPER;
2283         else if ( sStringValue == "subscript" )
2284                 nEscapement = DFLT_ESC_AUTO_SUB;
2285         else
2286             nProp = 100;
2287 
2288         rContext->Insert(PROP_CHAR_ESCAPEMENT,         uno::makeAny( nEscapement ) );
2289         rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT,  uno::makeAny( nProp ) );
2290     }
2291     break;
2292     case NS_ooxml::LN_CT_FtnProps_pos:
2293     //footnotes in word can be at page end or beneath text - writer supports only the first
2294     //endnotes in word can be at section end or document end - writer supports only the latter
2295     // -> so this property can be ignored
2296     break;
2297     case NS_ooxml::LN_EG_FtnEdnNumProps_numStart:
2298     case NS_ooxml::LN_EG_FtnEdnNumProps_numRestart:
2299     case NS_ooxml::LN_CT_FtnProps_numFmt:
2300     case NS_ooxml::LN_CT_EdnProps_numFmt:
2301     {
2302         try
2303         {
2304             uno::Reference< beans::XPropertySet >  xFtnEdnSettings;
2305             if( m_pImpl->IsInFootnoteProperties() )
2306             {
2307                 uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2308                 if (xFootnotesSupplier.is())
2309                     xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings();
2310             }
2311             else
2312             {
2313                 uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2314                 if (xEndnotesSupplier.is())
2315                     xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings();
2316             }
2317             if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId && xFtnEdnSettings.is())
2318             {
2319                 xFtnEdnSettings->setPropertyValue(
2320                     getPropertyName( PROP_START_AT),
2321                                                                     uno::makeAny( sal_Int16( nIntValue - 1 )));
2322             }
2323             else if( NS_ooxml::LN_EG_FtnEdnNumProps_numRestart == nSprmId && xFtnEdnSettings.is())
2324             {
2325                 sal_Int16 nFootnoteCounting = 0;
2326                 switch (nIntValue)
2327                 {
2328                     case NS_ooxml::LN_Value_ST_RestartNumber_continuous: nFootnoteCounting = text::FootnoteNumbering::PER_DOCUMENT; break;
2329                     case NS_ooxml::LN_Value_ST_RestartNumber_eachPage: nFootnoteCounting = text::FootnoteNumbering::PER_PAGE; break;
2330                     case NS_ooxml::LN_Value_ST_RestartNumber_eachSect: nFootnoteCounting = text::FootnoteNumbering::PER_CHAPTER; break;
2331                     default: break;
2332                 }
2333                 xFtnEdnSettings->setPropertyValue(
2334                         getPropertyName( PROP_FOOTNOTE_COUNTING ),
2335                         uno::makeAny( nFootnoteCounting ));
2336             }
2337             else if (xFtnEdnSettings.is())
2338             {
2339                 sal_Int16 nNumType = ConversionHelper::ConvertNumberingType( nIntValue );
2340                 xFtnEdnSettings->setPropertyValue(
2341                     getPropertyName( PROP_NUMBERING_TYPE),
2342                                                                     uno::makeAny( nNumType ));
2343             }
2344         }
2345         catch( const uno::Exception& )
2346         {
2347         }
2348     }
2349     break;
2350     case NS_ooxml::LN_paratrackchange:
2351         m_pImpl->StartParaMarkerChange( );
2352         [[fallthrough]];
2353     case NS_ooxml::LN_CT_PPr_pPrChange:
2354     case NS_ooxml::LN_CT_ParaRPr_rPrChange:
2355     case NS_ooxml::LN_trackchange:
2356     case NS_ooxml::LN_EG_RPrContent_rPrChange:
2357     case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeStart:
2358     case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeEnd:
2359     case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeStart:
2360     case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeEnd:
2361     case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeStart:
2362     case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeEnd:
2363     {
2364         HandleRedline( rSprm );
2365     }
2366     break;
2367     case NS_ooxml::LN_endtrackchange:
2368         m_pImpl->RemoveTopRedline();
2369     break;
2370     case NS_ooxml::LN_CT_RPrChange_rPr:
2371     {
2372         // Push all the current 'Character' properties to the stack, so that we don't store them
2373         // as 'tracked changes' by mistake
2374         m_pImpl->PushProperties(CONTEXT_CHARACTER);
2375 
2376         // Resolve all the properties that are under the 'rPrChange'->'rPr' XML node
2377         resolveSprmProps(*this, rSprm );
2378 
2379         // Get all the properties that were processed in the 'rPrChange'->'rPr' XML node
2380         uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2381 
2382         // Pop back out the character properties that were on the run
2383         m_pImpl->PopProperties(CONTEXT_CHARACTER);
2384 
2385         // Store these properties in the current redline object (do it after the PopProperties() above, since
2386         // otherwise it'd be stored in the content dropped there).
2387         m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2388     }
2389     break;
2390     case NS_ooxml::LN_CT_PPrChange_pPr:
2391     {
2392         // Push all the current 'Paragraph' properties to the stack, so that we don't store them
2393         // as 'tracked changes' by mistake
2394         m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2395 
2396         // Resolve all the properties that are under the 'pPrChange'->'pPr' XML node
2397         resolveSprmProps(*this, rSprm );
2398 
2399         // Get all the properties that were processed in the 'pPrChange'->'pPr' XML node
2400         uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2401 
2402         // Pop back out the character properties that were on the run
2403         m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
2404 
2405         // Store these properties in the current redline object (do it after the PopProperties() above, since
2406         // otherwise it'd be stored in the content dropped there).
2407         m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2408     }
2409     break;
2410     case NS_ooxml::LN_object:
2411     {
2412         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2413         if( pProperties.get( ) )
2414         {
2415             std::shared_ptr<OLEHandler> pOLEHandler( new OLEHandler(*this) );
2416             pProperties->resolve(*pOLEHandler);
2417             if ( pOLEHandler->isOLEObject( ) )
2418             {
2419                 OUString sStreamName = pOLEHandler->copyOLEOStream( m_pImpl->GetTextDocument() );
2420                 if( !sStreamName.isEmpty() )
2421                 {
2422                     m_pImpl->appendOLE( sStreamName, pOLEHandler );
2423                 }
2424             }
2425         }
2426     }
2427     break;
2428     case NS_ooxml::LN_EG_HdrFtrReferences_headerReference: // header reference - not needed
2429     case NS_ooxml::LN_EG_HdrFtrReferences_footerReference: // footer reference - not needed
2430     break;
2431     case NS_ooxml::LN_EG_RPrBase_snapToGrid: // "Use document grid  settings for inter-paragraph spacing"
2432     break;
2433     case NS_ooxml::LN_CT_PPrBase_contextualSpacing:
2434         rContext->Insert(PROP_PARA_CONTEXT_MARGIN, uno::makeAny( nIntValue != 0 ));
2435     break;
2436     case NS_ooxml::LN_CT_PPrBase_mirrorIndents: // mirrorIndents
2437         rContext->Insert(PROP_MIRROR_INDENTS, uno::makeAny( nIntValue != 0 ), true, PARA_GRAB_BAG);
2438     break;
2439     case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection
2440     {
2441         if( pSectionContext )
2442             pSectionContext->Insert( PROP_IS_PROTECTED, uno::makeAny( bool(nIntValue) ) );
2443     }
2444     break;
2445     case NS_ooxml::LN_EG_SectPrContents_vAlign:
2446     {
2447         OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2448         if( pSectionContext )
2449         {
2450             drawing::TextVerticalAdjust nVA = drawing::TextVerticalAdjust_TOP;
2451             switch( nIntValue )
2452             {
2453                 case NS_ooxml::LN_Value_ST_VerticalJc_center: //92367
2454                     nVA = drawing::TextVerticalAdjust_CENTER;
2455                     break;
2456                 case NS_ooxml::LN_Value_ST_VerticalJc_both:   //92368 - justify
2457                     nVA = drawing::TextVerticalAdjust_BLOCK;
2458                     break;
2459                 case NS_ooxml::LN_Value_ST_VerticalJc_bottom: //92369
2460                     nVA = drawing::TextVerticalAdjust_BOTTOM;
2461                     break;
2462                 default:
2463                     break;
2464             }
2465             pSectionContext->Insert( PROP_TEXT_VERTICAL_ADJUST, uno::makeAny( nVA ), true, PARA_GRAB_BAG );
2466         }
2467     }
2468     break;
2469     case NS_ooxml::LN_EG_RPrBase_fitText:
2470     break;
2471     case NS_ooxml::LN_ffdata:
2472     {
2473         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2474         if (pProperties.get() != nullptr)
2475         {
2476             FFDataHandler::Pointer_t pFFDataHandler(new FFDataHandler());
2477 
2478             pProperties->resolve(*pFFDataHandler);
2479             m_pImpl->SetFieldFFData(pFFDataHandler);
2480         }
2481     }
2482     break;
2483     case NS_ooxml::LN_CT_SdtPr_dropDownList:
2484     case NS_ooxml::LN_CT_SdtPr_comboBox:
2485     {
2486         m_pImpl->m_pSdtHelper->setInsideDropDownControl(true);
2487         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2488         if (pProperties.get() != nullptr)
2489             pProperties->resolve(*this);
2490     }
2491     break;
2492     case NS_ooxml::LN_CT_SdtDropDownList_listItem:
2493     {
2494         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2495         if (pProperties.get() != nullptr)
2496             pProperties->resolve(*this);
2497     }
2498     break;
2499     case NS_ooxml::LN_CT_SdtPr_date:
2500     {
2501         resolveSprmProps(*this, rSprm);
2502         m_pImpl->m_pSdtHelper->setDateFieldStartRange(GetCurrentTextRange()->getEnd());
2503     }
2504     break;
2505     case NS_ooxml::LN_CT_SdtDate_dateFormat:
2506     {
2507         m_pImpl->m_pSdtHelper->getDateFormat().append(sStringValue);
2508     }
2509     break;
2510     case NS_ooxml::LN_CT_SdtDate_storeMappedDataAs:
2511     {
2512     }
2513     break;
2514     case NS_ooxml::LN_CT_SdtDate_calendar:
2515     {
2516     }
2517     break;
2518     case NS_ooxml::LN_CT_SdtDate_lid:
2519     {
2520         m_pImpl->m_pSdtHelper->getLocale().append(sStringValue);
2521     }
2522     break;
2523     case NS_ooxml::LN_CT_SdtPr_dataBinding:
2524     case NS_ooxml::LN_CT_SdtPr_equation:
2525     case NS_ooxml::LN_CT_SdtPr_checkbox:
2526     case NS_ooxml::LN_CT_SdtPr_docPartObj:
2527     case NS_ooxml::LN_CT_SdtPr_docPartList:
2528     case NS_ooxml::LN_CT_SdtPr_picture:
2529     case NS_ooxml::LN_CT_SdtPr_citation:
2530     case NS_ooxml::LN_CT_SdtPr_group:
2531     case NS_ooxml::LN_CT_SdtPr_text:
2532     case NS_ooxml::LN_CT_SdtPr_id:
2533     case NS_ooxml::LN_CT_SdtPr_alias:
2534     {
2535         // this is an unsupported SDT property, create a grab bag for it
2536         OUString sName;
2537         switch (nSprmId)
2538         {
2539             case NS_ooxml::LN_CT_SdtPr_dataBinding: sName = "ooxml:CT_SdtPr_dataBinding"; break;
2540             case NS_ooxml::LN_CT_SdtPr_equation:    sName = "ooxml:CT_SdtPr_equation"; break;
2541             case NS_ooxml::LN_CT_SdtPr_checkbox:    sName = "ooxml:CT_SdtPr_checkbox"; break;
2542             case NS_ooxml::LN_CT_SdtPr_docPartObj:  sName = "ooxml:CT_SdtPr_docPartObj"; break;
2543             case NS_ooxml::LN_CT_SdtPr_docPartList: sName = "ooxml:CT_SdtPr_docPartList"; break;
2544             case NS_ooxml::LN_CT_SdtPr_picture:     sName = "ooxml:CT_SdtPr_picture"; break;
2545             case NS_ooxml::LN_CT_SdtPr_citation:    sName = "ooxml:CT_SdtPr_citation"; break;
2546             case NS_ooxml::LN_CT_SdtPr_group:       sName = "ooxml:CT_SdtPr_group"; break;
2547             case NS_ooxml::LN_CT_SdtPr_text:        sName = "ooxml:CT_SdtPr_text"; break;
2548             case NS_ooxml::LN_CT_SdtPr_id:          sName = "ooxml:CT_SdtPr_id"; break;
2549             case NS_ooxml::LN_CT_SdtPr_alias:       sName = "ooxml:CT_SdtPr_alias"; break;
2550             default: assert(false);
2551         };
2552         enableInteropGrabBag(sName);
2553 
2554         // process subitems
2555         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2556         if (pProperties.get() != nullptr)
2557             pProperties->resolve(*this);
2558 
2559         if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias)
2560         {
2561             beans::PropertyValue aValue;
2562             aValue.Name = sName;
2563             aValue.Value <<= sStringValue;
2564             m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
2565         }
2566         else
2567             m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
2568         m_pImpl->m_pSdtHelper->setOutsideAParagraph(m_pImpl->IsOutsideAParagraph());
2569         m_pImpl->disableInteropGrabBag();
2570     }
2571     break;
2572     case NS_ooxml::LN_CT_SdtCheckbox_checked:
2573         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checked", sStringValue);
2574         break;
2575     case NS_ooxml::LN_CT_SdtCheckbox_checkedState:
2576         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checkedState", sStringValue);
2577         break;
2578     case NS_ooxml::LN_CT_SdtCheckbox_uncheckedState:
2579         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_uncheckedState", sStringValue);
2580         break;
2581     case NS_ooxml::LN_CT_SdtDocPart_docPartGallery:
2582         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartGallery", sStringValue);
2583         break;
2584     case NS_ooxml::LN_CT_SdtDocPart_docPartCategory:
2585         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartCategory", sStringValue);
2586         break;
2587     case NS_ooxml::LN_CT_SdtDocPart_docPartUnique:
2588         m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartUnique", sStringValue);
2589         break;
2590     case NS_ooxml::LN_EG_SectPrContents_pgNumType:
2591     {
2592         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2593         if( pProperties.get())
2594         {
2595             pProperties->resolve(*this);
2596         }
2597     }
2598     break;
2599     case NS_ooxml::LN_tblStart:
2600     {
2601         if (m_pImpl->hasTableManager())
2602         {
2603             bool bTableStartsAtCellStart = m_pImpl->m_nTableDepth > 0 && m_pImpl->m_nTableCellDepth > m_pImpl->m_nLastTableCellParagraphDepth + 1;
2604             m_pImpl->getTableManager().setTableStartsAtCellStart(bTableStartsAtCellStart);
2605         }
2606         /*
2607          * Hack for Importing Section Properties
2608          * LO is not able to import section properties if first element in the
2609          * section is a table. So in case first element is a table add a dummy para
2610          * and remove it again when lcl_endSectionGroup is called
2611          */
2612         if(m_pImpl->m_nTableDepth == 0 && m_pImpl->GetIsFirstParagraphInSection()
2613                 && !m_pImpl->GetIsDummyParaAddedForTableInSection() && !m_pImpl->GetIsTextFrameInserted()
2614                 && !IsInHeaderFooter())
2615         {
2616             m_pImpl->AddDummyParaForTableInSection();
2617         }
2618 
2619         // if first paragraph style in table has break-before-page, transfer that setting to the table itself.
2620         if( m_pImpl->m_nTableDepth == 0 )
2621         {
2622             const uno::Any aBreakType = uno::makeAny(style::BreakType_PAGE_BEFORE);
2623             const PropertyMapPtr pParagraphProps = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
2624             if( pParagraphProps && pParagraphProps->isSet(PROP_PARA_STYLE_NAME) )
2625             {
2626                 StyleSheetEntryPtr pStyle;
2627                 OUString sStyleName;
2628                 pParagraphProps->getProperty(PROP_PARA_STYLE_NAME)->second >>= sStyleName;
2629                 if( !sStyleName.isEmpty() && GetStyleSheetTable() )
2630                     pStyle = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( sStyleName );
2631 
2632                 if( pStyle && pStyle->pProperties
2633                     && pStyle->pProperties->isSet(PROP_BREAK_TYPE)
2634                     && pStyle->pProperties->getProperty(PROP_BREAK_TYPE)->second == aBreakType )
2635                 {
2636                     pParagraphProps->Insert(PROP_BREAK_TYPE, aBreakType);
2637                 }
2638             }
2639         }
2640 
2641         m_pImpl->m_nTableDepth++;
2642     }
2643     break;
2644     case NS_ooxml::LN_tblEnd:
2645         m_pImpl->m_nTableDepth--;
2646     break;
2647     case NS_ooxml::LN_tcStart:
2648         m_pImpl->m_nTableCellDepth++;
2649     break;
2650     case NS_ooxml::LN_tcEnd:
2651         m_pImpl->m_nTableCellDepth--;
2652         m_pImpl->m_nLastTableCellParagraphDepth = 0;
2653     break;
2654     case NS_ooxml::LN_glow_glow:
2655     case NS_ooxml::LN_shadow_shadow:
2656     case NS_ooxml::LN_reflection_reflection:
2657     case NS_ooxml::LN_textOutline_textOutline:
2658     case NS_ooxml::LN_textFill_textFill:
2659     case NS_ooxml::LN_scene3d_scene3d:
2660     case NS_ooxml::LN_props3d_props3d:
2661     case NS_ooxml::LN_ligatures_ligatures:
2662     case NS_ooxml::LN_numForm_numForm:
2663     case NS_ooxml::LN_numSpacing_numSpacing:
2664     case NS_ooxml::LN_stylisticSets_stylisticSets:
2665     case NS_ooxml::LN_cntxtAlts_cntxtAlts:
2666     {
2667         tools::SvRef<TextEffectsHandler> pTextEffectsHandlerPtr( new TextEffectsHandler(nSprmId) );
2668         boost::optional<PropertyIds> aPropertyId = pTextEffectsHandlerPtr->getGrabBagPropertyId();
2669         if(aPropertyId)
2670         {
2671             writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2672             if( pProperties.get())
2673             {
2674                 pProperties->resolve(*pTextEffectsHandlerPtr);
2675 
2676                 rContext->Insert(*aPropertyId, uno::makeAny(pTextEffectsHandlerPtr->getInteropGrabBag()), true, CHAR_GRAB_BAG);
2677             }
2678         }
2679     }
2680     break;
2681     case NS_ooxml::LN_CT_SdtPr_rPr:
2682     {
2683         // Make sure properties from a previous SDT are not merged with the current ones.
2684         m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
2685     }
2686     break;
2687     case NS_ooxml::LN_CT_TblPrBase_tblLook:
2688     {
2689         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2690         if (pProperties.get())
2691         {
2692             pProperties->resolve(*this);
2693             m_pImpl->getTableManager().finishTableLook();
2694         }
2695     }
2696     break;
2697     case NS_ooxml::LN_CT_TrPrBase_cnfStyle:
2698     {
2699         m_pImpl->enableInteropGrabBag("cnfStyle");
2700         resolveSprmProps(*this, rSprm);
2701 
2702         TablePropertyMapPtr pPropMap(new TablePropertyMap());
2703         pPropMap->Insert(PROP_ROW_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, ROW_GRAB_BAG);
2704         m_pImpl->getTableManager().insertRowProps(pPropMap);
2705 
2706         m_pImpl->disableInteropGrabBag();
2707     }
2708     break;
2709     case NS_ooxml::LN_CT_TcPrBase_cnfStyle:
2710     {
2711         m_pImpl->enableInteropGrabBag("cnfStyle");
2712         resolveSprmProps(*this, rSprm);
2713 
2714         TablePropertyMapPtr pPropMap(new TablePropertyMap());
2715         pPropMap->Insert(PROP_CELL_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, CELL_GRAB_BAG);
2716         m_pImpl->getTableManager().cellProps(pPropMap);
2717 
2718         m_pImpl->disableInteropGrabBag();
2719     }
2720     break;
2721     case NS_ooxml::LN_CT_PPrBase_cnfStyle:
2722     {
2723         m_pImpl->enableInteropGrabBag("cnfStyle");
2724         resolveSprmProps(*this, rSprm);
2725         rContext->Insert(PROP_PARA_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, PARA_GRAB_BAG);
2726         m_pImpl->disableInteropGrabBag();
2727     }
2728     break;
2729     case NS_ooxml::LN_EG_RunInnerContent_sym:
2730     {
2731         resolveSprmProps(*this, rSprm);
2732         SymbolData  aSymbolData = m_pImpl->GetSymbolData();
2733         uno::Any    aVal = uno::makeAny( aSymbolData.sFont );
2734         auto xFootnote = rContext->GetFootnote();
2735         if (!xFootnote.is() && m_pImpl->IsInCustomFootnote())
2736             xFootnote = m_pImpl->GetFootnoteContext()->GetFootnote();
2737         if (xFootnote.is())
2738         {
2739             // DOCX can have different labels for the footnote reference and the footnote area.
2740             // This skips the one from the footnote area and just uses the reference one.
2741             if (!m_pImpl->IsInFootOrEndnote())
2742             {
2743                 auto xAnchorRange = xFootnote->getAnchor();
2744                 auto xAnchorCursor(xAnchorRange->getText()->createTextCursorByRange(xAnchorRange));
2745 
2746                 // append a dummy character, so the following properties will be set as
2747                 // as SwpHints::SwTextAttr instead of the SwAttrSet of the paragraph,
2748                 // which would be removed by SwXText::Impl::finishOrAppendParagraph
2749                 xAnchorCursor->collapseToEnd();
2750                 uno::Reference<text::XTextRange> xHackRange(xAnchorCursor, uno::UNO_QUERY);
2751                 xHackRange->setString("x");
2752 
2753                 uno::Reference<beans::XPropertySet> xAnchorProps(xAnchorRange, uno::UNO_QUERY);
2754                 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), aVal);
2755                 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_ASIAN), aVal);
2756                 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_COMPLEX), aVal);
2757                 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_CHAR_SET), uno::makeAny(awt::CharSet::SYMBOL));
2758 
2759                 // remove the dummy char
2760                 xHackRange->setString("");
2761 
2762                 OUString sLabel = xFootnote->getLabel() + OUStringChar(aSymbolData.cSymbol);
2763                 xFootnote->setLabel(sLabel);
2764             }
2765         }
2766         else //it's a _real_ symbol
2767         {
2768             rContext->Insert(PROP_CHAR_FONT_NAME, aVal);
2769             rContext->Insert(PROP_CHAR_FONT_NAME_ASIAN, aVal);
2770             rContext->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aVal);
2771             rContext->Insert(PROP_CHAR_FONT_CHAR_SET, uno::makeAny(awt::CharSet::SYMBOL));
2772             utext( reinterpret_cast < const sal_uInt8 * >( &(aSymbolData.cSymbol) ), 1 );
2773         }
2774     }
2775     break;
2776     case NS_ooxml::LN_EG_RunInnerContent_ruby:
2777     {
2778         RubyInfo    aInfo ;
2779         m_pImpl->SetRubyInfo(aInfo);
2780     }
2781     break;
2782     case NS_ooxml::LN_CT_RubyPr:
2783     case NS_ooxml::LN_CT_Ruby_rt:
2784     case NS_ooxml::LN_CT_Ruby_rubyBase:
2785     {
2786         m_pImpl->SetRubySprmId(nSprmId);
2787         if (nSprmId == NS_ooxml::LN_CT_RubyPr)
2788         {
2789             resolveSprmProps(*this, rSprm);
2790         }
2791     }
2792     break;
2793     case NS_ooxml::LN_EG_RubyContent_r:
2794     {
2795         const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
2796         if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase)
2797         {
2798             rContext->Insert(PROP_RUBY_TEXT, uno::makeAny(aInfo.sRubyText));
2799             rContext->Insert(PROP_RUBY_STYLE, uno::makeAny(aInfo.sRubyStyle));
2800             rContext->Insert(PROP_RUBY_ADJUST, uno::makeAny(static_cast<sal_Int16>(ConversionHelper::convertRubyAlign(aInfo.nRubyAlign))));
2801             if ( aInfo.nRubyAlign == NS_ooxml::LN_Value_ST_RubyAlign_rightVertical )
2802                 rContext->Insert(PROP_RUBY_POSITION, uno::makeAny(css::text::RubyPosition::INTER_CHARACTER));
2803 
2804             m_pImpl->SetRubySprmId(0);
2805         }
2806     }
2807     break;
2808     case NS_ooxml::LN_CT_RubyPr_rubyAlign:
2809     case NS_ooxml::LN_CT_RubyPr_hps:
2810     case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
2811     {
2812         RubyInfo    aInfo = m_pImpl->GetRubyInfo();
2813         switch(nSprmId)
2814         {
2815             case NS_ooxml::LN_CT_RubyPr_rubyAlign:
2816                 aInfo.nRubyAlign = nIntValue;
2817                 break;
2818             case NS_ooxml::LN_CT_RubyPr_hps:
2819                 aInfo.nHps= nIntValue;
2820                 break;
2821             case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
2822                 aInfo.nHpsBaseText = nIntValue;
2823                 break;
2824         }
2825         m_pImpl->SetRubyInfo(aInfo);
2826     }
2827     break;
2828     case NS_ooxml::LN_CT_SmartTagRun_smartTagPr:
2829     {
2830         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2831         if (pProperties.get() && m_pImpl->GetTopContextType() == CONTEXT_PARAGRAPH)
2832             pProperties->resolve(m_pImpl->getSmartTagHandler());
2833     }
2834     break;
2835     case NS_ooxml::LN_CT_DocPartPr_name:
2836     {
2837         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2838         if (pProperties.get() != nullptr)
2839             pProperties->resolve(*this);
2840     }
2841     break;
2842     case NS_ooxml::LN_CT_DocPartPr_category:
2843     {
2844         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2845         if (pProperties.get() != nullptr)
2846             pProperties->resolve(*this);
2847     }
2848     break;
2849     case NS_ooxml::LN_CT_DocPartCategory_gallery:
2850     {
2851         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2852         if (pProperties.get() != nullptr)
2853             pProperties->resolve(*this);
2854     }
2855     break;
2856     default:
2857         {
2858 #ifdef DBG_UTIL
2859             TagLogger::getInstance().startElement("unhandled");
2860             TagLogger::getInstance().attribute("id", nSprmId);
2861             TagLogger::getInstance().attribute("name", rSprm.getName());
2862             TagLogger::getInstance().endElement();
2863 #endif
2864         }
2865     }
2866 }
2867 
setInTableStyleRunProps(bool bInTableStyleRunProps)2868 void DomainMapper::setInTableStyleRunProps(bool bInTableStyleRunProps)
2869 {
2870     m_pImpl->m_bInTableStyleRunProps = bInTableStyleRunProps;
2871 }
2872 
processDeferredCharacterProperties(const std::map<sal_Int32,uno::Any> & deferredCharacterProperties)2873 void DomainMapper::processDeferredCharacterProperties( const std::map< sal_Int32, uno::Any >& deferredCharacterProperties )
2874 {
2875     assert( m_pImpl->GetTopContextType() == CONTEXT_CHARACTER );
2876     PropertyMapPtr rContext = m_pImpl->GetTopContext();
2877     for( const auto& rProp : deferredCharacterProperties )
2878     {
2879         sal_Int32 Id = rProp.first;
2880         sal_Int32 nIntValue = 0;
2881         OUString sStringValue;
2882         rProp.second >>= nIntValue;
2883         rProp.second >>= sStringValue;
2884         switch( Id )
2885         {
2886         case NS_ooxml::LN_EG_RPrBase_position:
2887         {
2888             double nEscapement = 0;
2889             sal_Int8 nProp = 0;
2890             if ( nIntValue )
2891             {
2892                 nProp = 100;
2893                 double fFontSize = 0;
2894                 m_pImpl->GetAnyProperty(PROP_CHAR_HEIGHT, rContext) >>= fFontSize;
2895                 if ( fFontSize )
2896                     // nIntValue is in half-points, fontsize is in points, escapement is a percentage.
2897                     nEscapement = round( nIntValue/2.0 / fFontSize * 100 );
2898                 else
2899                     nEscapement = nIntValue > 0 ? DFLT_ESC_SUPER : DFLT_ESC_SUB;
2900             }
2901             // tdf#120412 up to 14400% (eg. 1584 pt with 11 pt letters)
2902             if ( nEscapement > MAX_ESC_POS )
2903                 nEscapement = MAX_ESC_POS;
2904             else if ( nEscapement < -MAX_ESC_POS )
2905                 nEscapement = -MAX_ESC_POS;
2906 
2907             rContext->Insert(PROP_CHAR_ESCAPEMENT,         uno::makeAny( sal_Int16(nEscapement) ) );
2908             rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT,  uno::makeAny( nProp ) );
2909         }
2910         break;
2911         default:
2912             SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" );
2913             break;
2914         }
2915     }
2916 }
2917 
lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref)2918 void DomainMapper::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref)
2919 {
2920     ref->resolve(*this);
2921 }
2922 
data(const sal_uInt8 *,size_t)2923 void DomainMapper::data(const sal_uInt8* /*buf*/, size_t /*len*/)
2924 {
2925 }
2926 
lcl_startSectionGroup()2927 void DomainMapper::lcl_startSectionGroup()
2928 {
2929     if (!m_pImpl->isInIndexContext() && !m_pImpl->isInBibliographyContext())
2930     {
2931         m_pImpl->PushProperties(CONTEXT_SECTION);
2932     }
2933     m_pImpl->SetIsFirstParagraphInSection(true);
2934     m_pImpl->SetIsFirstParagraphInSectionAfterRedline(true);
2935 }
2936 
lcl_endSectionGroup()2937 void DomainMapper::lcl_endSectionGroup()
2938 {
2939     if (!m_pImpl->isInIndexContext() && !m_pImpl->isInBibliographyContext())
2940     {
2941         m_pImpl->CheckUnregisteredFrameConversion();
2942         m_pImpl->ExecuteFrameConversion();
2943         // When pasting, it's fine to not have any paragraph inside the document at all.
2944         if (m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->IsNewDoc())
2945         {
2946             // This section has no paragraph at all (e.g. they are all actually in a frame).
2947             // If this section has a page break, there would be nothing to apply to the page
2948             // style, so force a dummy paragraph.
2949             lcl_startParagraphGroup();
2950             lcl_startCharacterGroup();
2951             sal_uInt8 const sBreak[] = { 0xd };
2952             lcl_text(sBreak, 1);
2953             lcl_endCharacterGroup();
2954             lcl_endParagraphGroup();
2955         }
2956         PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_SECTION);
2957         SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
2958         OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2959         if(pSectionContext)
2960         {
2961             pSectionContext->CloseSectionGroup( *m_pImpl );
2962             // Remove the dummy paragraph if added for
2963             // handling the section properties if section starts with a table
2964             if (m_pImpl->GetIsDummyParaAddedForTableInSection())
2965                 m_pImpl->RemoveDummyParaForTableInSection();
2966         }
2967         m_pImpl->SetIsTextFrameInserted( false );
2968         m_pImpl->PopProperties(CONTEXT_SECTION);
2969     }
2970 }
2971 
lcl_startParagraphGroup()2972 void DomainMapper::lcl_startParagraphGroup()
2973 {
2974     if (m_pImpl->hasTableManager())
2975         m_pImpl->getTableManager().startParagraphGroup();
2976     /*
2977      * Add new para properties only if paragraph is not split
2978      * or the top context is not of paragraph properties
2979      * Set mbIsSplitPara to false as it has been handled
2980      */
2981     if (!mbIsSplitPara)
2982         m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2983     mbIsSplitPara = false;
2984     if (m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) != m_pImpl->GetTopContext())
2985         m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2986 
2987     if (m_pImpl->GetTopContext())
2988     {
2989         if (!m_pImpl->IsInShape())
2990         {
2991             const OUString& sDefaultParaStyle = m_pImpl->GetDefaultParaStyleName();
2992             m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::makeAny( sDefaultParaStyle ) );
2993             m_pImpl->SetCurrentParaStyleName( sDefaultParaStyle );
2994         }
2995         if (m_pImpl->isBreakDeferred(PAGE_BREAK))
2996             m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
2997         else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
2998             m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
2999 
3000         if (m_pImpl->isParaSdtEndDeferred())
3001             m_pImpl->GetTopContext()->Insert(PROP_PARA_SDT_END_BEFORE, uno::makeAny(true), true, PARA_GRAB_BAG);
3002     }
3003     m_pImpl->SetIsFirstRun(true);
3004     m_pImpl->SetIsOutsideAParagraph(false);
3005     m_pImpl->clearDeferredBreaks();
3006     m_pImpl->setParaSdtEndDeferred(false);
3007 }
3008 
lcl_endParagraphGroup()3009 void DomainMapper::lcl_endParagraphGroup()
3010 {
3011     m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
3012     if (m_pImpl->hasTableManager())
3013        m_pImpl->getTableManager().endParagraphGroup();
3014     //frame conversion has to be executed after table conversion
3015     m_pImpl->ExecuteFrameConversion();
3016     m_pImpl->SetIsOutsideAParagraph(true);
3017 }
3018 
markLastParagraphInSection()3019 void DomainMapper::markLastParagraphInSection( )
3020 {
3021     m_pImpl->SetIsLastParagraphInSection( true );
3022 }
3023 
markLastSectionGroup()3024 void DomainMapper::markLastSectionGroup( )
3025 {
3026     m_pImpl->SetIsLastSectionGroup( true );
3027 }
3028 
lcl_startShape(uno::Reference<drawing::XShape> const & xShape)3029 void DomainMapper::lcl_startShape(uno::Reference<drawing::XShape> const& xShape)
3030 {
3031     assert(xShape.is());
3032 
3033     if (m_pImpl->GetTopContext())
3034     {
3035         // If there is a deferred page break, handle it now, so that the
3036         // started shape will be on the correct page.
3037         if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3038         {
3039             m_pImpl->clearDeferredBreak(PAGE_BREAK);
3040             lcl_startCharacterGroup();
3041             sal_uInt8 const sBreak[] = { 0xd };
3042             lcl_text(sBreak, 1);
3043             lcl_endCharacterGroup();
3044             lcl_endParagraphGroup();
3045             lcl_startParagraphGroup();
3046             m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
3047         }
3048         m_pImpl->PushShapeContext( xShape );
3049         lcl_startParagraphGroup();
3050     }
3051     else
3052         // No context? Then this image should not appear directly inside the
3053         // document, just save it for later usage.
3054         m_pImpl->PushPendingShape(xShape);
3055 
3056     m_pImpl->SetIsFirstParagraphInShape(true);
3057 }
3058 
lcl_endShape()3059 void DomainMapper::lcl_endShape( )
3060 {
3061     if (m_pImpl->GetTopContext())
3062     {
3063         // End the current table, if there are any. Otherwise the unavoidable
3064         // empty paragraph at the end of the shape text will cause problems: if
3065         // the shape text ends with a table, the extra paragraph will be
3066         // handled as an additional row of the ending table.
3067         if (m_pImpl->hasTableManager())
3068             m_pImpl->getTableManager().endTable();
3069 
3070         lcl_endParagraphGroup();
3071         m_pImpl->PopShapeContext( );
3072         // A shape is always inside a paragraph (anchored or inline).
3073         m_pImpl->SetIsOutsideAParagraph(false);
3074     }
3075 }
3076 
PushStyleSheetProperties(const PropertyMapPtr & pStyleProperties,bool bAffectTableMngr)3077 void DomainMapper::PushStyleSheetProperties( const PropertyMapPtr& pStyleProperties, bool bAffectTableMngr )
3078 {
3079     m_pImpl->PushStyleProperties( pStyleProperties );
3080     if ( bAffectTableMngr )
3081         m_pImpl->getTableManager( ).SetStyleProperties( pStyleProperties );
3082 }
3083 
PopStyleSheetProperties(bool bAffectTableMngr)3084 void DomainMapper::PopStyleSheetProperties( bool bAffectTableMngr )
3085 {
3086     m_pImpl->PopProperties( CONTEXT_STYLESHEET );
3087     if ( bAffectTableMngr )
3088     {
3089         PropertyMapPtr emptyPtr;
3090         m_pImpl->getTableManager( ).SetStyleProperties( emptyPtr );
3091     }
3092 }
3093 
PushListProperties(const::tools::SvRef<PropertyMap> & pListProperties)3094 void DomainMapper::PushListProperties( const ::tools::SvRef<PropertyMap>& pListProperties )
3095 {
3096     m_pImpl->PushListProperties( pListProperties );
3097 }
3098 
PopListProperties()3099 void DomainMapper::PopListProperties()
3100 {
3101     m_pImpl->PopProperties( CONTEXT_LIST );
3102 }
3103 
lcl_startCharacterGroup()3104 void DomainMapper::lcl_startCharacterGroup()
3105 {
3106     m_pImpl->PushProperties(CONTEXT_CHARACTER);
3107     if (m_pImpl->isSdtEndDeferred())
3108     {
3109         // Fields have an empty character group before the real one, so don't
3110         // call setSdtEndDeferred(false) here, that will happen only in lcl_utext().
3111         m_pImpl->GetTopContext()->Insert(PROP_SDT_END_BEFORE, uno::makeAny(true), true, CHAR_GRAB_BAG);
3112     }
3113 }
3114 
lcl_endCharacterGroup()3115 void DomainMapper::lcl_endCharacterGroup()
3116 {
3117     if (m_pImpl->CheckFootnoteStyle())
3118     {
3119         m_pImpl->SetCheckFootnoteStyle(m_pImpl->IsInCustomFootnote());
3120         m_pImpl->SetHasFootnoteStyle(false);
3121     }
3122     m_pImpl->PopProperties(CONTEXT_CHARACTER);
3123 }
3124 
lcl_text(const sal_uInt8 * data_,size_t len)3125 void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
3126 {
3127     //TODO: Determine the right text encoding (FIB?)
3128     OUString sText( reinterpret_cast<const char*>(data_), len, RTL_TEXTENCODING_MS_1252 );
3129 #ifdef DBG_UTIL
3130     TagLogger::getInstance().startElement("text");
3131     TagLogger::getInstance().chars(sText);
3132     TagLogger::getInstance().endElement();
3133 #endif
3134 
3135     try
3136     {
3137         if(len == 1)
3138         {
3139             switch(*data_)
3140             {
3141                 case 0x02: return; //footnote character
3142                 case 0x08: // Lock field if in field context
3143                     if (m_pImpl->IsOpenField())
3144                         m_pImpl->SetFieldLocked();
3145                     return;
3146                 case 0x0c: //page break
3147                     m_pImpl->deferBreak(PAGE_BREAK);
3148                     return;
3149                 case 0x0e: //column break
3150                     m_pImpl->deferBreak(COLUMN_BREAK);
3151                     return;
3152                 case 0x07:
3153                     m_pImpl->getTableManager().text(data_, len);
3154                     return;
3155                 case 0x0d:
3156                 {
3157                     PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3158                     if (pContext && m_pImpl->isBreakDeferred(COLUMN_BREAK))
3159                     {
3160                         pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
3161                         m_pImpl->clearDeferredBreak(COLUMN_BREAK);
3162                     }
3163                     finishParagraph();
3164                     return;
3165                 }
3166                 case cFieldStart:
3167                     m_pImpl->PushFieldContext();
3168                     return;
3169                 case cFieldSep:
3170                     // delimiter not necessarily available
3171                     // appears only if field contains further content
3172                     m_pImpl->CloseFieldCommand();
3173                     return;
3174                 case cFieldEnd:
3175                     // In case there isn't any field separator.
3176                     if ( m_pImpl->IsOpenFieldCommand() )
3177                         m_pImpl->CloseFieldCommand();
3178                     m_pImpl->PopFieldContext();
3179                     return;
3180                 default:
3181                     break;
3182             }
3183         }
3184 
3185         // GetTopContext() is changed by inserted breaks, but we want to keep the current context
3186         PropertyMapPtr pContext = m_pImpl->GetTopContext();
3187         if (!m_pImpl->GetFootnoteContext())
3188         {
3189             if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3190                 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
3191             else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3192                 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
3193             m_pImpl->clearDeferredBreaks();
3194         }
3195 
3196         if (pContext && pContext->GetFootnote().is() && m_pImpl->IsInCustomFootnote())
3197         {
3198             pContext->GetFootnote()->setLabel(sText);
3199             m_pImpl->EndCustomFootnote();
3200             //otherwise ignore sText
3201         }
3202         else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields())
3203         {
3204             m_pImpl->AppendFieldCommand(sText);
3205         }
3206         else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
3207              /*depending on the success of the field insert operation this result will be
3208               set at the field or directly inserted into the text*/
3209             m_pImpl->AppendFieldResult(sText);
3210         else
3211         {
3212             if (pContext == nullptr)
3213                 pContext = new PropertyMap();
3214 
3215             m_pImpl->appendTextPortion( sText, pContext );
3216         }
3217     }
3218     catch( const uno::RuntimeException& )
3219     {
3220         TOOLS_WARN_EXCEPTION("writerfilter", "");
3221     }
3222 }
3223 
lcl_positionOffset(const OUString & rText,bool bVertical)3224 void DomainMapper::lcl_positionOffset(const OUString& rText, bool bVertical)
3225 {
3226     if (bVertical)
3227         m_pImpl->m_aPositionOffsets.second = rText;
3228     else
3229         m_pImpl->m_aPositionOffsets.first = rText;
3230 }
3231 
getPositionOffset()3232 awt::Point DomainMapper::getPositionOffset()
3233 {
3234     awt::Point aRet;
3235     aRet.X = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.first.toInt32());
3236     aRet.Y = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.second.toInt32());
3237     return aRet;
3238 }
3239 
lcl_align(const OUString & rText,bool bVertical)3240 void DomainMapper::lcl_align(const OUString& rText, bool bVertical)
3241 {
3242     if (bVertical)
3243         m_pImpl->m_aAligns.second = rText;
3244     else
3245         m_pImpl->m_aAligns.first = rText;
3246 }
3247 
lcl_positivePercentage(const OUString & rText)3248 void DomainMapper::lcl_positivePercentage(const OUString& rText)
3249 {
3250     m_pImpl->m_aPositivePercentages.push(rText);
3251 }
3252 
lcl_utext(const sal_uInt8 * data_,size_t len)3253 void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
3254 {
3255     // All these fixed values are defined as static const sal_Unicode codepoints in the fast parser,
3256     // like uFtnEdnRef = 0x2, uFtnEdnSep = 0x3, ... and have a len of 1, if they aren't valid unicode.
3257 
3258     OUString sText(reinterpret_cast<const sal_Unicode *>(data_), len);
3259     const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
3260     if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt)
3261     {
3262         PropertyMapPtr pContext = m_pImpl->GetTopContext();
3263         PropertyValueVector_t aProps = comphelper::sequenceToContainer< PropertyValueVector_t >(pContext->GetPropertyValues());
3264         OUString sStyle = getOrCreateCharStyle(aProps, /*bAlwaysCreate=*/false);
3265         m_pImpl->SetRubyText(sText,sStyle);
3266         return;
3267     }
3268 
3269     if (len == 1)
3270     {
3271         // If the footnote contains a Footnote Reference Mark, it can't be a custom footnote
3272         // ******
3273         // This code block is wrong, as it should also be in m_pImpl->IsInFootOrEndnote().
3274         // The main problem is that
3275         //
3276         //  assert(len != 1 || sText[0] != 0x2)
3277         //
3278         // is triggered by the unit test SwLayoutWriter::testForcepoint75, so all these pseudo
3279         // value handling is broken.
3280         // But this is just a symptom, as I guess it's possible to generate broken DOCX documents,
3281         // which might be problematic, triggering *funny* code paths left and right.
3282         // ******
3283         if (sText[0] == 0x2)
3284         {
3285             m_pImpl->EndCustomFootnote();
3286             return;
3287         }
3288 
3289         if (m_pImpl->IsInCustomFootnote())
3290         {
3291             if (sText[0] != 0xd && sText[0] != 0x3)
3292             {
3293                 // DOCX can have different labels for the footnote reference and the footnote area.
3294                 // This skips the one from the footnote area and just uses the reference one.
3295                 if (!m_pImpl->IsInFootOrEndnote())
3296                 {
3297                     if (PropertyMapPtr pFootnoteContext = m_pImpl->GetFootnoteContext())
3298                     {
3299                         auto xFootnote = pFootnoteContext->GetFootnote();
3300                         xFootnote->setLabel(xFootnote->getLabel() + sText);
3301                     }
3302                 }
3303                 return;
3304             }
3305             else
3306                 m_pImpl->SetHasFootnoteStyle(true);
3307         }
3308     }
3309 
3310     if (m_pImpl->isSdtEndDeferred())
3311     {
3312         // In case we have a field context, then save the property there, so
3313         // SDT's ending right before a field start are handled as well.
3314         PropertyMapPtr pContext = m_pImpl->GetTopContext();
3315         if (m_pImpl->IsOpenField())
3316             pContext = m_pImpl->GetTopFieldContext()->getProperties();
3317         pContext->Insert(PROP_SDT_END_BEFORE, uno::makeAny(true), true, CHAR_GRAB_BAG);
3318         m_pImpl->setSdtEndDeferred(false);
3319     }
3320 
3321     bool bNewLine = len == 1 && (sText[0] == 0x0d || sText[0] == 0x07);
3322     if (m_pImpl->m_pSdtHelper->isInsideDropDownControl())
3323     {
3324         if (bNewLine)
3325             // Dropdown control has single-line texts, so in case of newline, create the control.
3326             m_pImpl->m_pSdtHelper->createDropDownControl();
3327         else
3328         {
3329             m_pImpl->m_pSdtHelper->getSdtTexts().append(sText);
3330             return;
3331         }
3332     }
3333     else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty())
3334     {
3335          // Ignore grabbag when we have a date field, it can conflict during export
3336         if(m_pImpl->m_pSdtHelper->validateDateFormat())
3337         {
3338             m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3339         }
3340         else
3341         {
3342 
3343             // there are unsupported SDT properties in the document
3344             // save them in the paragraph interop grab bag
3345             if (m_pImpl->IsDiscardHeaderFooter())
3346             {
3347                 // Unless we're supposed to ignore this header/footer.
3348                 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3349                 return;
3350             }
3351             if((m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") ||
3352                     m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") ||
3353                     m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") ||
3354                     m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") ||
3355                     (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") &&
3356                             m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph())
3357             {
3358                 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER);
3359 
3360                 if (m_pImpl->IsOpenField())
3361                     // We have a field, insert the SDT properties to the field's grab-bag, so they won't be lost.
3362                     pContext = m_pImpl->GetTopFieldContext()->getProperties();
3363 
3364                 pContext->Insert(PROP_SDTPR, uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, CHAR_GRAB_BAG);
3365             }
3366             else
3367                 m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR,
3368                         uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, PARA_GRAB_BAG);
3369         }
3370     }
3371     else if (len == 1 && sText[0] == 0x03)
3372     {
3373         // This is the uFtnEdnSep, remember that the document has a separator.
3374         m_pImpl->m_bHasFtnSep = true;
3375         return;
3376     }
3377     else if (len == 1 && sText[0] == '\t' )
3378     {
3379         if ( m_pImpl->m_bCheckFirstFootnoteTab && m_pImpl->IsInFootOrEndnote() )
3380         {
3381             // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent
3382             m_pImpl->m_bCheckFirstFootnoteTab = false;
3383             sal_Int32 nFirstLineIndent = 0;
3384             m_pImpl->GetAnyProperty(PROP_PARA_FIRST_LINE_INDENT, m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)) >>= nFirstLineIndent;
3385             if ( nFirstLineIndent < 0 )
3386                 m_pImpl->m_bIgnoreNextTab = true;
3387         }
3388 
3389         if ( m_pImpl->m_bIgnoreNextTab )
3390         {
3391             m_pImpl->m_bIgnoreNextTab = false;
3392             return;
3393         }
3394     }
3395     else if (m_pImpl->m_pSdtHelper->validateDateFormat())
3396     {
3397         if(IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
3398         {
3399             m_pImpl->m_pSdtHelper->getDateFormat().truncate();
3400             m_pImpl->m_pSdtHelper->getLocale().truncate();
3401             return;
3402         }
3403     }
3404     if (!m_pImpl->hasTableManager())
3405         return;
3406 
3407     SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
3408     if ( eSkip == SkipFootnoteSeparator::ON || eSkip == SkipFootnoteSeparator::SKIPPING )
3409     {
3410         m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
3411         return;
3412     }
3413 
3414     try
3415     {
3416         m_pImpl->getTableManager().utext(data_, len);
3417 
3418         if (bNewLine)
3419         {
3420             const bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection();
3421             const bool bSingleParagraphAfterRedline = m_pImpl->GetIsFirstParagraphInSection(true) && m_pImpl->GetIsLastParagraphInSection();
3422             PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3423             if (!m_pImpl->GetFootnoteContext())
3424             {
3425                 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3426                 {
3427                     if (m_pImpl->GetSettingsTable()->GetSplitPgBreakAndParaMark())
3428                     {
3429                         if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
3430                         {
3431                             m_pImpl->m_bIsSplitPara = true;
3432                             finishParagraph();
3433                             lcl_startParagraphGroup();
3434                         }
3435 
3436 
3437                         pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
3438                         m_pImpl->clearDeferredBreaks();
3439                     }
3440                 }
3441                 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3442                 {
3443                     if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
3444                     {
3445                         mbIsSplitPara = true;
3446                         finishParagraph();
3447                         lcl_startParagraphGroup();
3448                     }
3449 
3450                     pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
3451                     m_pImpl->clearDeferredBreaks();
3452                 }
3453             }
3454 
3455             // If the paragraph contains only the section properties and it has
3456             // no runs, we should not create a paragraph for it in Writer, unless that would remove the whole section.
3457             SectionPropertyMap* pSectionContext = m_pImpl->GetSectionContext();
3458             bool bRemove = (!m_pImpl->GetParaChanged() && m_pImpl->GetRemoveThisPara()) ||
3459                            (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr()
3460                             && !bSingleParagraphAfterRedline
3461                             && !m_pImpl->GetIsDummyParaAddedForTableInSection()
3462                             && !( pSectionContext && pSectionContext->GetBreakType() != -1 && pContext && pContext->isSet(PROP_BREAK_TYPE) )
3463                             && !m_pImpl->GetIsPreviousParagraphFramed());
3464 
3465             const bool bNoNumbering = bRemove || (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && bSingleParagraph);
3466             PropertyMapPtr xContext = bNoNumbering ? m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) : PropertyMapPtr();
3467             if (xContext)
3468             {
3469                 // tdf#97417 delete numbering of the paragraph
3470                 // it will be deleted anyway, and the numbering would be copied
3471                 // to the next paragraph in sw SplitNode and then be applied to
3472                 // every following paragraph
3473                 xContext->Erase(PROP_NUMBERING_RULES);
3474                 xContext->Erase(PROP_NUMBERING_LEVEL);
3475             }
3476             m_pImpl->SetParaSectpr(false);
3477             finishParagraph(bRemove);
3478             if (bRemove)
3479                 m_pImpl->RemoveLastParagraph();
3480         }
3481         else
3482         {
3483             // GetTopContext() is changed by inserted breaks, but we want to keep the current context
3484             PropertyMapPtr pContext = m_pImpl->GetTopContext();
3485             if (!m_pImpl->GetFootnoteContext())
3486             {
3487                 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3488                 {
3489                     /* If PAGEBREAK appears in first paragraph of the section or
3490                      * after first run of any paragraph then need to split paragraph
3491                      * to handle it properly.
3492                      */
3493                     if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
3494                     {
3495                         m_pImpl->m_bIsSplitPara = true;
3496                         finishParagraph();
3497                         lcl_startParagraphGroup();
3498                     }
3499                     m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
3500                 }
3501                 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3502                 {
3503                     if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
3504                     {
3505                         mbIsSplitPara = true;
3506                         finishParagraph();
3507                         lcl_startParagraphGroup();
3508                     }
3509                     m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
3510                 }
3511                 m_pImpl->clearDeferredBreaks();
3512             }
3513 
3514             if (pContext && pContext->GetFootnote().is())
3515             {
3516                 pContext->GetFootnote()->setLabel( sText );
3517                 //otherwise ignore sText
3518             }
3519             else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields())
3520             {
3521                 m_pImpl->AppendFieldCommand(sText);
3522             }
3523             else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
3524                 /*depending on the success of the field insert operation this result will be
3525                   set at the field or directly inserted into the text*/
3526                 m_pImpl->AppendFieldResult(sText);
3527             else
3528             {
3529                 if (pContext == nullptr)
3530                     pContext = new PropertyMap();
3531 
3532                 m_pImpl->appendTextPortion( sText, pContext );
3533             }
3534 
3535         }
3536         m_pImpl->SetIsFirstRun(false);
3537     }
3538     catch( const uno::RuntimeException& )
3539     {
3540     }
3541 }
3542 
lcl_props(writerfilter::Reference<Properties>::Pointer_t ref)3543 void DomainMapper::lcl_props(writerfilter::Reference<Properties>::Pointer_t ref)
3544 {
3545     ref->resolve(*this);
3546 }
3547 
lcl_table(Id name,writerfilter::Reference<Table>::Pointer_t ref)3548 void DomainMapper::lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t ref)
3549 {
3550     m_pImpl->SetAnyTableImport(true);
3551     switch(name)
3552     {
3553     case NS_ooxml::LN_FONTTABLE:
3554 
3555         // create a font table object that listens to the attributes
3556         // each entry call inserts a new font entry
3557         ref->resolve( *m_pImpl->GetFontTable() );
3558         break;
3559     case NS_ooxml::LN_STYLESHEET:
3560         //same as above to import style sheets
3561         m_pImpl->SetStyleSheetImport( true );
3562         ref->resolve( *m_pImpl->GetStyleSheetTable() );
3563         m_pImpl->GetStyleSheetTable()->ApplyStyleSheets(m_pImpl->GetFontTable());
3564         m_pImpl->SetStyleSheetImport( false );
3565         break;
3566     case NS_ooxml::LN_NUMBERING:
3567         {
3568 
3569             //the same for list tables
3570             ref->resolve( *m_pImpl->GetListTable() );
3571             m_pImpl->GetListTable( )->CreateNumberingRules( );
3572         }
3573         break;
3574     case NS_ooxml::LN_THEMETABLE:
3575         m_pImpl->GetThemeTable()->setThemeFontLangProperties(
3576                 m_pImpl->GetSettingsTable()->GetThemeFontLangProperties() );
3577         ref->resolve ( *m_pImpl->GetThemeTable() );
3578     break;
3579     case NS_ooxml::LN_settings_settings:
3580         ref->resolve ( *m_pImpl->GetSettingsTable() );
3581         m_pImpl->ApplySettingsTable();
3582     break;
3583     default:
3584         OSL_FAIL( "which table is to be filled here?");
3585     }
3586     m_pImpl->SetAnyTableImport(false);
3587 }
3588 
lcl_substream(Id rName,::writerfilter::Reference<Stream>::Pointer_t ref)3589 void DomainMapper::lcl_substream(Id rName, ::writerfilter::Reference<Stream>::Pointer_t ref)
3590 {
3591     m_pImpl->substream(rName, ref);
3592 }
3593 
lcl_startGlossaryEntry()3594 void DomainMapper::lcl_startGlossaryEntry()
3595 {
3596     uno::Reference< text::XTextRange > xTextRange =  GetCurrentTextRange();
3597     m_pImpl->setGlossaryEntryStart(xTextRange);
3598 }
3599 
lcl_endGlossaryEntry()3600 void DomainMapper::lcl_endGlossaryEntry()
3601 {
3602     m_pImpl->appendGlossaryEntry();
3603 }
3604 
handleUnderlineType(const Id nId,const::tools::SvRef<PropertyMap> & rContext)3605 void DomainMapper::handleUnderlineType(const Id nId, const ::tools::SvRef<PropertyMap>& rContext)
3606 {
3607     sal_Int16 nUnderline = awt::FontUnderline::NONE;
3608 
3609     switch (nId)
3610     {
3611     case NS_ooxml::LN_Value_ST_Underline_none:
3612         nUnderline = awt::FontUnderline::NONE;
3613         break;
3614     case NS_ooxml::LN_Value_ST_Underline_words:
3615         rContext->Insert(PROP_CHAR_WORD_MODE, uno::makeAny(true));
3616         [[fallthrough]];
3617     case NS_ooxml::LN_Value_ST_Underline_single:
3618         nUnderline = awt::FontUnderline::SINGLE;
3619         break;
3620     case NS_ooxml::LN_Value_ST_Underline_double:
3621         nUnderline = awt::FontUnderline::DOUBLE;
3622         break;
3623     case NS_ooxml::LN_Value_ST_Underline_dotted:
3624         nUnderline = awt::FontUnderline::DOTTED;
3625         break;
3626     case NS_ooxml::LN_Value_ST_Underline_dash:
3627         nUnderline = awt::FontUnderline::DASH;
3628         break;
3629     case NS_ooxml::LN_Value_ST_Underline_dotDash:
3630         nUnderline = awt::FontUnderline::DASHDOT;
3631         break;
3632     case NS_ooxml::LN_Value_ST_Underline_dotDotDash:
3633         nUnderline = awt::FontUnderline::DASHDOTDOT;
3634         break;
3635     case NS_ooxml::LN_Value_ST_Underline_thick:
3636         nUnderline = awt::FontUnderline::BOLD;
3637         break;
3638     case NS_ooxml::LN_Value_ST_Underline_wave:
3639         nUnderline = awt::FontUnderline::WAVE;
3640         break;
3641     case NS_ooxml::LN_Value_ST_Underline_dottedHeavy:
3642         nUnderline = awt::FontUnderline::BOLDDOTTED;
3643         break;
3644     case NS_ooxml::LN_Value_ST_Underline_dashedHeavy:
3645         nUnderline = awt::FontUnderline::BOLDDASH;
3646         break;
3647     case NS_ooxml::LN_Value_ST_Underline_dashLong:
3648         nUnderline = awt::FontUnderline::LONGDASH;
3649         break;
3650     case NS_ooxml::LN_Value_ST_Underline_dashLongHeavy:
3651         nUnderline = awt::FontUnderline::BOLDLONGDASH;
3652         break;
3653     case NS_ooxml::LN_Value_ST_Underline_dashDotHeavy:
3654         nUnderline = awt::FontUnderline::BOLDDASHDOT;
3655         break;
3656     case NS_ooxml::LN_Value_ST_Underline_dashDotDotHeavy:
3657         nUnderline = awt::FontUnderline::BOLDDASHDOTDOT;
3658         break;
3659     case NS_ooxml::LN_Value_ST_Underline_wavyHeavy:
3660         nUnderline = awt::FontUnderline::BOLDWAVE;
3661         break;
3662     case NS_ooxml::LN_Value_ST_Underline_wavyDouble:
3663         nUnderline = awt::FontUnderline::DOUBLEWAVE;
3664         break;
3665     }
3666     rContext->Insert(PROP_CHAR_UNDERLINE, uno::makeAny(nUnderline));
3667 }
3668 
handleParaJustification(const sal_Int32 nIntValue,const::tools::SvRef<PropertyMap> & rContext,const bool bExchangeLeftRight)3669 void DomainMapper::handleParaJustification(const sal_Int32 nIntValue, const ::tools::SvRef<PropertyMap>& rContext, const bool bExchangeLeftRight)
3670 {
3671     style::ParagraphAdjust nAdjust = style::ParagraphAdjust_LEFT;
3672     style::ParagraphAdjust nLastLineAdjust = style::ParagraphAdjust_LEFT;
3673     OUString aStringValue = "left";
3674     switch(nIntValue)
3675     {
3676     case NS_ooxml::LN_Value_ST_Jc_center:
3677         nAdjust = style::ParagraphAdjust_CENTER;
3678         aStringValue = "center";
3679         break;
3680     case NS_ooxml::LN_Value_ST_Jc_right:
3681     case NS_ooxml::LN_Value_ST_Jc_end:
3682         nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_LEFT : style::ParagraphAdjust_RIGHT;
3683         aStringValue = "right";
3684         break;
3685     case NS_ooxml::LN_Value_ST_Jc_distribute:
3686         nLastLineAdjust = style::ParagraphAdjust_BLOCK;
3687         [[fallthrough]];
3688     case NS_ooxml::LN_Value_ST_Jc_both:
3689         nAdjust = style::ParagraphAdjust_BLOCK;
3690         aStringValue = "both";
3691         break;
3692     case NS_ooxml::LN_Value_ST_Jc_left:
3693     case NS_ooxml::LN_Value_ST_Jc_start:
3694     default:
3695         nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
3696         break;
3697     }
3698     rContext->Insert( PROP_PARA_ADJUST, uno::makeAny( nAdjust ) );
3699     rContext->Insert( PROP_PARA_LAST_LINE_ADJUST, uno::makeAny( nLastLineAdjust ) );
3700     m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "jc", aStringValue);
3701 }
3702 
getColorFromId(const Id nId,sal_Int32 & nColor)3703 bool DomainMapper::getColorFromId(const Id nId, sal_Int32 &nColor)
3704 {
3705     nColor = 0;
3706     if ((nId < NS_ooxml::LN_Value_ST_HighlightColor_black) || (nId > NS_ooxml::LN_Value_ST_HighlightColor_lightGray))
3707         return false;
3708 
3709     switch (nId)
3710     {
3711     case NS_ooxml::LN_Value_ST_HighlightColor_black: nColor=0x000000; break;
3712     case NS_ooxml::LN_Value_ST_HighlightColor_blue: nColor=0x0000ff; break;
3713     case NS_ooxml::LN_Value_ST_HighlightColor_cyan: nColor=0x00ffff; break;
3714     case NS_ooxml::LN_Value_ST_HighlightColor_green: nColor=0x00ff00; break;
3715     case NS_ooxml::LN_Value_ST_HighlightColor_magenta: nColor=0xff00ff; break;
3716     case NS_ooxml::LN_Value_ST_HighlightColor_red: nColor=0xff0000; break;
3717     case NS_ooxml::LN_Value_ST_HighlightColor_yellow: nColor=0xffff00; break;
3718     case NS_ooxml::LN_Value_ST_HighlightColor_white: nColor=0xffffff; break;
3719     case NS_ooxml::LN_Value_ST_HighlightColor_darkBlue: nColor=0x000080;  break;
3720     case NS_ooxml::LN_Value_ST_HighlightColor_darkCyan: nColor=0x008080; break;
3721     case NS_ooxml::LN_Value_ST_HighlightColor_darkGreen: nColor=0x008000; break;
3722     case NS_ooxml::LN_Value_ST_HighlightColor_darkMagenta: nColor=0x800080; break;
3723     case NS_ooxml::LN_Value_ST_HighlightColor_darkRed: nColor=0x800000; break;
3724     case NS_ooxml::LN_Value_ST_HighlightColor_darkYellow: nColor=0x808000; break;
3725     case NS_ooxml::LN_Value_ST_HighlightColor_darkGray: nColor=0x808080; break;
3726     case NS_ooxml::LN_Value_ST_HighlightColor_lightGray: nColor=0xC0C0C0; break;
3727     default:
3728         return false;
3729     }
3730     return true;
3731 }
3732 
getEmphasisValue(const sal_Int32 nIntValue)3733 sal_Int16 DomainMapper::getEmphasisValue(const sal_Int32 nIntValue)
3734 {
3735     switch (nIntValue)
3736     {
3737     case NS_ooxml::LN_Value_ST_Em_dot:
3738         return text::FontEmphasis::DOT_ABOVE;
3739     case NS_ooxml::LN_Value_ST_Em_comma:
3740         return text::FontEmphasis::ACCENT_ABOVE;
3741     case NS_ooxml::LN_Value_ST_Em_circle:
3742         return text::FontEmphasis::CIRCLE_ABOVE;
3743     case NS_ooxml::LN_Value_ST_Em_underDot:
3744         return text::FontEmphasis::DOT_BELOW;
3745     default:
3746         return text::FontEmphasis::NONE;
3747     }
3748 }
3749 
getBracketStringFromEnum(const sal_Int32 nIntValue,const bool bIsPrefix)3750 OUString DomainMapper::getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix)
3751 {
3752     switch(nIntValue)
3753     {
3754     case NS_ooxml::LN_Value_ST_CombineBrackets_round:
3755         if (bIsPrefix)
3756             return "(";
3757         return ")";
3758 
3759     case NS_ooxml::LN_Value_ST_CombineBrackets_square:
3760         if (bIsPrefix)
3761             return "[";
3762         return "]";
3763 
3764     case NS_ooxml::LN_Value_ST_CombineBrackets_angle:
3765         if (bIsPrefix)
3766             return "<";
3767         return ">";
3768 
3769     case NS_ooxml::LN_Value_ST_CombineBrackets_curly:
3770         if (bIsPrefix)
3771             return "{";
3772         return "}";
3773 
3774     case NS_ooxml::LN_Value_ST_CombineBrackets_none:
3775     default:
3776         return OUString();
3777     }
3778 }
3779 
getTabAlignFromValue(const sal_Int32 nIntValue)3780 style::TabAlign DomainMapper::getTabAlignFromValue(const sal_Int32 nIntValue)
3781 {
3782     switch (nIntValue)
3783     {
3784     case NS_ooxml::LN_Value_ST_TabJc_start:
3785     case NS_ooxml::LN_Value_ST_TabJc_left:
3786     case NS_ooxml::LN_Value_ST_TabJc_bar: // bar not supported
3787     case NS_ooxml::LN_Value_ST_TabJc_num: // num not supported
3788         return style::TabAlign_LEFT;
3789     case NS_ooxml::LN_Value_ST_TabJc_center:
3790         return style::TabAlign_CENTER;
3791     case NS_ooxml::LN_Value_ST_TabJc_end:
3792     case NS_ooxml::LN_Value_ST_TabJc_right:
3793         return style::TabAlign_RIGHT;
3794     case NS_ooxml::LN_Value_ST_TabJc_decimal:
3795         return style::TabAlign_DECIMAL;
3796     }
3797     return style::TabAlign_LEFT;
3798 }
3799 
getFillCharFromValue(const sal_Int32 nIntValue)3800 sal_Unicode DomainMapper::getFillCharFromValue(const sal_Int32 nIntValue)
3801 {
3802     switch (nIntValue)
3803     {
3804     case NS_ooxml::LN_Value_ST_TabTlc_dot:
3805         return u'.';
3806     case NS_ooxml::LN_Value_ST_TabTlc_hyphen:
3807         return u'-';
3808     case NS_ooxml::LN_Value_ST_TabTlc_underscore:
3809     case NS_ooxml::LN_Value_ST_TabTlc_heavy: // FIXME ???
3810         return u'_';
3811     case NS_ooxml::LN_Value_ST_TabTlc_middleDot: // middleDot
3812         return u'\x00b7';
3813     case NS_ooxml::LN_Value_ST_TabTlc_none:
3814     default:
3815         return u' '; // blank space
3816     }
3817 }
3818 
IsOOXMLImport() const3819 bool DomainMapper::IsOOXMLImport() const
3820 {
3821     return m_pImpl->IsOOXMLImport();
3822 }
3823 
IsRTFImport() const3824 bool DomainMapper::IsRTFImport() const
3825 {
3826     return m_pImpl->IsRTFImport();
3827 }
3828 
GetTextFactory() const3829 uno::Reference < lang::XMultiServiceFactory > const & DomainMapper::GetTextFactory() const
3830 {
3831     return m_pImpl->GetTextFactory();
3832 }
3833 
GetCurrentTextRange()3834 uno::Reference< text::XTextRange > DomainMapper::GetCurrentTextRange()
3835 {
3836     return m_pImpl->GetTopTextAppend()->getEnd();
3837 }
3838 
getOrCreateCharStyle(PropertyValueVector_t & rCharProperties,bool bAlwaysCreate)3839 OUString DomainMapper::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate )
3840 {
3841     StyleSheetTablePtr pStyleSheets = m_pImpl->GetStyleSheetTable();
3842     return pStyleSheets->getOrCreateCharStyle( rCharProperties, bAlwaysCreate );
3843 }
3844 
GetStyleSheetTable()3845 StyleSheetTablePtr const & DomainMapper::GetStyleSheetTable( )
3846 {
3847     return m_pImpl->GetStyleSheetTable( );
3848 }
3849 
graphicZOrderHelper()3850 GraphicZOrderHelper* DomainMapper::graphicZOrderHelper()
3851 {
3852     if (zOrderHelper == nullptr)
3853         zOrderHelper.reset( new GraphicZOrderHelper );
3854     return zOrderHelper.get();
3855 }
3856 
GetGraphicNamingHelper()3857 GraphicNamingHelper& DomainMapper::GetGraphicNamingHelper()
3858 {
3859     if (m_pGraphicNamingHelper == nullptr)
3860         m_pGraphicNamingHelper.reset(new GraphicNamingHelper());
3861     return *m_pGraphicNamingHelper;
3862 }
3863 
PopPendingShape()3864 uno::Reference<drawing::XShape> DomainMapper::PopPendingShape()
3865 {
3866     return m_pImpl->PopPendingShape();
3867 }
3868 
IsInHeaderFooter() const3869 bool DomainMapper::IsInHeaderFooter() const
3870 {
3871     return m_pImpl->IsInHeaderFooter();
3872 }
3873 
IsInTable() const3874 bool DomainMapper::IsInTable() const
3875 {
3876     return m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell();
3877 }
3878 
IsStyleSheetImport() const3879 bool DomainMapper::IsStyleSheetImport() const
3880 {
3881     return m_pImpl->IsStyleSheetImport();
3882 }
3883 
enableInteropGrabBag(const OUString & aName)3884 void DomainMapper::enableInteropGrabBag(const OUString& aName)
3885 {
3886     m_pImpl->m_aInteropGrabBagName = aName;
3887 }
3888 
getInteropGrabBag()3889 beans::PropertyValue DomainMapper::getInteropGrabBag()
3890 {
3891     beans::PropertyValue aRet;
3892     aRet.Name = m_pImpl->m_aInteropGrabBagName;
3893     aRet.Value <<= comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag);
3894 
3895     m_pImpl->m_aInteropGrabBag.clear();
3896     m_pImpl->m_aInteropGrabBagName.clear();
3897     return aRet;
3898 }
3899 
HandleRedline(Sprm & rSprm)3900 void DomainMapper::HandleRedline( Sprm& rSprm )
3901 {
3902     sal_uInt32 nSprmId = rSprm.getId();
3903 
3904     m_pImpl->AddNewRedline( nSprmId );
3905 
3906     if (nSprmId == NS_ooxml::LN_CT_PPr_pPrChange)
3907     {
3908         m_pImpl->SetCurrentRedlineToken(XML_ParagraphFormat);
3909     }
3910     else if (nSprmId == NS_ooxml::LN_CT_TrPr_ins)
3911     {
3912         m_pImpl->SetCurrentRedlineToken(XML_tableRowInsert);
3913     }
3914     else if (nSprmId == NS_ooxml::LN_CT_TrPr_del)
3915     {
3916         m_pImpl->SetCurrentRedlineToken(XML_tableRowDelete);
3917     }
3918     else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellIns)
3919     {
3920         m_pImpl->SetCurrentRedlineToken(XML_tableCellInsert);
3921     }
3922     else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellDel)
3923     {
3924         m_pImpl->SetCurrentRedlineToken(XML_tableCellDelete);
3925     }
3926 
3927     resolveSprmProps(*this, rSprm );
3928     // now the properties author, date and id should be available
3929     sal_Int32 nToken = m_pImpl->GetCurrentRedlineToken();
3930     switch( nToken & 0xffff )
3931     {
3932         case XML_mod:
3933         case XML_ins:
3934         case XML_del:
3935         case XML_moveTo:
3936         case XML_moveFrom:
3937         case XML_ParagraphFormat:
3938         case XML_tableRowInsert:
3939         case XML_tableRowDelete:
3940         case XML_tableCellInsert:
3941         case XML_tableCellDelete:
3942             break;
3943         default: OSL_FAIL( "redline token other than mod, ins, del, moveTo, moveFrom or table row" ); break;
3944     }
3945     m_pImpl->EndParaMarkerChange( );
3946     m_pImpl->SetCurrentRedlineIsRead();
3947 }
3948 
finishParagraph(const bool bRemove)3949 void DomainMapper::finishParagraph(const bool bRemove)
3950 {
3951     if (m_pImpl->m_pSdtHelper->validateDateFormat())
3952         m_pImpl->m_pSdtHelper->createDateContentControl();
3953     m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), bRemove);
3954 }
3955 
3956 } //namespace dmapper
3957 } //namespace writerfilter
3958 
3959 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3960