lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / writerfilter / source / dmapper / DomainMapper.cxx
blob9381a5fb86821f87c9943128d3b3abc15eeb8da6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "PageBordersHandler.hxx"
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 <filter/msfilter/util.hxx>
72 #include <sfx2/DocumentMetadataAccess.hxx>
73 #include <unotools/mediadescriptor.hxx>
75 #include "TextEffectsHandler.hxx"
76 #include "CellColorHandler.hxx"
77 #include "SectionColumnHandler.hxx"
78 #include "GraphicHelpers.hxx"
79 #include <dmapper/GraphicZOrderHelper.hxx>
80 #include <tools/diagnose_ex.h>
81 #include <sal/log.hxx>
83 using namespace ::com::sun::star;
84 using namespace oox;
86 namespace writerfilter {
88 namespace dmapper{
90 struct
92 sal_Int32 h;
93 bool orient;
94 sal_Int32 w;
95 } CT_PageSz;
98 DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xContext,
99 uno::Reference<io::XInputStream> const& xInputStream,
100 uno::Reference<lang::XComponent> const& xModel,
101 bool bRepairStorage,
102 SourceDocumentType eDocumentType,
103 utl::MediaDescriptor const & rMediaDesc) :
104 LoggedProperties("DomainMapper"),
105 LoggedTable("DomainMapper"),
106 LoggedStream("DomainMapper"),
107 m_pImpl(new DomainMapper_Impl(*this, xContext, xModel, eDocumentType, rMediaDesc)),
108 mbIsSplitPara(false)
109 ,mbHasControls(false)
111 // #i24363# tab stops relative to indent
112 m_pImpl->SetDocumentSettingsProperty(
113 getPropertyName( PROP_TABS_RELATIVE_TO_INDENT ),
114 uno::makeAny( false ) );
115 m_pImpl->SetDocumentSettingsProperty(
116 getPropertyName( PROP_SURROUND_TEXT_WRAP_SMALL ),
117 uno::makeAny( true ) );
118 m_pImpl->SetDocumentSettingsProperty(
119 getPropertyName( PROP_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING ),
120 uno::makeAny( true ) );
122 // Don't load the default style definitions to avoid weird mix
123 m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::makeAny(true));
125 // Initialize RDF metadata, to be able to add statements during the import.
128 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY_THROW);
129 uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
130 OUString aBaseURL = rMediaDesc.getUnpackedValueOrDefault("URL", OUString());
131 const uno::Reference<frame::XModel> xModel_(xModel,
132 uno::UNO_QUERY_THROW);
133 const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xContext, xModel_, aBaseURL, OUString()));
134 const uno::Reference<task::XInteractionHandler> xHandler;
135 xDocumentMetadataAccess->loadMetadataFromStorage(xStorage, xBaseURI, xHandler);
137 catch (const uno::Exception&)
139 DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize RDF metadata");
142 if (eDocumentType == SourceDocumentType::OOXML) {
143 // tdf#108350
144 // In Word since version 2007, the default document font is Calibri 11 pt.
145 // If a DOCX document doesn't contain font information, we should assume
146 // the intended font to provide best layout match.
149 uno::Reference< beans::XPropertySet > xDefProps(GetTextFactory()->createInstance("com.sun.star.text.Defaults"),
150 uno::UNO_QUERY_THROW);
151 xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), css::uno::Any(OUString("Calibri")));
152 xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), css::uno::Any(double(11)));
154 catch (const uno::Exception&)
156 DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize default font");
160 //import document properties
163 uno::Reference< embed::XStorage > xDocumentStorage =
164 comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xContext, bRepairStorage );
166 uno::Reference< uno::XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext(
167 "com.sun.star.document.OOXMLDocumentPropertiesImporter",
168 xContext);
170 uno::Reference< document::XOOXMLDocumentPropertiesImporter > xImporter( xTemp, uno::UNO_QUERY_THROW );
171 uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier( xModel, uno::UNO_QUERY_THROW);
172 xImporter->importProperties( xDocumentStorage, xPropSupplier->getDocumentProperties() );
174 catch( const uno::Exception& ) {}
177 DomainMapper::~DomainMapper()
181 uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
182 sal_Int32 nIndexes = 0;
183 if( xIndexesSupplier.is() )
185 uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes();
186 nIndexes = xIndexes->getCount();
188 // If we have page references, those need updating as well, similar to the indexes.
189 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
190 if(xTextFieldsSupplier.is())
192 uno::Reference<container::XEnumeration> xEnumeration = xTextFieldsSupplier->getTextFields()->createEnumeration();
193 while(xEnumeration->hasMoreElements())
195 ++nIndexes;
196 xEnumeration->nextElement();
200 mbHasControls |= m_pImpl->m_pSdtHelper->hasElements();
201 if ( nIndexes || mbHasControls )
203 //index update has to wait until first view is created
204 uno::Reference< document::XEventBroadcaster > xBroadcaster(xIndexesSupplier, uno::UNO_QUERY);
205 if (xBroadcaster.is())
206 xBroadcaster->addEventListener(uno::Reference< document::XEventListener >(new ModelEventListener(nIndexes, mbHasControls)));
210 // Apply the document settings after everything else
211 m_pImpl->GetSettingsTable()->ApplyProperties( m_pImpl->GetTextDocument( ) );
213 // now that importing is finished, re-enable default styles for any that were never defined/imported.
214 m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::makeAny(false));
216 // Grab-bag handling
217 comphelper::SequenceAsHashMap aProperties;
219 // Add the saved w:themeFontLang setting
220 aProperties["ThemeFontLangProps"] <<= m_pImpl->GetSettingsTable()->GetThemeFontLangProperties();
222 // Add the saved compat settings
223 aProperties["CompatSettings"] <<= m_pImpl->GetSettingsTable()->GetCompatSettings();
225 // Add the saved DocumentProtection settings
226 aProperties["DocumentProtection"] <<= m_pImpl->GetSettingsTable()->GetDocumentProtectionSettings();
228 uno::Reference<beans::XPropertySet> xDocProps(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
229 if (xDocProps.is())
231 comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue("InteropGrabBag"));
232 aGrabBag.update(aProperties);
233 xDocProps->setPropertyValue("InteropGrabBag", uno::Any(aGrabBag.getAsConstPropertyValueList()));
236 catch( const uno::Exception& ) {}
238 #ifdef DEBUG_WRITERFILTER
239 TagLogger::getInstance().endDocument();
240 #endif
243 void DomainMapper::lcl_attribute(Id nName, Value & val)
245 if (m_pImpl->hasTableManager() && m_pImpl->getTableManager().attribute(nName, val))
246 return;
248 static const int nSingleLineSpacing = 240;
249 sal_Int32 nIntValue = val.getInt();
250 OUString sStringValue = val.getString();
252 SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
253 switch( nName )
255 case NS_ooxml::LN_CT_Lvl_start:
256 break;
257 case NS_ooxml::LN_CT_Lvl_numFmt:
258 break;
259 case NS_ooxml::LN_CT_Lvl_isLgl:
260 break;
261 case NS_ooxml::LN_CT_Lvl_legacy:
262 break;
263 case NS_ooxml::LN_CT_AbstractNum_nsid:
264 break;
265 case NS_ooxml::LN_CT_AbstractNum_tmpl:
266 break;
267 case NS_ooxml::LN_CT_Border_sz:
268 break;
269 case NS_ooxml::LN_CT_Border_val:
270 break;
271 case NS_ooxml::LN_CT_Border_space:
272 break;
273 case NS_ooxml::LN_CT_Border_shadow:
274 break;
275 case NS_ooxml::LN_CT_Border_frame:
276 break;
277 case NS_ooxml::LN_headerr:
278 break;
279 case NS_ooxml::LN_footerr:
280 break;
281 case NS_ooxml::LN_endnote:
282 break;
283 case NS_ooxml::LN_CT_Bookmark_name:
284 m_pImpl->SetBookmarkName( sStringValue );
285 break;
286 case NS_ooxml::LN_CT_MarkupRangeBookmark_id:
287 // add a bookmark range -- this remembers a bookmark starting here
288 // or, if the bookmark was already started or, if the bookmark was
289 // already started before, writes out the bookmark
290 m_pImpl->StartOrEndBookmark( sStringValue );
291 break;
292 case NS_ooxml::LN_CT_MarkupRange_displacedByCustomXml:
293 break;
294 case NS_ooxml::LN_NUMBERING:
295 break;
296 case NS_ooxml::LN_FONTTABLE:
297 break;
298 case NS_ooxml::LN_STYLESHEET:
299 break;
301 case NS_ooxml::LN_CT_Sym_char:
302 m_pImpl->SetSymbolChar(nIntValue);
303 break;
304 case NS_ooxml::LN_CT_Sym_font:
305 m_pImpl->SetSymbolFont(sStringValue);
306 break;
307 case NS_ooxml::LN_CT_Underline_val:
308 if (m_pImpl->GetTopContext())
309 handleUnderlineType(nIntValue, m_pImpl->GetTopContext());
310 break;
311 case NS_ooxml::LN_CT_Color_val:
312 if (m_pImpl->GetTopContext())
313 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR, uno::makeAny( nIntValue ) );
314 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue)));
315 break;
316 case NS_ooxml::LN_CT_Underline_color:
317 if (m_pImpl->GetTopContext())
319 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_HAS_COLOR, uno::makeAny( true ) );
320 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COLOR, uno::makeAny( nIntValue ) );
322 break;
324 case NS_ooxml::LN_CT_TabStop_val:
325 if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_TabJc_clear)
327 m_pImpl->m_aCurrentTabStop.bDeleted = true;
329 else
331 m_pImpl->m_aCurrentTabStop.bDeleted = false;
332 m_pImpl->m_aCurrentTabStop.Alignment = getTabAlignFromValue(nIntValue);
334 break;
335 case NS_ooxml::LN_CT_TabStop_leader:
336 m_pImpl->m_aCurrentTabStop.FillChar = getFillCharFromValue(nIntValue);
337 break;
338 case NS_ooxml::LN_CT_TabStop_pos:
339 m_pImpl->m_aCurrentTabStop.Position = ConversionHelper::convertTwipToMM100(nIntValue);
340 break;
342 case NS_ooxml::LN_CT_Fonts_ascii:
343 if (m_pImpl->GetTopContext())
345 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( sStringValue ));
346 if (m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) && m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->isSet(PROP_NUMBERING_RULES))
348 // Font of the paragraph mark should be used for the numbering as well.
349 uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle());
350 if (xCharStyle.is())
351 xCharStyle->setPropertyValue("CharFontName", uno::makeAny(sStringValue));
354 break;
355 case NS_ooxml::LN_CT_Fonts_asciiTheme:
356 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeTable::getStringForTheme(nIntValue));
357 if (m_pImpl->GetTopContext())
359 uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) );
360 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, aPropValue );
361 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_ASCII, aPropValue, true, CHAR_GRAB_BAG );
362 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_ASCII, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
364 break;
365 case NS_ooxml::LN_CT_Fonts_hAnsi:
366 break;//unsupported
367 case NS_ooxml::LN_CT_Fonts_hAnsiTheme:
368 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeTable::getStringForTheme(nIntValue));
369 if (m_pImpl->GetTopContext())
370 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_H_ANSI, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
371 break;
372 case NS_ooxml::LN_CT_Fonts_eastAsia:
373 if (m_pImpl->GetTopContext())
374 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::makeAny( sStringValue ));
375 break;
376 case NS_ooxml::LN_CT_Fonts_eastAsiaTheme:
377 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsiaTheme", ThemeTable::getStringForTheme(nIntValue));
378 if (m_pImpl->GetTopContext())
380 uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) );
381 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, aPropValue );
382 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_EAST_ASIA, aPropValue, true, CHAR_GRAB_BAG );
383 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_EAST_ASIA, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
385 break;
386 case NS_ooxml::LN_CT_Fonts_cs:
387 if (m_pImpl->GetTopContext())
388 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::makeAny( sStringValue ));
389 break;
390 case NS_ooxml::LN_CT_Fonts_cstheme:
391 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "cstheme", ThemeTable::getStringForTheme(nIntValue));
392 if (m_pImpl->GetTopContext())
394 uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) );
395 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aPropValue );
396 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_CS, aPropValue, true, CHAR_GRAB_BAG );
397 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_CS, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
399 break;
400 case NS_ooxml::LN_CT_Spacing_before:
401 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "before", OUString::number(nIntValue));
402 if (m_pImpl->GetTopContext())
403 // Don't overwrite NS_ooxml::LN_CT_Spacing_beforeAutospacing.
404 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
405 break;
406 case NS_ooxml::LN_CT_Spacing_beforeLines:
407 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "beforeLines", OUString::number(nIntValue));
408 // We would need to make sure that this doesn't overwrite any
409 // NS_ooxml::LN_CT_Spacing_before in parent styles before style
410 // sheet support can be enabled.
411 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
412 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
413 break;
414 case NS_ooxml::LN_CT_Spacing_after:
415 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "after", OUString::number(nIntValue));
416 if (m_pImpl->GetTopContext())
418 // Don't overwrite NS_ooxml::LN_CT_Spacing_afterAutospacing.
419 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
421 uno::Any aContextualSpacingFromStyle = m_pImpl->GetPropertyFromStyleSheet(PROP_PARA_CONTEXT_MARGIN);
422 if (aContextualSpacingFromStyle.hasValue())
423 // Setting "after" spacing means Writer doesn't inherit
424 // contextual spacing anymore from style, but Word does.
425 m_pImpl->GetTopContext()->Insert(PROP_PARA_CONTEXT_MARGIN, aContextualSpacingFromStyle);
427 break;
428 case NS_ooxml::LN_CT_Spacing_afterLines:
429 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "afterLines", OUString::number(nIntValue));
430 // We would need to make sure that this doesn't overwrite any
431 // NS_ooxml::LN_CT_Spacing_after in parent styles before style
432 // sheet support can be enabled.
433 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
434 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
435 break;
436 case NS_ooxml::LN_CT_Spacing_line: //91434
437 case NS_ooxml::LN_CT_Spacing_lineRule: //91435
439 style::LineSpacing aSpacing;
440 PropertyMapPtr pTopContext = m_pImpl->GetTopContext();
441 boost::optional<PropertyMap::Property> aLineSpacingVal;
442 if (pTopContext && (aLineSpacingVal = pTopContext->getProperty(PROP_PARA_LINE_SPACING)) )
444 aLineSpacingVal->second >>= aSpacing;
446 else
448 //default to single line spacing
449 aSpacing.Mode = style::LineSpacingMode::FIX;
450 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
452 if( nName == NS_ooxml::LN_CT_Spacing_line )
454 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "line", OUString::number(nIntValue));
455 //now set the value depending on the Mode
456 if( aSpacing.Mode == style::LineSpacingMode::PROP )
457 aSpacing.Height = sal_Int16(nIntValue * 100 / nSingleLineSpacing );
458 else
459 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nIntValue ));
461 else //NS_ooxml::LN_CT_Spacing_lineRule:
463 // exactly, atLeast, auto
464 if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_auto)
466 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "auto");
467 if (aSpacing.Height >= 0)
469 aSpacing.Mode = style::LineSpacingMode::PROP;
470 //reinterpret the already set value
471 aSpacing.Height = sal_Int16( aSpacing.Height * 100 / ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
473 else
475 // Negative value still means a positive height,
476 // just the mode is "exact".
477 aSpacing.Mode = style::LineSpacingMode::FIX;
478 aSpacing.Height *= -1;
481 else if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast)
483 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "atLeast");
484 aSpacing.Mode = style::LineSpacingMode::MINIMUM;
486 else // NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact
488 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "exact");
489 aSpacing.Mode = style::LineSpacingMode::FIX;
492 if (pTopContext)
493 pTopContext->Insert(PROP_PARA_LINE_SPACING, uno::makeAny( aSpacing ));
495 break;
496 case NS_ooxml::LN_CT_Ind_start:
497 case NS_ooxml::LN_CT_Ind_left:
498 if (m_pImpl->GetTopContext())
500 // Word inherits FirstLineIndent property of the numbering, even if ParaLeftMargin is set, Writer does not.
501 // So copy it explicitly, if necessary.
502 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
503 sal_Int32 nIndentAt = m_pImpl->getCurrentNumberingProperty("IndentAt");
505 sal_Int32 nParaLeftMargin = ConversionHelper::convertTwipToMM100(nIntValue);
506 if (nParaLeftMargin != 0 && nIndentAt == nParaLeftMargin)
507 // Avoid direct left margin when it's the same as from the
508 // numbering.
509 break;
511 if (nFirstLineIndent != 0)
512 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
514 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN,
515 uno::makeAny(nParaLeftMargin));
517 break;
518 case NS_ooxml::LN_CT_Ind_end:
519 case NS_ooxml::LN_CT_Ind_right:
520 if (m_pImpl->GetTopContext())
522 // Word inherits FirstLineIndent/ParaLeftMargin property of the numbering, even if ParaRightMargin is set, Writer does not.
523 // So copy it explicitly, if necessary.
524 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
525 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
527 if (nFirstLineIndent != 0)
528 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
529 if (nParaLeftMargin != 0)
530 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);
532 m_pImpl->GetTopContext()->Insert(
533 PROP_PARA_RIGHT_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) ));
535 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "right", OUString::number(nIntValue));
536 break;
537 case NS_ooxml::LN_CT_Ind_hanging:
538 if (m_pImpl->GetTopContext())
540 sal_Int32 nValue = ConversionHelper::convertTwipToMM100( nIntValue );
541 m_pImpl->GetTopContext()->Insert(
542 PROP_PARA_FIRST_LINE_INDENT, uno::makeAny( - nValue ));
544 // See above, need to inherit left margin from list style when first is set.
545 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
546 if (nParaLeftMargin != 0)
547 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);
549 break;
550 case NS_ooxml::LN_CT_Ind_firstLine:
551 if (m_pImpl->GetTopContext())
553 sal_Int32 nFirstLineIndent
554 = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
555 sal_Int32 nParaFirstLineIndent = ConversionHelper::convertTwipToMM100(nIntValue);
556 if (nParaFirstLineIndent != 0 && nFirstLineIndent == nParaFirstLineIndent)
557 // Avoid direct first margin when it's the same as from the
558 // numbering.
559 break;
560 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT,
561 uno::makeAny(nParaFirstLineIndent));
563 break;
564 case NS_ooxml::LN_CT_Ind_rightChars:
565 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "rightChars", OUString::number(nIntValue));
566 break;
568 case NS_ooxml::LN_CT_EastAsianLayout_id:
569 break;
570 case NS_ooxml::LN_CT_EastAsianLayout_combine:
571 if (m_pImpl->GetTopContext())
572 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_IS_ON, uno::makeAny ( nIntValue != 0 ));
573 break;
574 case NS_ooxml::LN_CT_EastAsianLayout_combineBrackets:
575 if (m_pImpl->GetTopContext())
577 OUString sCombinePrefix = getBracketStringFromEnum(nIntValue);
578 OUString sCombineSuffix = getBracketStringFromEnum(nIntValue, false);
579 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_PREFIX, uno::makeAny ( sCombinePrefix ));
580 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_SUFFIX, uno::makeAny ( sCombineSuffix ));
582 break;
583 case NS_ooxml::LN_CT_EastAsianLayout_vert:
584 if (m_pImpl->GetTopContext())
586 sal_Int16 nRotationAngle = (nIntValue ? 900 : 0);
587 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION, uno::makeAny ( nRotationAngle ));
589 break;
590 case NS_ooxml::LN_CT_EastAsianLayout_vertCompress:
591 if (m_pImpl->GetTopContext())
592 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION_IS_FIT_TO_LINE, uno::makeAny ( nIntValue != 0 ));
593 break;
595 case NS_ooxml::LN_CT_PageSz_code:
596 break;
597 case NS_ooxml::LN_CT_PageSz_h:
599 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100(nIntValue);
600 CT_PageSz.h = PaperInfo::sloppyFitPageDimension(nHeight);
602 break;
603 case NS_ooxml::LN_CT_PageSz_orient:
604 CT_PageSz.orient = (nIntValue != static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_PageOrientation_portrait));
605 break;
606 case NS_ooxml::LN_CT_PageSz_w:
608 sal_Int32 nWidth = ConversionHelper::convertTwipToMM100(nIntValue);
609 CT_PageSz.w = PaperInfo::sloppyFitPageDimension(nWidth);
611 break;
613 case NS_ooxml::LN_CT_PageMar_top:
614 m_pImpl->SetPageMarginTwip( PAGE_MAR_TOP, nIntValue );
615 break;
616 case NS_ooxml::LN_CT_PageMar_right:
617 m_pImpl->SetPageMarginTwip( PAGE_MAR_RIGHT, nIntValue );
618 break;
619 case NS_ooxml::LN_CT_PageMar_bottom:
620 m_pImpl->SetPageMarginTwip( PAGE_MAR_BOTTOM, nIntValue );
621 break;
622 case NS_ooxml::LN_CT_PageMar_left:
623 m_pImpl->SetPageMarginTwip( PAGE_MAR_LEFT, nIntValue );
624 break;
625 case NS_ooxml::LN_CT_PageMar_header:
626 m_pImpl->SetPageMarginTwip( PAGE_MAR_HEADER, nIntValue );
627 break;
628 case NS_ooxml::LN_CT_PageMar_footer:
629 m_pImpl->SetPageMarginTwip( PAGE_MAR_FOOTER, nIntValue );
630 break;
631 case NS_ooxml::LN_CT_PageMar_gutter:
632 m_pImpl->SetPageMarginTwip( PAGE_MAR_GUTTER, nIntValue );
633 break;
634 case NS_ooxml::LN_CT_Language_val: //90314
635 case NS_ooxml::LN_CT_Language_eastAsia: //90315
636 case NS_ooxml::LN_CT_Language_bidi: //90316
638 if (nName == NS_ooxml::LN_CT_Language_eastAsia)
639 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsia", sStringValue);
640 else if (nName == NS_ooxml::LN_CT_Language_val)
641 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", sStringValue);
642 else if (nName == NS_ooxml::LN_CT_Language_bidi)
643 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "bidi", sStringValue);
644 lang::Locale aLocale( LanguageTag::convertToLocale( sStringValue));
645 if (m_pImpl->GetTopContext())
646 m_pImpl->GetTopContext()->Insert(NS_ooxml::LN_CT_Language_val== nName ? PROP_CHAR_LOCALE :
647 NS_ooxml::LN_CT_Language_eastAsia == nName ? PROP_CHAR_LOCALE_ASIAN : PROP_CHAR_LOCALE_COMPLEX,
648 uno::makeAny( aLocale ) );
650 break;
651 // See SwWW8ImplReader::GetParagraphAutoSpace() on why these are 100 and 280
652 case NS_ooxml::LN_CT_Spacing_beforeAutospacing:
654 sal_Int32 default_spacing = -1;
655 if (nIntValue)
657 m_pImpl->SetParaAutoBefore(true);
659 default_spacing = 100;
660 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
662 // 49 is just the old value that should be removed, once the
663 // root cause in SwTabFrm::MakeAll() is fixed.
664 if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
665 default_spacing = 49;
666 else
667 default_spacing = 280;
669 // required at export (here mainly for StyleSheets) to determine if the setting has changed from grab_bag
670 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(default_spacing)));
672 m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING, uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG );
674 break;
675 case NS_ooxml::LN_CT_Spacing_afterAutospacing:
677 sal_Int32 default_spacing = -1;
678 if (nIntValue)
680 default_spacing = 100;
681 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
683 if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
684 default_spacing = 49;
685 else
686 default_spacing = 280;
688 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(default_spacing)));
690 m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING, uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG );
692 break;
693 case NS_ooxml::LN_CT_SmartTagRun_uri:
694 m_pImpl->getSmartTagHandler().setURI(val.getString());
695 break;
696 case NS_ooxml::LN_CT_SmartTagRun_element:
697 m_pImpl->getSmartTagHandler().setElement(val.getString());
698 break;
699 case NS_ooxml::LN_CT_Br_type :
700 //TODO: attributes for break (0x12) are not supported
701 break;
702 case NS_ooxml::LN_CT_Fonts_hint :
703 /* assigns script type to ambiguous characters, values can be:
704 NS_ooxml::LN_Value_ST_Hint_default
705 NS_ooxml::LN_Value_ST_Hint_eastAsia
706 NS_ooxml::LN_Value_ST_Hint_cs
708 //TODO: unsupported?
709 break;
710 case NS_ooxml::LN_CT_TblBorders_right:
711 case NS_ooxml::LN_CT_TblBorders_top:
712 case NS_ooxml::LN_CT_TblBorders_left:
713 case NS_ooxml::LN_CT_TblBorders_bottom:
714 //todo: handle cell mar
715 break;
716 case NS_ooxml::LN_blip: // contains the binary graphic
717 case NS_ooxml::LN_shape:
719 //looks a bit like a hack - and it is. The graphic import is split into the inline_inline part and
720 //afterwards the adding of the binary data.
721 m_pImpl->GetGraphicImport( IMPORT_AS_DETECTED_INLINE )->attribute(nName, val);
722 m_pImpl->ImportGraphic( val.getProperties(), IMPORT_AS_DETECTED_INLINE );
724 break;
725 case NS_ooxml::LN_starmath:
726 m_pImpl->appendStarMath( val );
727 break;
728 case NS_ooxml::LN_CT_FramePr_dropCap:
729 case NS_ooxml::LN_CT_FramePr_lines:
730 case NS_ooxml::LN_CT_FramePr_hAnchor:
731 case NS_ooxml::LN_CT_FramePr_vAnchor:
732 case NS_ooxml::LN_CT_FramePr_x:
733 case NS_ooxml::LN_CT_FramePr_xAlign:
734 case NS_ooxml::LN_CT_FramePr_y:
735 case NS_ooxml::LN_CT_FramePr_yAlign:
736 case NS_ooxml::LN_CT_FramePr_hRule:
737 case NS_ooxml::LN_CT_FramePr_w:
738 case NS_ooxml::LN_CT_FramePr_h:
739 case NS_ooxml::LN_CT_FramePr_wrap:
740 case NS_ooxml::LN_CT_FramePr_hSpace:
741 case NS_ooxml::LN_CT_FramePr_vSpace:
743 ParagraphProperties* pParaProperties = nullptr;
744 // handle frame properties at styles
745 if( m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET )
746 pParaProperties = dynamic_cast< ParagraphProperties*>( m_pImpl->GetTopContextOfType( CONTEXT_STYLESHEET ).get() );
747 else
748 pParaProperties = dynamic_cast< ParagraphProperties*>( m_pImpl->GetTopContextOfType( CONTEXT_PARAGRAPH ).get() );
750 if( pParaProperties )
752 switch( nName )
754 case NS_ooxml::LN_CT_FramePr_dropCap:
755 pParaProperties->SetDropCap( nIntValue );
756 break;
757 case NS_ooxml::LN_CT_FramePr_lines:
758 pParaProperties->SetLines( nIntValue );
759 break;
760 case NS_ooxml::LN_CT_FramePr_hAnchor:
761 switch(nIntValue)
763 case NS_ooxml::LN_Value_doc_ST_HAnchor_text: //relative to column
764 nIntValue = text::RelOrientation::FRAME; break;
765 case NS_ooxml::LN_Value_doc_ST_HAnchor_margin: nIntValue = text::RelOrientation::PAGE_PRINT_AREA; break;
766 case NS_ooxml::LN_Value_doc_ST_HAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
767 default:;
769 pParaProperties->SethAnchor( nIntValue );
770 break;
771 case NS_ooxml::LN_CT_FramePr_vAnchor:
772 switch(nIntValue)
774 case NS_ooxml::LN_Value_doc_ST_VAnchor_text: //relative to paragraph
775 nIntValue = text::RelOrientation::FRAME; break;
776 case NS_ooxml::LN_Value_doc_ST_VAnchor_margin:nIntValue = text::RelOrientation::PAGE_PRINT_AREA ; break;
777 case NS_ooxml::LN_Value_doc_ST_VAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
778 default:;
780 pParaProperties->SetvAnchor( nIntValue );
781 break;
782 case NS_ooxml::LN_CT_FramePr_x:
783 pParaProperties->Setx( ConversionHelper::convertTwipToMM100(nIntValue ));
784 pParaProperties->SetxAlign( text::HoriOrientation::NONE );
785 break;
786 case NS_ooxml::LN_CT_FramePr_xAlign:
787 switch( nIntValue )
789 case NS_ooxml::LN_Value_doc_ST_XAlign_center : nIntValue = text::HoriOrientation::CENTER; break;
790 case NS_ooxml::LN_Value_doc_ST_XAlign_right : nIntValue = text::HoriOrientation::RIGHT; break;
791 case NS_ooxml::LN_Value_doc_ST_XAlign_inside : nIntValue = text::HoriOrientation::INSIDE; break;
792 case NS_ooxml::LN_Value_doc_ST_XAlign_outside : nIntValue = text::HoriOrientation::OUTSIDE; break;
793 case NS_ooxml::LN_Value_doc_ST_XAlign_left : nIntValue = text::HoriOrientation::LEFT; break;
794 default: nIntValue = text::HoriOrientation::NONE;
796 pParaProperties->SetxAlign( nIntValue );
797 break;
798 case NS_ooxml::LN_CT_FramePr_y:
799 pParaProperties->Sety( ConversionHelper::convertTwipToMM100(nIntValue ));
800 pParaProperties->SetyAlign( text::VertOrientation::NONE );
801 break;
802 case NS_ooxml::LN_CT_FramePr_yAlign:
803 switch( nIntValue )
805 case NS_ooxml::LN_Value_doc_ST_YAlign_top :
806 case NS_ooxml::LN_Value_doc_ST_YAlign_inside :nIntValue = text::VertOrientation::TOP; break;
807 case NS_ooxml::LN_Value_doc_ST_YAlign_center :nIntValue = text::VertOrientation::CENTER;break;
808 case NS_ooxml::LN_Value_doc_ST_YAlign_bottom :
809 case NS_ooxml::LN_Value_doc_ST_YAlign_outside :nIntValue = text::VertOrientation::BOTTOM;break;
810 case NS_ooxml::LN_Value_doc_ST_YAlign_inline :
812 // HACK: This is for bnc#780851, where a table has one cell that has w:framePr,
813 // which causes that paragraph to be converted to a text frame, and the original
814 // paragraph object no longer exists, which makes table creation fail and furthermore
815 // it would be missing in the table layout anyway. So actually no letting that paragraph
816 // be a text frame "fixes" it. I'm not sure what "inline" is supposed to mean in practice
817 // anyway, so as long as this doesn't cause trouble elsewhere ...
818 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
819 if( pContext.get() )
821 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
822 if (pParaContext)
823 pParaContext->SetFrameMode(false);
825 nIntValue = text::VertOrientation::NONE;
826 break;
828 default:
829 nIntValue = text::VertOrientation::NONE;
830 break;
832 pParaProperties->SetyAlign( nIntValue );
833 break;
834 case NS_ooxml::LN_CT_FramePr_hRule:
835 switch( nIntValue )
837 case NS_ooxml::LN_Value_doc_ST_HeightRule_exact:
838 nIntValue = text::SizeType::FIX;
839 break;
840 case NS_ooxml::LN_Value_doc_ST_HeightRule_atLeast:
841 nIntValue = text::SizeType::MIN;
842 break;
843 case NS_ooxml::LN_Value_doc_ST_HeightRule_auto:
844 //no break;
845 default:;
846 nIntValue = text::SizeType::VARIABLE;
848 pParaProperties->SethRule( nIntValue );
849 break;
850 case NS_ooxml::LN_CT_FramePr_wrap:
852 //should be either LN_Value_doc_ST_Wrap_notBeside or LN_Value_doc_ST_Wrap_around or LN_Value_doc_ST_Wrap_auto
853 OSL_ENSURE( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
854 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_notBeside ||
855 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
856 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none ||
857 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto,
858 "wrap not around, not_Beside, through, none or auto?");
859 if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
860 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
861 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto )
862 pParaProperties->SetWrap ( text::WrapTextMode_DYNAMIC ) ;
863 else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none)
864 pParaProperties->SetWrap ( text::WrapTextMode_THROUGH ) ;
865 else
866 pParaProperties->SetWrap ( text::WrapTextMode_NONE ) ;
868 break;
869 case NS_ooxml::LN_CT_FramePr_w:
870 pParaProperties->Setw(ConversionHelper::convertTwipToMM100(nIntValue));
871 break;
872 case NS_ooxml::LN_CT_FramePr_h:
873 pParaProperties->Seth(ConversionHelper::convertTwipToMM100(nIntValue));
874 break;
875 case NS_ooxml::LN_CT_FramePr_hSpace:
876 pParaProperties->SethSpace( ConversionHelper::convertTwipToMM100(nIntValue ));
877 break;
878 case NS_ooxml::LN_CT_FramePr_vSpace:
879 pParaProperties->SetvSpace( ConversionHelper::convertTwipToMM100(nIntValue ));
880 break;
881 default:;
885 break;
886 case NS_ooxml::LN_CT_TrackChange_author:
887 m_pImpl->SetCurrentRedlineAuthor( sStringValue );
888 break;
889 case NS_ooxml::LN_CT_TrackChange_date:
890 m_pImpl->SetCurrentRedlineDate( sStringValue );
891 break;
892 case NS_ooxml::LN_CT_Markup_id:
893 m_pImpl->SetCurrentRedlineId( nIntValue );
894 break;
895 case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart:
896 m_pImpl->AddAnnotationPosition( true, nIntValue );
897 break;
898 case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd:
899 m_pImpl->AddAnnotationPosition( false, nIntValue );
900 break;
901 case NS_ooxml::LN_CT_Comment_initials:
902 m_pImpl->SetCurrentRedlineInitials(sStringValue);
903 break;
904 case NS_ooxml::LN_token:
905 m_pImpl->SetCurrentRedlineToken( nIntValue );
906 break;
907 case NS_ooxml::LN_CT_LineNumber_start:
908 case NS_ooxml::LN_CT_LineNumber_distance:
909 case NS_ooxml::LN_CT_LineNumber_countBy:
910 case NS_ooxml::LN_CT_LineNumber_restart:
912 //line numbering in Writer is a global document setting
913 //in Word is a section setting
914 //if line numbering is switched on anywhere in the document it's set at the global settings
915 LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
916 switch( nName )
918 case NS_ooxml::LN_CT_LineNumber_countBy:
919 aSettings.nInterval = nIntValue;
920 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
921 if( pSectionContext )
922 pSectionContext->SetLnnMod( nIntValue );
923 break;
924 case NS_ooxml::LN_CT_LineNumber_start:
925 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
926 if( pSectionContext )
927 pSectionContext->SetLnnMin( nIntValue );
928 break;
929 case NS_ooxml::LN_CT_LineNumber_distance:
930 aSettings.nDistance = ConversionHelper::convertTwipToMM100( nIntValue );
931 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
932 if( pSectionContext )
933 pSectionContext->SetdxaLnn( nIntValue );
934 break;
935 case NS_ooxml::LN_CT_LineNumber_restart:
936 aSettings.bRestartAtEachPage = nIntValue == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_LineNumberRestart_newPage);
937 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
938 if( pSectionContext )
939 pSectionContext->SetLnc( nIntValue );
940 break;
941 default:;
943 m_pImpl->SetLineNumberSettings( aSettings );
945 break;
946 case NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows:
947 m_pImpl->SetCustomFtnMark( true );
948 break;
949 case NS_ooxml::LN_CT_FtnEdnRef_id:
950 // footnote or endnote reference id - not needed
951 break;
952 case NS_ooxml::LN_CT_Color_themeColor:
953 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeColor", TDefTableHandler::getThemeColorTypeString(nIntValue));
954 break;
955 case NS_ooxml::LN_CT_Color_themeTint:
956 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeTint", OUString::number(nIntValue, 16));
957 break;
958 case NS_ooxml::LN_CT_Color_themeShade:
959 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeShade", OUString::number(nIntValue, 16));
960 break;
961 case NS_ooxml::LN_CT_DocGrid_linePitch:
963 //see SwWW8ImplReader::SetDocumentGrid
964 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
965 if(pSectionContext)
967 pSectionContext->SetGridLinePitch( ConversionHelper::convertTwipToMM100( nIntValue ) );
970 break;
971 case NS_ooxml::LN_CT_DocGrid_charSpace:
973 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
974 if(pSectionContext)
976 pSectionContext->SetDxtCharSpace( nIntValue );
979 break;
980 case NS_ooxml::LN_CT_DocGrid_type:
982 if (pSectionContext != nullptr)
984 switch( nIntValue )
986 case NS_ooxml::LN_Value_doc_ST_DocGrid_default:
987 pSectionContext->SetGridType(text::TextGridMode::NONE);
988 break;
989 case NS_ooxml::LN_Value_doc_ST_DocGrid_lines:
990 pSectionContext->SetGridType(text::TextGridMode::LINES);
991 break;
992 case NS_ooxml::LN_Value_doc_ST_DocGrid_linesAndChars:
993 pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
994 pSectionContext->SetGridSnapToChars( false );
995 break;
996 case NS_ooxml::LN_Value_doc_ST_DocGrid_snapToChars:
997 pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
998 pSectionContext->SetGridSnapToChars( true );
999 break;
1000 default :
1001 OSL_FAIL("unknown SwTextGrid value");
1005 break;
1006 case NS_ooxml::LN_CT_SdtBlock_sdtContent:
1007 m_pImpl->SetSdt(true);
1008 break;
1009 case NS_ooxml::LN_CT_SdtBlock_sdtEndContent:
1010 m_pImpl->SetSdt(false);
1012 // It's not possible to insert the relevant property to the character context here:
1013 // the previous, already sent character context may be still active, so the property would be lost.
1014 if (m_pImpl->m_pSdtHelper->isOutsideAParagraph())
1015 m_pImpl->setParaSdtEndDeferred(true);
1016 else
1017 m_pImpl->setSdtEndDeferred(true);
1019 if (m_pImpl->m_pSdtHelper->isInsideDropDownControl())
1020 m_pImpl->m_pSdtHelper->createDropDownControl();
1021 else if (m_pImpl->m_pSdtHelper->validateDateFormat())
1022 m_pImpl->m_pSdtHelper->createDateContentControl();
1023 break;
1024 case NS_ooxml::LN_CT_SdtListItem_displayText:
1025 // TODO handle when this is != value
1026 break;
1027 case NS_ooxml::LN_CT_SdtListItem_value:
1028 m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue);
1029 break;
1030 case NS_ooxml::LN_CT_SdtDate_fullDate:
1031 m_pImpl->m_pSdtHelper->getDate().append(sStringValue);
1032 break;
1033 case NS_ooxml::LN_CT_Background_color:
1034 if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape())
1035 m_pImpl->m_oBackgroundColor = nIntValue;
1036 break;
1037 case NS_ooxml::LN_CT_PageNumber_start:
1038 if (pSectionContext != nullptr)
1039 pSectionContext->SetPageNumber(nIntValue);
1040 break;
1041 case NS_ooxml::LN_CT_PageNumber_fmt:
1042 if (pSectionContext)
1044 switch (nIntValue)
1046 case NS_ooxml::LN_Value_ST_NumberFormat_decimal:
1047 // 1, 2, ...
1048 pSectionContext->SetPageNumberType(style::NumberingType::ARABIC);
1049 break;
1050 case NS_ooxml::LN_Value_ST_NumberFormat_upperLetter:
1051 // A, B, ...
1052 pSectionContext->SetPageNumberType(style::NumberingType::CHARS_UPPER_LETTER_N);
1053 break;
1054 case NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter:
1055 // a, b, ...
1056 pSectionContext->SetPageNumberType(style::NumberingType::CHARS_LOWER_LETTER_N);
1057 break;
1058 case NS_ooxml::LN_Value_ST_NumberFormat_upperRoman:
1059 // I, II, ...
1060 pSectionContext->SetPageNumberType(style::NumberingType::ROMAN_UPPER);
1061 break;
1062 case NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman:
1063 // i, ii, ...
1064 pSectionContext->SetPageNumberType(style::NumberingType::ROMAN_LOWER);
1065 break;
1068 break;
1069 case NS_ooxml::LN_CT_FtnEdn_type:
1070 // This is the "separator" footnote, ignore its linebreak.
1071 if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator)
1072 m_pImpl->SeenFootOrEndnoteSeparator();
1073 break;
1074 case NS_ooxml::LN_CT_DataBinding_prefixMappings:
1075 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_prefixMappings", sStringValue);
1076 break;
1077 case NS_ooxml::LN_CT_DataBinding_xpath:
1078 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_xpath", sStringValue);
1079 break;
1080 case NS_ooxml::LN_CT_DataBinding_storeItemID:
1081 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_storeItemID", sStringValue);
1082 break;
1083 case NS_ooxml::LN_CT_PTab_leader:
1084 case NS_ooxml::LN_CT_PTab_relativeTo:
1085 case NS_ooxml::LN_CT_PTab_alignment:
1086 break;
1087 case NS_ooxml::LN_CT_Cnf_lastRowLastColumn:
1088 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowLastColumn", OUString::number(nIntValue));
1089 break;
1090 case NS_ooxml::LN_CT_Cnf_lastRowFirstColumn:
1091 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowFirstColumn", OUString::number(nIntValue));
1092 break;
1093 case NS_ooxml::LN_CT_Cnf_firstRowLastColumn:
1094 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowLastColumn", OUString::number(nIntValue));
1095 break;
1096 case NS_ooxml::LN_CT_Cnf_oddHBand:
1097 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddHBand", OUString::number(nIntValue));
1098 break;
1099 case NS_ooxml::LN_CT_Cnf_firstRowFirstColumn:
1100 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowFirstColumn", OUString::number(nIntValue));
1101 break;
1102 case NS_ooxml::LN_CT_Cnf_evenVBand:
1103 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenVBand", OUString::number(nIntValue));
1104 break;
1105 case NS_ooxml::LN_CT_Cnf_evenHBand:
1106 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenHBand", OUString::number(nIntValue));
1107 break;
1108 case NS_ooxml::LN_CT_Cnf_lastColumn:
1109 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastColumn", OUString::number(nIntValue));
1110 break;
1111 case NS_ooxml::LN_CT_Cnf_firstColumn:
1112 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstColumn", OUString::number(nIntValue));
1113 break;
1114 case NS_ooxml::LN_CT_Cnf_oddVBand:
1115 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddVBand", OUString::number(nIntValue));
1116 break;
1117 case NS_ooxml::LN_CT_Cnf_lastRow:
1118 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRow", OUString::number(nIntValue));
1119 break;
1120 case NS_ooxml::LN_CT_Cnf_firstRow:
1121 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRow", OUString::number(nIntValue));
1122 break;
1123 case NS_ooxml::LN_CT_Cnf_val:
1124 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "val", sStringValue);
1125 break;
1126 case NS_ooxml::LN_CT_DocPartName_val:
1128 m_sGlossaryEntryName = sStringValue;
1129 break;
1131 case NS_ooxml::LN_CT_DocPartGallery_val:
1133 const OUString& sGlossaryEntryGallery = sStringValue;
1134 if(m_pImpl->GetTopContext().get())
1136 OUString sName = sGlossaryEntryGallery + ":" + m_sGlossaryEntryName;
1137 // Add glossary entry name as a first paragraph in section
1138 m_pImpl->appendTextPortion(sName, m_pImpl->GetTopContext());
1140 break;
1142 case NS_ooxml::LN_CT_PermStart_ed:
1144 m_pImpl->setPermissionRangeEd(sStringValue);
1145 break;
1147 case NS_ooxml::LN_CT_PermStart_edGrp:
1149 m_pImpl->setPermissionRangeEdGrp(sStringValue);
1150 break;
1152 case NS_ooxml::LN_CT_PermStart_id:
1154 m_pImpl->startOrEndPermissionRange(nIntValue);
1155 break;
1157 case NS_ooxml::LN_CT_PermEnd_id:
1159 m_pImpl->startOrEndPermissionRange(nIntValue);
1160 break;
1162 default:
1163 SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName);
1167 void DomainMapper::lcl_sprm(Sprm & rSprm)
1169 if (!m_pImpl->hasTableManager() || !m_pImpl->getTableManager().sprm(rSprm))
1170 sprmWithProps(rSprm, m_pImpl->GetTopContext());
1173 // In rtl-paragraphs the meaning of left/right are to be exchanged
1174 static bool ExchangeLeftRight(const PropertyMapPtr& rContext, DomainMapper_Impl& rImpl)
1176 bool bExchangeLeftRight = false;
1177 sal_Int32 aAdjust;
1178 uno::Any aPropPara = rImpl.GetAnyProperty(PROP_WRITING_MODE, rContext);
1179 if( (aPropPara >>= aAdjust) && aAdjust == text::WritingMode2::RL_TB )
1180 bExchangeLeftRight = true;
1181 return bExchangeLeftRight;
1184 void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
1186 // These SPRM's are not specific to any section, so it's expected that there is no context yet.
1187 switch (rSprm.getId())
1189 case NS_ooxml::LN_background_background:
1190 return;
1191 break;
1192 default:
1193 break;
1196 OSL_ENSURE(rContext.get(), "PropertyMap has to be valid!");
1197 if(!rContext.get())
1198 return ;
1200 sal_uInt32 nSprmId = rSprm.getId();
1201 //needed for page properties
1202 SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
1203 Value::Pointer_t pValue = rSprm.getValue();
1204 sal_Int32 nIntValue = pValue->getInt();
1205 const OUString sStringValue = pValue->getString();
1207 switch(nSprmId)
1209 case NS_ooxml::LN_CT_PPrBase_jc:
1210 handleParaJustification(nIntValue, rContext, ExchangeLeftRight( rContext, *m_pImpl ));
1211 break;
1212 case NS_ooxml::LN_CT_PPrBase_keepLines:
1213 rContext->Insert(PROP_PARA_SPLIT, uno::makeAny(nIntValue == 0));
1214 break;
1215 case NS_ooxml::LN_CT_PPrBase_keepNext:
1216 rContext->Insert(PROP_PARA_KEEP_TOGETHER, uno::makeAny( nIntValue != 0 ) );
1217 break;
1218 case NS_ooxml::LN_CT_PPrBase_pageBreakBefore:
1219 rContext->Insert(PROP_BREAK_TYPE, uno::makeAny(nIntValue ? style::BreakType_PAGE_BEFORE : style::BreakType_NONE));
1220 break;
1221 case NS_ooxml::LN_CT_NumPr_ilvl:
1222 if (nIntValue < 0 || 10 <= nIntValue) // Writer can't do everything
1224 SAL_INFO("writerfilter",
1225 "unsupported numbering level " << nIntValue);
1226 break;
1228 if( IsStyleSheetImport() )
1230 //style sheets cannot have a numbering rule attached
1231 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1232 if (pStyleSheetPropertyMap)
1233 pStyleSheetPropertyMap->SetListLevel( static_cast<sal_Int16>(nIntValue) );
1235 else
1236 rContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny( static_cast<sal_Int16>(nIntValue) ));
1237 break;
1238 case NS_ooxml::LN_CT_NumPr_numId:
1240 //convert the ListTable entry to a NumberingRules property and apply it
1241 ListsManager::Pointer pListTable = m_pImpl->GetListTable();
1242 ListDef::Pointer pList = pListTable->GetList( nIntValue );
1243 if( IsStyleSheetImport() )
1245 //style sheets cannot have a numbering rule attached
1246 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1247 if (pStyleSheetPropertyMap)
1248 pStyleSheetPropertyMap->SetListId( nIntValue );
1250 if( pList.get( ) )
1252 if( !IsStyleSheetImport() )
1254 uno::Any aRules = uno::makeAny( pList->GetNumberingRules( ) );
1255 rContext->Insert( PROP_NUMBERING_RULES, aRules );
1256 // erase numbering from pStyle if already set
1257 rContext->Erase(PROP_NUMBERING_STYLE_NAME);
1259 // Indentation can came from:
1260 // 1) Paragraph style's numbering's indentation: the current non-style numId has priority over it.
1261 // 2) Numbering's indentation: Writer handles that natively, so it should not be set on rContext.
1262 // 3) Paragraph style's indentation: ditto.
1263 // 4) Direct paragraph formatting: that will came later.
1264 // So no situation where keeping indentation at this point would make sense -> erase.
1265 rContext->Erase(PROP_PARA_FIRST_LINE_INDENT);
1266 rContext->Erase(PROP_PARA_LEFT_MARGIN);
1267 rContext->Erase(PROP_PARA_RIGHT_MARGIN);
1270 else
1272 if( IsStyleSheetImport() )
1274 // set the number id for AbstractNum references
1275 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1276 if (pStyleSheetPropertyMap)
1277 pStyleSheetPropertyMap->SetNumId( nIntValue );
1279 else
1281 rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( OUString() ) );
1285 break;
1286 case NS_ooxml::LN_CT_PPrBase_suppressLineNumbers:
1287 rContext->Insert(PROP_PARA_LINE_NUMBER_COUNT, uno::makeAny( nIntValue == 0 ) );
1288 break;
1289 case NS_ooxml::LN_inTbl:
1290 break;
1291 case NS_ooxml::LN_tblDepth:
1292 //not handled via sprm but via text( 0x07 )
1293 break;
1294 case NS_ooxml::LN_CT_FramePr_w:
1295 break;
1296 case NS_ooxml::LN_CT_FramePr_wrap:
1297 break;
1299 case NS_ooxml::LN_CT_PrBase_pBdr: //paragraph border
1300 resolveSprmProps(*this, rSprm);
1301 break;
1302 case NS_ooxml::LN_CT_PBdr_top:
1303 case NS_ooxml::LN_CT_PBdr_left:
1304 case NS_ooxml::LN_CT_PBdr_bottom:
1305 case NS_ooxml::LN_CT_PBdr_right:
1306 case NS_ooxml::LN_CT_PBdr_between:
1308 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1309 if( pProperties.get())
1311 std::shared_ptr<BorderHandler> pBorderHandler( new BorderHandler( true ) );
1312 pProperties->resolve(*pBorderHandler);
1313 PropertyIds eBorderId = PropertyIds( 0 );
1314 PropertyIds eBorderDistId = PropertyIds( 0 );
1315 switch( nSprmId )
1317 case NS_ooxml::LN_CT_PBdr_top:
1318 eBorderId = PROP_TOP_BORDER;
1319 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
1320 break;
1321 case NS_ooxml::LN_CT_PBdr_left:
1322 eBorderId = PROP_LEFT_BORDER;
1323 eBorderDistId = PROP_LEFT_BORDER_DISTANCE;
1324 break;
1325 case NS_ooxml::LN_CT_PBdr_bottom:
1326 eBorderId = PROP_BOTTOM_BORDER ;
1327 eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE;
1328 break;
1329 case NS_ooxml::LN_CT_PBdr_right:
1330 eBorderId = PROP_RIGHT_BORDER;
1331 eBorderDistId = PROP_RIGHT_BORDER_DISTANCE ;
1332 break;
1333 case NS_ooxml::LN_CT_PBdr_between:
1334 //not supported
1335 break;
1336 default:;
1338 if( eBorderId )
1339 rContext->Insert( eBorderId, uno::makeAny( pBorderHandler->getBorderLine()) );
1340 if(eBorderDistId)
1341 rContext->Insert(eBorderDistId, uno::makeAny( pBorderHandler->getLineDistance()));
1342 if (nSprmId == NS_ooxml::LN_CT_PBdr_right && pBorderHandler->getShadow())
1344 table::ShadowFormat aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
1345 rContext->Insert(PROP_PARA_SHADOW_FORMAT, uno::makeAny(aFormat));
1349 break;
1350 case NS_ooxml::LN_CT_PBdr_bar:
1351 break;
1352 case NS_ooxml::LN_CT_PPrBase_suppressAutoHyphens:
1353 rContext->Insert(PROP_PARA_IS_HYPHENATION, uno::makeAny( nIntValue == 0 ));
1354 break;
1355 case NS_ooxml::LN_CT_FramePr_h:
1356 break;
1357 case NS_ooxml::LN_CT_PrBase_shd:
1359 //contains fore color, back color and shadow percentage, results in a brush
1360 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1361 if( pProperties.get())
1363 std::shared_ptr<CellColorHandler> pCellColorHandler( new CellColorHandler );
1364 pCellColorHandler->setOutputFormat( CellColorHandler::Paragraph );
1365 bool bEnableTempGrabBag = !pCellColorHandler->isInteropGrabBagEnabled();
1366 if( bEnableTempGrabBag )
1367 pCellColorHandler->enableInteropGrabBag( "TempShdPropsGrabBag" );
1369 pProperties->resolve(*pCellColorHandler);
1370 rContext->InsertProps(pCellColorHandler->getProperties().get());
1372 rContext->Insert(PROP_CHAR_THEME_FILL, pCellColorHandler->getInteropGrabBag().Value, true, PARA_GRAB_BAG);
1373 if(bEnableTempGrabBag)
1374 pCellColorHandler->disableInteropGrabBag();
1377 break;
1378 case NS_ooxml::LN_CT_FramePr_vSpace:
1379 break; // sprmPDyaFromText
1380 case NS_ooxml::LN_CT_FramePr_hSpace:
1381 break; // sprmPDxaFromText
1382 case NS_ooxml::LN_CT_FramePr_anchorLock:
1383 break;
1384 case NS_ooxml::LN_CT_PPrBase_widowControl:
1386 uno::Any aVal( uno::makeAny( sal_Int8(nIntValue ? 2 : 0 )));
1387 rContext->Insert( PROP_PARA_WIDOWS, aVal );
1388 rContext->Insert( PROP_PARA_ORPHANS, aVal );
1390 break; // sprmPFWidowControl
1391 case NS_ooxml::LN_CT_PPrBase_overflowPunct:
1392 rContext->Insert(PROP_PARA_IS_HANGING_PUNCTUATION, uno::makeAny( nIntValue == 0 ));
1393 break;
1394 case NS_ooxml::LN_CT_PPrBase_topLinePunct:
1395 break;
1396 case NS_ooxml::LN_CT_PPrBase_autoSpaceDE:
1397 break;
1398 case NS_ooxml::LN_CT_PPrBase_autoSpaceDN:
1399 break;
1400 case NS_ooxml::LN_CT_PPrBase_textAlignment:
1402 sal_Int16 nAlignment = 0;
1403 switch (nIntValue)
1405 case NS_ooxml::LN_Value_doc_ST_TextAlignment_top:
1406 nAlignment = 2;
1407 break;
1408 case NS_ooxml::LN_Value_doc_ST_TextAlignment_center:
1409 nAlignment = 3;
1410 break;
1411 case NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline:
1412 nAlignment = 1;
1413 break;
1414 case NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom:
1415 nAlignment = 4;
1416 break;
1417 case NS_ooxml::LN_Value_doc_ST_TextAlignment_auto:
1418 default:
1419 break;
1421 rContext->Insert( PROP_PARA_VERT_ALIGNMENT, uno::makeAny( nAlignment) );
1423 break;
1424 case NS_ooxml::LN_CT_PPrBase_textDirection:
1425 break;
1426 case NS_ooxml::LN_CT_PPrBase_outlineLvl:
1428 sal_Int16 nLvl = static_cast< sal_Int16 >( nIntValue );
1429 if( IsStyleSheetImport() )
1432 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1433 if (pStyleSheetPropertyMap)
1434 pStyleSheetPropertyMap->SetOutlineLevel( nLvl );
1436 else
1438 nLvl = nLvl >= WW_OUTLINE_MIN && nLvl < WW_OUTLINE_MAX? nLvl+1 : 0; //0 means no outline level set on
1439 rContext->Insert(PROP_OUTLINE_LEVEL, uno::makeAny ( nLvl ));
1442 break;
1443 case NS_ooxml::LN_CT_PPrBase_bidi:
1445 // Four situations to handle:
1446 // 1.) bidi same as previous setting: no adjust change
1447 // 2.) no previous adjust: set appropriate default for this bidi
1448 // 3.) previous adjust and bidi different from previous: swap adjusts
1449 // 4.) previous adjust and no previous bidi: RTL swaps adjust
1451 const sal_Int16 nWritingMode = nIntValue ? text::WritingMode2::RL_TB : text::WritingMode2::LR_TB;
1452 sal_Int16 nParentBidi = -1;
1453 m_pImpl->GetPropertyFromStyleSheet(PROP_WRITING_MODE) >>= nParentBidi;
1454 // Paragraph justification reverses its meaning in an RTL context.
1455 // 1. Only make adjustments if the BiDi changes.
1456 if ( nParentBidi != nWritingMode && !IsRTFImport() )
1458 style::ParagraphAdjust eAdjust = style::ParagraphAdjust(-1);
1459 // 2. no adjust property exists yet
1460 if ( !(m_pImpl->GetAnyProperty(PROP_PARA_ADJUST, rContext) >>= eAdjust) )
1462 // RTL defaults to right adjust
1463 eAdjust = nIntValue ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
1464 rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( eAdjust ), /*bOverwrite=*/false);
1466 // 3,4. existing adjust: if RTL, then swap. If LTR, but previous was RTL, also swap.
1467 else if ( nIntValue || nParentBidi == sal_Int16(text::WritingMode2::RL_TB) )
1469 if ( eAdjust == style::ParagraphAdjust_RIGHT )
1470 rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( style::ParagraphAdjust_LEFT ));
1471 else if ( eAdjust == style::ParagraphAdjust_LEFT )
1472 rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( style::ParagraphAdjust_RIGHT ));
1475 rContext->Insert(PROP_WRITING_MODE, uno::makeAny( nWritingMode ));
1478 break;
1479 case NS_ooxml::LN_EG_SectPrContents_bidi:
1480 if (pSectionContext != nullptr)
1482 const sal_Int16 writingMode = (nIntValue != 0) ? sal_Int16(text::WritingMode2::RL_TB) : sal_Int16(text::WritingMode2::LR_TB);
1483 pSectionContext->Insert(PROP_WRITING_MODE, uno::makeAny(writingMode));
1485 break;
1486 case NS_ooxml::LN_EG_RPrBase_highlight:
1488 // OOXML import uses an ID
1489 if( IsOOXMLImport() )
1491 sal_Int32 nColor = 0;
1492 if( getColorFromId(nIntValue, nColor) )
1493 rContext->Insert(PROP_CHAR_HIGHLIGHT, uno::makeAny( nColor ));
1495 // RTF import uses the actual color value
1496 else if( IsRTFImport() )
1498 rContext->Insert(PROP_CHAR_HIGHLIGHT, uno::makeAny( nIntValue ));
1501 break;
1502 case NS_ooxml::LN_EG_RPrBase_em:
1503 rContext->Insert(PROP_CHAR_EMPHASIS, uno::makeAny ( getEmphasisValue (nIntValue)));
1504 break;
1505 case NS_ooxml::LN_EG_RPrBase_emboss:
1506 case NS_ooxml::LN_EG_RPrBase_b:
1507 case NS_ooxml::LN_EG_RPrBase_bCs:
1508 case NS_ooxml::LN_EG_RPrBase_i:
1509 case NS_ooxml::LN_EG_RPrBase_iCs:
1510 case NS_ooxml::LN_EG_RPrBase_strike:
1511 case NS_ooxml::LN_EG_RPrBase_dstrike:
1512 case NS_ooxml::LN_EG_RPrBase_outline:
1513 case NS_ooxml::LN_EG_RPrBase_shadow:
1514 case NS_ooxml::LN_EG_RPrBase_caps:
1515 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1516 case NS_ooxml::LN_EG_RPrBase_vanish:
1517 case NS_ooxml::LN_EG_RPrBase_webHidden:
1519 PropertyIds ePropertyId = PROP_CHAR_WEIGHT; //initialized to prevent warning!
1520 switch( nSprmId )
1522 case NS_ooxml::LN_EG_RPrBase_b:
1523 case NS_ooxml::LN_EG_RPrBase_bCs:
1524 ePropertyId = nSprmId != NS_ooxml::LN_EG_RPrBase_bCs ? PROP_CHAR_WEIGHT : PROP_CHAR_WEIGHT_COMPLEX;
1525 break;
1526 case NS_ooxml::LN_EG_RPrBase_i:
1527 case NS_ooxml::LN_EG_RPrBase_iCs:
1528 ePropertyId = nSprmId == NS_ooxml::LN_EG_RPrBase_i ? PROP_CHAR_POSTURE : PROP_CHAR_POSTURE_COMPLEX;
1529 break;
1530 case NS_ooxml::LN_EG_RPrBase_strike:
1531 case NS_ooxml::LN_EG_RPrBase_dstrike:
1532 ePropertyId = PROP_CHAR_STRIKEOUT;
1533 break;
1534 case NS_ooxml::LN_EG_RPrBase_outline:
1535 ePropertyId = PROP_CHAR_CONTOURED;
1536 break;
1537 case NS_ooxml::LN_EG_RPrBase_shadow:
1538 ePropertyId = PROP_CHAR_SHADOWED;
1539 break;
1540 case NS_ooxml::LN_EG_RPrBase_caps:
1541 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1542 ePropertyId = PROP_CHAR_CASE_MAP;
1543 break;
1544 case NS_ooxml::LN_EG_RPrBase_vanish:
1545 case NS_ooxml::LN_EG_RPrBase_webHidden:
1546 ePropertyId = PROP_CHAR_HIDDEN;
1547 break;
1548 case NS_ooxml::LN_EG_RPrBase_emboss:
1549 ePropertyId = PROP_CHAR_RELIEF;
1550 break;
1552 //expected: 0,1,128,129
1553 if(nIntValue != 128) //inherited from paragraph - ignore
1555 if( nIntValue == 129) //inverted style sheet value
1557 //get value from style sheet and invert it
1558 sal_Int16 nStyleValue = 0;
1559 uno::Any aStyleVal = m_pImpl->GetPropertyFromStyleSheet(ePropertyId);
1560 if( !aStyleVal.hasValue() )
1562 nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
1563 4 : 1;
1565 else if(aStyleVal.getValueTypeClass() == uno::TypeClass_FLOAT )
1567 double fDoubleValue = 0;
1568 //only in case of awt::FontWeight
1569 aStyleVal >>= fDoubleValue;
1570 nIntValue = fDoubleValue > 100. ? 0 : 1;
1572 else if((aStyleVal >>= nStyleValue) ||
1573 (nStyleValue = static_cast<sal_Int16>(comphelper::getEnumAsINT32(aStyleVal))) >= 0 )
1575 nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
1576 nStyleValue ? 0 : 4 :
1577 nStyleValue ? 0 : 1;
1579 else
1581 OSL_FAIL( "what type was it");
1585 switch( nSprmId )
1587 case NS_ooxml::LN_EG_RPrBase_b:
1588 case NS_ooxml::LN_EG_RPrBase_bCs:
1590 uno::Any aBold( uno::makeAny( nIntValue ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL ) );
1592 rContext->Insert(ePropertyId, aBold );
1593 if( nSprmId != NS_ooxml::LN_EG_RPrBase_bCs )
1594 rContext->Insert(PROP_CHAR_WEIGHT_ASIAN, aBold );
1596 uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle());
1597 if (xCharStyle.is())
1598 xCharStyle->setPropertyValue(getPropertyName(PROP_CHAR_WEIGHT), aBold);
1599 if (nSprmId == NS_ooxml::LN_EG_RPrBase_b)
1600 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "b", OUString::number(nIntValue));
1601 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_bCs)
1602 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "bCs", OUString::number(nIntValue));
1604 break;
1605 case NS_ooxml::LN_EG_RPrBase_i:
1606 case NS_ooxml::LN_EG_RPrBase_iCs:
1608 uno::Any aPosture( uno::makeAny( nIntValue ? awt::FontSlant_ITALIC : awt::FontSlant_NONE ) );
1609 rContext->Insert( ePropertyId, aPosture );
1610 if (nSprmId != NS_ooxml::LN_EG_RPrBase_iCs)
1611 rContext->Insert(PROP_CHAR_POSTURE_ASIAN, aPosture );
1612 if (nSprmId == NS_ooxml::LN_EG_RPrBase_i)
1613 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "i", OUString::number(nIntValue));
1615 break;
1616 case NS_ooxml::LN_EG_RPrBase_strike:
1617 rContext->Insert(ePropertyId,
1618 uno::makeAny( nIntValue ? awt::FontStrikeout::SINGLE : awt::FontStrikeout::NONE ) );
1619 break;
1620 case NS_ooxml::LN_EG_RPrBase_dstrike:
1621 rContext->Insert(ePropertyId,
1622 uno::makeAny( nIntValue ? awt::FontStrikeout::DOUBLE : awt::FontStrikeout::NONE ) );
1623 break;
1624 case NS_ooxml::LN_EG_RPrBase_outline:
1625 case NS_ooxml::LN_EG_RPrBase_shadow:
1626 case NS_ooxml::LN_EG_RPrBase_vanish:
1627 case NS_ooxml::LN_EG_RPrBase_webHidden:
1628 rContext->Insert(ePropertyId, uno::makeAny( nIntValue != 0 ));
1629 break;
1630 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1631 // If smallcaps would be just disabled and another casemap is already inserted, don't do anything.
1632 if (nIntValue || !rContext->isSet(ePropertyId) )
1633 rContext->Insert(ePropertyId, uno::makeAny( nIntValue ? style::CaseMap::SMALLCAPS : style::CaseMap::NONE));
1634 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "smallCaps", OUString::number(nIntValue));
1635 break;
1636 case NS_ooxml::LN_EG_RPrBase_caps:
1637 rContext->Insert(ePropertyId,
1638 uno::makeAny( nIntValue ? style::CaseMap::UPPERCASE : style::CaseMap::NONE));
1639 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "caps", OUString::number(nIntValue));
1640 break;
1641 case NS_ooxml::LN_EG_RPrBase_emboss:
1642 rContext->Insert(ePropertyId,
1643 uno::makeAny( nIntValue ? awt::FontRelief::EMBOSSED : awt::FontRelief::NONE ));
1644 break;
1649 break;
1650 case NS_ooxml::LN_EG_RPrBase_sz:
1651 case NS_ooxml::LN_EG_RPrBase_szCs:
1653 //multiples of half points (12pt == 24)
1654 double fVal = double(nIntValue) / 2.;
1655 uno::Any aVal = uno::makeAny( fVal );
1656 if( NS_ooxml::LN_EG_RPrBase_szCs == nSprmId )
1658 rContext->Insert( PROP_CHAR_HEIGHT_COMPLEX, aVal );
1660 else
1662 bool bIgnore = false;
1663 const RubyInfo &aInfo = m_pImpl->GetRubyInfo();
1664 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt && aInfo.nHps > 0 )
1666 fVal = double(aInfo.nHps) / 2.;
1667 aVal <<= fVal;
1669 else if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase && aInfo.nHpsBaseText > 0 )
1671 fVal = double(aInfo.nHpsBaseText) / 2.;
1672 aVal <<= fVal;
1674 else if (m_pImpl->m_bInTableStyleRunProps)
1676 // If the default para style contains PROP_CHAR_HEIGHT, that should have priority over the table style.
1677 StyleSheetEntryPtr pTable = m_pImpl->GetStyleSheetTable()->FindDefaultParaStyle();
1678 if (pTable && pTable->pProperties->isSet(PROP_CHAR_HEIGHT) )
1679 bIgnore = true;
1681 if (!bIgnore)
1683 //Asian get the same value as Western
1684 rContext->Insert( PROP_CHAR_HEIGHT, aVal );
1685 rContext->Insert( PROP_CHAR_HEIGHT_ASIAN, aVal );
1687 uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle());
1688 if (xCharStyle.is())
1689 xCharStyle->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), aVal);
1692 // Make sure char sizes defined in the stylesheets don't affect char props from direct formatting.
1693 if (!IsStyleSheetImport())
1694 m_pImpl->deferCharacterProperty( nSprmId, uno::makeAny( nIntValue ));
1695 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, (nSprmId == NS_ooxml::LN_EG_RPrBase_sz ? OUString("sz") : OUString("szCs")), OUString::number(nIntValue));
1697 break;
1698 case NS_ooxml::LN_EG_RPrBase_position:
1699 // The spec says 0 is the same as the lack of the value, so don't parse that.
1700 if (nIntValue)
1701 m_pImpl->deferCharacterProperty( nSprmId, uno::makeAny( nIntValue ));
1702 break;
1703 case NS_ooxml::LN_EG_RPrBase_spacing:
1705 //Kerning half point values
1706 //TODO: there are two kerning values -
1707 // in ww8par6.cxx NS_sprm::LN_CHpsKern is used as boolean AutoKerning
1708 sal_Int16 nResult = static_cast<sal_Int16>(ConversionHelper::convertTwipToMM100(nIntValue));
1709 if (m_pImpl->IsInComments())
1711 nResult = static_cast<sal_Int16>(nIntValue);
1713 rContext->Insert(PROP_CHAR_CHAR_KERNING, uno::makeAny(nResult));
1714 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", OUString::number(nIntValue));
1716 break;
1717 case NS_ooxml::LN_EG_RPrBase_kern: // auto kerning is bound to a minimum font size in Word - but not in Writer :-(
1718 rContext->Insert(PROP_CHAR_AUTO_KERNING, uno::makeAny( nIntValue != 0 ) );
1719 break;
1720 case NS_ooxml::LN_EG_RPrBase_w:
1721 // ST_TextScale must fall between 1% and 600% according to spec, otherwise resets to 100% according to experience
1722 if ((1 <= nIntValue) && (nIntValue <= 600))
1724 rContext->Insert(PROP_CHAR_SCALE_WIDTH,
1725 uno::makeAny( sal_Int16(nIntValue) ));
1727 else
1729 rContext->Insert(PROP_CHAR_SCALE_WIDTH,
1730 uno::makeAny( sal_Int16(100) ));
1732 break;
1733 case NS_ooxml::LN_EG_RPrBase_imprint:
1734 // FontRelief: NONE, EMBOSSED, ENGRAVED
1735 rContext->Insert(PROP_CHAR_RELIEF,
1736 uno::makeAny( nIntValue ? awt::FontRelief::ENGRAVED : awt::FontRelief::NONE ));
1737 break;
1738 case NS_ooxml::LN_EG_RPrBase_effect:
1739 // The file-format has many character animations. We have only
1740 // one, so we use it always. Suboptimal solution though.
1741 if (nIntValue != NS_ooxml::LN_Value_ST_TextEffect_none)
1742 rContext->Insert(PROP_CHAR_FLASH, uno::makeAny( true ));
1743 else
1744 rContext->Insert(PROP_CHAR_FLASH, uno::makeAny( false ));
1745 break;
1746 case NS_ooxml::LN_EG_RPrBase_rtl:
1747 break;
1748 case NS_ooxml::LN_EG_RPrBase_shd:
1750 //contains fore color, back color and shadow percentage, results in a brush
1751 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1752 if( pProperties.get())
1754 std::shared_ptr<CellColorHandler> pCellColorHandler( new CellColorHandler );
1755 pCellColorHandler->setOutputFormat( CellColorHandler::Character );
1756 pProperties->resolve(*pCellColorHandler);
1757 rContext->InsertProps(pCellColorHandler->getProperties().get());
1758 m_pImpl->GetTopContext()->Insert(PROP_CHAR_SHADING_MARKER, uno::makeAny(true), true, CHAR_GRAB_BAG );
1760 break;
1762 case NS_ooxml::LN_EG_SectPrContents_type:
1763 /* break type
1764 0 - No break
1765 1 - New Column
1766 2 - New page
1767 3 - Even page
1768 4 - odd page
1770 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1771 if(pSectionContext)
1773 //continuous break only allowed if it is not the only section break
1774 SectionPropertyMap* pLastContext = m_pImpl->GetLastSectionContext();
1775 if ( nIntValue != static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous) || pLastContext || m_pImpl->GetParaSectpr() )
1776 pSectionContext->SetBreakType( nIntValue );
1778 break;
1779 case NS_ooxml::LN_EG_SectPrContents_titlePg:
1781 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1782 if(pSectionContext)
1783 pSectionContext->SetTitlePage( nIntValue > 0 );//section has title page
1785 break;
1786 case 165:
1788 //page height, rounded to default values, default: 0x3dc0 twip
1789 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100( nIntValue );
1790 rContext->Insert( PROP_HEIGHT, uno::makeAny( PaperInfo::sloppyFitPageDimension( nHeight ) ) );
1792 break;
1793 case NS_ooxml::LN_EG_SectPrContents_textDirection:
1795 /* 0 HoriLR 1 Vert TR 2 Vert TR 3 Vert TT 4 HoriLT
1796 only 0 and 1 can be imported correctly
1798 text::WritingMode nDirection = text::WritingMode_LR_TB;
1799 switch( nIntValue )
1801 case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
1802 case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
1803 nDirection = text::WritingMode_LR_TB;
1804 break;
1805 case NS_ooxml::LN_Value_ST_TextDirection_tbRl:
1806 case NS_ooxml::LN_Value_ST_TextDirection_btLr:
1807 nDirection = text::WritingMode_TB_RL;
1808 break;
1809 default:;
1812 PropertyMap * pTargetContext = rContext.get();
1814 if (pSectionContext != nullptr &&
1815 nSprmId == NS_ooxml::LN_EG_SectPrContents_textDirection)
1817 pTargetContext = pSectionContext;
1820 pTargetContext->Insert(PROP_WRITING_MODE, uno::makeAny( sal_Int16(nDirection) ) );
1822 break; // sprmSTextFlow
1823 // the following are not part of the official documentation
1824 case NS_ooxml::LN_CT_Tabs_tab:
1825 resolveSprmProps(*this, rSprm);
1826 m_pImpl->IncorporateTabStop(m_pImpl->m_aCurrentTabStop);
1827 m_pImpl->m_aCurrentTabStop = DeletableTabStop();
1828 break;
1829 case NS_ooxml::LN_CT_PPrBase_tabs:
1831 // Initialize tab stop vector from style sheet
1832 // fdo#81033: for RTF, a tab stop is inherited from the style if it
1833 // is also applied to the paragraph directly, and cleared if it is
1834 // not applied to the paragraph directly => don't InitTabStopFromStyle
1835 if ( !IsRTFImport() )
1837 uno::Any aValue = m_pImpl->GetPropertyFromStyleSheet(PROP_PARA_TAB_STOPS);
1838 uno::Sequence< style::TabStop > aStyleTabStops;
1839 if(aValue >>= aStyleTabStops)
1841 m_pImpl->InitTabStopFromStyle( aStyleTabStops );
1844 resolveSprmProps(*this, rSprm);
1845 rContext->Insert(PROP_PARA_TAB_STOPS, uno::makeAny( m_pImpl->GetCurrentTabStopAndClear()));
1847 break;
1849 case NS_ooxml::LN_CT_DocDefaults_pPrDefault:
1850 case NS_ooxml::LN_CT_DocDefaults_rPrDefault:
1851 GetStyleSheetTable()->sprm( rSprm );
1852 break;
1853 case NS_ooxml::LN_EG_RPrBase_bdr:
1855 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1856 if( pProperties.get())
1858 std::shared_ptr<BorderHandler> pBorderHandler( new BorderHandler( true ) );
1859 pProperties->resolve(*pBorderHandler);
1861 rContext->Insert( PROP_CHAR_TOP_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
1862 rContext->Insert( PROP_CHAR_BOTTOM_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
1863 rContext->Insert( PROP_CHAR_LEFT_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
1864 rContext->Insert( PROP_CHAR_RIGHT_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
1866 rContext->Insert( PROP_CHAR_TOP_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
1867 rContext->Insert( PROP_CHAR_BOTTOM_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
1868 rContext->Insert( PROP_CHAR_LEFT_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
1869 rContext->Insert( PROP_CHAR_RIGHT_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
1871 if( pBorderHandler->getShadow() )
1873 table::ShadowFormat aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
1874 rContext->Insert(PROP_CHAR_SHADOW_FORMAT, uno::makeAny(aFormat));
1878 break;
1879 case NS_ooxml::LN_CT_PPr_sectPr:
1880 case NS_ooxml::LN_EG_RPrBase_color:
1881 case NS_ooxml::LN_EG_RPrBase_rFonts:
1882 case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
1883 case NS_ooxml::LN_EG_RPrBase_u:
1884 case NS_ooxml::LN_EG_RPrBase_lang:
1885 case NS_ooxml::LN_CT_PPrBase_spacing:
1886 case NS_ooxml::LN_CT_PPrBase_ind:
1887 case NS_ooxml::LN_CT_RPrDefault_rPr:
1888 case NS_ooxml::LN_CT_PPrDefault_pPr:
1889 case NS_ooxml::LN_CT_Style_pPr:
1890 case NS_ooxml::LN_CT_Style_rPr:
1891 case NS_ooxml::LN_CT_PPr_rPr:
1892 case NS_ooxml::LN_CT_PPrBase_numPr:
1894 bool bTempGrabBag = !m_pImpl->isInteropGrabBagEnabled();
1895 if (nSprmId == NS_ooxml::LN_CT_PPr_sectPr)
1896 m_pImpl->SetParaSectpr(true);
1897 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_color && bTempGrabBag)
1898 // if DomainMapper grab bag is not enabled, enable it temporarily
1899 m_pImpl->enableInteropGrabBag("TempColorPropsGrabBag");
1900 resolveSprmProps(*this, rSprm);
1901 if (nSprmId == NS_ooxml::LN_CT_PPrBase_spacing)
1902 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", m_pImpl->m_aSubInteropGrabBag);
1903 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_rFonts)
1904 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "rFonts", m_pImpl->m_aSubInteropGrabBag);
1905 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_lang)
1906 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lang", m_pImpl->m_aSubInteropGrabBag);
1907 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_color)
1909 for (const auto& rItem : m_pImpl->m_aSubInteropGrabBag)
1911 if (rItem.Name == "val")
1912 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_ORIGINAL_COLOR, rItem.Value, true, CHAR_GRAB_BAG);
1913 else if (rItem.Name == "themeColor")
1914 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR, rItem.Value, true, CHAR_GRAB_BAG);
1915 else if (rItem.Name == "themeShade")
1916 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_SHADE, rItem.Value, true, CHAR_GRAB_BAG);
1917 else if (rItem.Name == "themeTint")
1918 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_TINT, rItem.Value, true, CHAR_GRAB_BAG);
1920 if (bTempGrabBag)
1921 //disable and clear DomainMapper grab bag if it wasn't enabled before
1922 m_pImpl->disableInteropGrabBag();
1924 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "color", m_pImpl->m_aSubInteropGrabBag);
1926 else if (nSprmId == NS_ooxml::LN_CT_PPrBase_ind)
1927 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ind", m_pImpl->m_aSubInteropGrabBag);
1929 break;
1930 case NS_ooxml::LN_CT_PPrBase_wordWrap:
1931 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "wordWrap", "");
1932 break;
1933 case NS_ooxml::LN_EG_SectPrContents_footnotePr:
1934 case NS_ooxml::LN_EG_SectPrContents_endnotePr:
1935 m_pImpl->SetInFootnoteProperties( NS_ooxml::LN_EG_SectPrContents_footnotePr == nSprmId );
1936 resolveSprmProps(*this, rSprm);
1937 break;
1938 case NS_ooxml::LN_EG_SectPrContents_lnNumType:
1940 resolveSprmProps(*this, rSprm);
1941 LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
1942 m_pImpl->SetLineNumberSettings( aSettings );
1943 //apply settings at XLineNumberingProperties
1946 uno::Reference< text::XLineNumberingProperties > xLineNumberingProperties( m_pImpl->GetTextDocument(), uno::UNO_QUERY_THROW );
1947 uno::Reference< beans::XPropertySet > xLineNumberingPropSet = xLineNumberingProperties->getLineNumberingProperties();
1948 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::makeAny(true) );
1949 if( aSettings.nInterval )
1950 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_INTERVAL ), uno::makeAny(static_cast<sal_Int16>(aSettings.nInterval)) );
1951 if( aSettings.nDistance )
1952 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::makeAny(aSettings.nDistance) );
1953 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny(aSettings.bRestartAtEachPage) );
1955 catch( const uno::Exception& )
1960 break;
1961 case NS_ooxml::LN_CT_PPrBase_framePr:
1962 // Avoid frames if we're inside a structured document tag, would just cause outer tables fail to create.
1963 if (!m_pImpl->GetSdt())
1965 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
1966 if( pContext.get() )
1968 // If there is a deferred page break applied to this framed paragraph,
1969 // create a dummy paragraph without extra properties,
1970 // so that the anchored frame will be on the correct page (similar to shapes).
1971 if (pContext->isSet(PROP_BREAK_TYPE))
1973 pContext->Erase(PROP_BREAK_TYPE);
1975 lcl_startParagraphGroup();
1976 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
1977 lcl_startCharacterGroup();
1978 sal_uInt8 const sBreak[] = { 0xd };
1979 lcl_text(sBreak, 1);
1980 lcl_endCharacterGroup();
1981 lcl_endParagraphGroup();
1984 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
1985 if (pParaContext)
1986 pParaContext->SetFrameMode();
1988 else
1990 //TODO: What about style sheet import of frame properties
1992 resolveSprmProps(*this, rSprm);
1994 break;
1995 case NS_ooxml::LN_EG_SectPrContents_pgSz:
1997 PaperInfo aLetter(PAPER_LETTER);
1998 CT_PageSz.w = aLetter.getWidth();
1999 CT_PageSz.h = aLetter.getHeight();
2001 CT_PageSz.orient = false;
2002 resolveSprmProps(*this, rSprm);
2003 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2004 if(pSectionContext)
2006 pSectionContext->Insert( PROP_HEIGHT, uno::makeAny( CT_PageSz.h ) );
2007 pSectionContext->Insert( PROP_IS_LANDSCAPE, uno::makeAny( CT_PageSz.orient ));
2008 pSectionContext->Insert( PROP_WIDTH, uno::makeAny( CT_PageSz.w ) );
2010 break;
2012 case NS_ooxml::LN_EG_SectPrContents_pgMar:
2013 m_pImpl->InitPageMargins();
2014 resolveSprmProps(*this, rSprm);
2015 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2016 if(pSectionContext)
2018 const PageMar& rPageMar = m_pImpl->GetPageMargins();
2019 pSectionContext->SetTopMargin( rPageMar.top );
2020 pSectionContext->SetRightMargin( rPageMar.right );
2021 pSectionContext->SetBottomMargin( rPageMar.bottom );
2022 pSectionContext->SetLeftMargin( rPageMar.left );
2023 pSectionContext->SetHeaderTop( rPageMar.header );
2024 pSectionContext->SetHeaderBottom( rPageMar.footer );
2026 break;
2028 case NS_ooxml::LN_EG_SectPrContents_cols:
2030 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2031 if( pProperties.get())
2034 tools::SvRef< SectionColumnHandler > pSectHdl( new SectionColumnHandler );
2035 pProperties->resolve(*pSectHdl);
2036 if(pSectionContext && !m_pImpl->isInIndexContext())
2038 if( pSectHdl->IsEqualWidth() )
2040 pSectionContext->SetEvenlySpaced( true );
2041 pSectionContext->SetColumnCount( static_cast<sal_Int16>(pSectHdl->GetNum() - 1) );
2042 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2043 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2045 else if( !pSectHdl->GetColumns().empty() )
2047 pSectionContext->SetEvenlySpaced( false );
2048 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2049 pSectionContext->SetColumnCount( static_cast<sal_Int16>(pSectHdl->GetColumns().size() -1));
2050 std::vector<Column_>::const_iterator tmpIter = pSectHdl->GetColumns().begin();
2051 for (; tmpIter != pSectHdl->GetColumns().end(); ++tmpIter)
2053 pSectionContext->AppendColumnWidth( tmpIter->nWidth );
2054 if ((tmpIter != pSectHdl->GetColumns().end() - 1) || (tmpIter->nSpace > 0))
2055 pSectionContext->AppendColumnSpacing( tmpIter->nSpace );
2057 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2059 else if( pSectHdl->GetNum() > 0 )
2061 pSectionContext->SetColumnCount( static_cast<sal_Int16>(pSectHdl->GetNum()) - 1 );
2062 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2063 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2067 else if ( pSectionContext )
2069 FieldContextPtr pContext = m_pImpl->GetTopFieldContext();
2070 uno::Reference< beans::XPropertySet > xTOC = pContext->GetTOC();
2071 if( xTOC.is() )
2073 uno::Reference<text::XTextColumns> xTextColumns;
2074 xTOC->getPropertyValue(getPropertyName( PROP_TEXT_COLUMNS )) >>= xTextColumns;
2075 if (xTextColumns.is())
2077 uno::Reference< beans::XPropertySet > xColumnPropSet( xTextColumns, uno::UNO_QUERY_THROW );
2078 xColumnPropSet->setPropertyValue( getPropertyName( PROP_AUTOMATIC_DISTANCE ), uno::makeAny( pSectHdl->GetSpace() ));
2079 xTOC->setPropertyValue( getPropertyName( PROP_TEXT_COLUMNS ), uno::makeAny( xTextColumns ) );
2085 break;
2086 case NS_ooxml::LN_EG_SectPrContents_docGrid:
2087 resolveSprmProps(*this, rSprm);
2088 break;
2089 case NS_ooxml::LN_EG_SectPrContents_pgBorders:
2091 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2092 if( pProperties.get( ) && pSectionContext )
2094 tools::SvRef< PageBordersHandler > pHandler( new PageBordersHandler );
2095 pProperties->resolve( *pHandler );
2097 // Set the borders to the context and apply them to the styles
2098 pHandler->SetBorders( pSectionContext );
2101 break;
2103 case NS_ooxml::LN_CT_PPrBase_snapToGrid:
2104 if (!IsStyleSheetImport()||!m_pImpl->isInteropGrabBagEnabled())
2106 rContext->Insert( PROP_SNAP_TO_GRID, uno::makeAny(bool(nIntValue)));
2108 else
2110 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "snapToGrid", OUString::number(nIntValue));
2112 break;
2113 case NS_ooxml::LN_CT_PPrBase_pStyle:
2115 StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable();
2116 const OUString sConvertedStyleName = pStyleTable->ConvertStyleName( sStringValue, true );
2117 m_pImpl->SetCurrentParaStyleName( sConvertedStyleName );
2118 if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION)
2119 m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::makeAny( sConvertedStyleName ));
2121 break;
2122 case NS_ooxml::LN_EG_RPrBase_rStyle:
2124 OUString sConvertedName( m_pImpl->GetStyleSheetTable()->ConvertStyleName( sStringValue, true ) );
2125 // First check if the style exists in the document.
2126 StyleSheetEntryPtr pEntry = m_pImpl->GetStyleSheetTable( )->FindStyleSheetByConvertedStyleName( sConvertedName );
2127 bool bExists = pEntry.get( ) && ( pEntry->nStyleTypeCode == STYLE_TYPE_CHAR );
2128 // Add the property if the style exists, but do not add it elements in TOC:
2129 // they will receive later another style references from TOC
2130 if ( bExists && m_pImpl->GetTopContext() && !m_pImpl->IsInTOC())
2131 m_pImpl->GetTopContext()->Insert( PROP_CHAR_STYLE_NAME, uno::makeAny( sConvertedName ) );
2133 break;
2134 case NS_ooxml::LN_CT_TblPrBase_tblCellMar: //cell margins
2136 resolveSprmProps(*this, rSprm);//contains LN_CT_TblCellMar_top, LN_CT_TblCellMar_left, LN_CT_TblCellMar_bottom, LN_CT_TblCellMar_right
2138 break;
2139 case NS_ooxml::LN_CT_TblCellMar_top:
2140 case NS_ooxml::LN_CT_TblCellMar_start:
2141 case NS_ooxml::LN_CT_TblCellMar_left:
2142 case NS_ooxml::LN_CT_TblCellMar_bottom:
2143 case NS_ooxml::LN_CT_TblCellMar_end:
2144 case NS_ooxml::LN_CT_TblCellMar_right:
2146 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2147 if( pProperties.get())
2149 MeasureHandlerPtr pMeasureHandler( new MeasureHandler );
2150 pProperties->resolve(*pMeasureHandler);
2151 sal_Int32 nMeasureValue = pMeasureHandler->getMeasureValue();
2152 PropertyIds eId = META_PROP_CELL_MAR_TOP;
2153 bool rtl = false; // TODO
2154 switch(nSprmId)
2156 case NS_ooxml::LN_CT_TblCellMar_top:
2157 break;
2158 case NS_ooxml::LN_CT_TblCellMar_start:
2159 eId = rtl ? META_PROP_CELL_MAR_RIGHT : META_PROP_CELL_MAR_LEFT;
2160 break;
2161 case NS_ooxml::LN_CT_TblCellMar_left:
2162 eId = META_PROP_CELL_MAR_LEFT;
2163 break;
2164 case NS_ooxml::LN_CT_TblCellMar_bottom:
2165 eId = META_PROP_CELL_MAR_BOTTOM;
2166 break;
2167 case NS_ooxml::LN_CT_TblCellMar_end:
2168 eId = rtl ? META_PROP_CELL_MAR_LEFT : META_PROP_CELL_MAR_RIGHT;
2169 break;
2170 case NS_ooxml::LN_CT_TblCellMar_right:
2171 eId = META_PROP_CELL_MAR_RIGHT;
2172 break;
2173 default:;
2175 rContext->Insert( eId, uno::makeAny(nMeasureValue), false);
2178 break;
2179 case NS_ooxml::LN_EG_RPrBase_noProof: // no grammar and spell checking, unsupported
2180 break;
2181 case NS_ooxml::LN_anchor_anchor: // at_character drawing
2182 case NS_ooxml::LN_inline_inline: // as_character drawing
2184 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2185 if( pProperties.get())
2187 GraphicImportType eGraphicType =
2188 (NS_ooxml::LN_anchor_anchor ==
2189 sal::static_int_cast<Id>(nSprmId)) ?
2190 IMPORT_AS_DETECTED_ANCHOR :
2191 IMPORT_AS_DETECTED_INLINE;
2192 GraphicImportPtr pGraphicImport =
2193 m_pImpl->GetGraphicImport(eGraphicType);
2194 pProperties->resolve(*pGraphicImport);
2195 m_pImpl->ImportGraphic(pProperties, eGraphicType);
2196 if( !pGraphicImport->IsGraphic() )
2198 m_pImpl->ResetGraphicImport();
2199 // todo: It's a shape, now start shape import
2203 break;
2204 case NS_ooxml::LN_EG_RPrBase_vertAlign:
2206 sal_Int16 nEscapement = 0;
2207 sal_Int8 nProp = 58;
2208 if ( sStringValue == "superscript" )
2209 nEscapement = 101;
2210 else if ( sStringValue == "subscript" )
2211 nEscapement = -101;
2212 else
2213 nProp = 100;
2215 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( nEscapement ) );
2216 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::makeAny( nProp ) );
2218 break;
2219 case NS_ooxml::LN_CT_FtnProps_pos:
2220 //footnotes in word can be at page end or beneath text - writer supports only the first
2221 //endnotes in word can be at section end or document end - writer supports only the latter
2222 // -> so this property can be ignored
2223 break;
2224 case NS_ooxml::LN_EG_FtnEdnNumProps_numStart:
2225 case NS_ooxml::LN_EG_FtnEdnNumProps_numRestart:
2226 case NS_ooxml::LN_CT_FtnProps_numFmt:
2227 case NS_ooxml::LN_CT_EdnProps_numFmt:
2231 uno::Reference< beans::XPropertySet > xFtnEdnSettings;
2232 if( m_pImpl->IsInFootnoteProperties() )
2234 uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2235 if (xFootnotesSupplier.is())
2236 xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings();
2238 else
2240 uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2241 if (xEndnotesSupplier.is())
2242 xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings();
2244 if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId && xFtnEdnSettings.is())
2246 xFtnEdnSettings->setPropertyValue(
2247 getPropertyName( PROP_START_AT),
2248 uno::makeAny( sal_Int16( nIntValue - 1 )));
2250 else if( NS_ooxml::LN_EG_FtnEdnNumProps_numRestart == nSprmId && xFtnEdnSettings.is())
2252 sal_Int16 nFootnoteCounting = 0;
2253 switch (nIntValue)
2255 case NS_ooxml::LN_Value_ST_RestartNumber_continuous: nFootnoteCounting = text::FootnoteNumbering::PER_DOCUMENT; break;
2256 case NS_ooxml::LN_Value_ST_RestartNumber_eachPage: nFootnoteCounting = text::FootnoteNumbering::PER_PAGE; break;
2257 case NS_ooxml::LN_Value_ST_RestartNumber_eachSect: nFootnoteCounting = text::FootnoteNumbering::PER_CHAPTER; break;
2258 default: break;
2260 xFtnEdnSettings->setPropertyValue(
2261 getPropertyName( PROP_FOOTNOTE_COUNTING ),
2262 uno::makeAny( nFootnoteCounting ));
2264 else if (xFtnEdnSettings.is())
2266 sal_Int16 nNumType = ConversionHelper::ConvertNumberingType( nIntValue );
2267 xFtnEdnSettings->setPropertyValue(
2268 getPropertyName( PROP_NUMBERING_TYPE),
2269 uno::makeAny( nNumType ));
2272 catch( const uno::Exception& )
2276 break;
2277 case NS_ooxml::LN_paratrackchange:
2278 m_pImpl->StartParaMarkerChange( );
2279 SAL_FALLTHROUGH;
2280 case NS_ooxml::LN_CT_PPr_pPrChange:
2281 case NS_ooxml::LN_trackchange:
2282 case NS_ooxml::LN_EG_RPrContent_rPrChange:
2283 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeStart:
2284 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeEnd:
2285 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeStart:
2286 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeEnd:
2287 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeStart:
2288 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeEnd:
2290 HandleRedline( rSprm );
2292 break;
2293 case NS_ooxml::LN_endtrackchange:
2294 m_pImpl->RemoveTopRedline();
2295 break;
2296 case NS_ooxml::LN_CT_RPrChange_rPr:
2298 // Push all the current 'Character' properties to the stack, so that we don't store them
2299 // as 'tracked changes' by mistake
2300 m_pImpl->PushProperties(CONTEXT_CHARACTER);
2302 // Resolve all the properties that are under the 'rPrChange'->'rPr' XML node
2303 resolveSprmProps(*this, rSprm );
2305 // Get all the properties that were processed in the 'rPrChange'->'rPr' XML node
2306 uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2308 // Pop back out the character properties that were on the run
2309 m_pImpl->PopProperties(CONTEXT_CHARACTER);
2311 // Store these properties in the current redline object (do it after the PopProperties() above, since
2312 // otherwise it'd be stored in the content dropped there).
2313 m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2315 break;
2316 case NS_ooxml::LN_CT_PPrChange_pPr:
2318 // Push all the current 'Paragraph' properties to the stack, so that we don't store them
2319 // as 'tracked changes' by mistake
2320 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2322 // Resolve all the properties that are under the 'pPrChange'->'pPr' XML node
2323 resolveSprmProps(*this, rSprm );
2325 // Get all the properties that were processed in the 'pPrChange'->'pPr' XML node
2326 uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2328 // Pop back out the character properties that were on the run
2329 m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
2331 // Store these properties in the current redline object (do it after the PopProperties() above, since
2332 // otherwise it'd be stored in the content dropped there).
2333 m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2335 break;
2336 case NS_ooxml::LN_object:
2338 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2339 if( pProperties.get( ) )
2341 std::shared_ptr<OLEHandler> pOLEHandler( new OLEHandler(*this) );
2342 pProperties->resolve(*pOLEHandler);
2343 if ( pOLEHandler->isOLEObject( ) )
2345 OUString sStreamName = pOLEHandler->copyOLEOStream( m_pImpl->GetTextDocument() );
2346 if( !sStreamName.isEmpty() )
2348 m_pImpl->appendOLE( sStreamName, pOLEHandler );
2353 break;
2354 case NS_ooxml::LN_EG_HdrFtrReferences_headerReference: // header reference - not needed
2355 case NS_ooxml::LN_EG_HdrFtrReferences_footerReference: // footer reference - not needed
2356 break;
2357 case NS_ooxml::LN_EG_RPrBase_snapToGrid: // "Use document grid settings for inter-paragraph spacing"
2358 break;
2359 case NS_ooxml::LN_CT_PPrBase_contextualSpacing:
2360 rContext->Insert(PROP_PARA_CONTEXT_MARGIN, uno::makeAny( nIntValue != 0 ));
2361 break;
2362 case NS_ooxml::LN_CT_PPrBase_mirrorIndents: // mirrorIndents
2363 rContext->Insert(PROP_MIRROR_INDENTS, uno::makeAny( nIntValue != 0 ), true, PARA_GRAB_BAG);
2364 break;
2365 case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection
2367 if( pSectionContext )
2368 pSectionContext->Insert( PROP_IS_PROTECTED, uno::makeAny( bool(nIntValue) ) );
2370 break;
2371 case NS_ooxml::LN_EG_SectPrContents_vAlign:
2373 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2374 if( pSectionContext )
2376 drawing::TextVerticalAdjust nVA = drawing::TextVerticalAdjust_TOP;
2377 switch( nIntValue )
2379 case NS_ooxml::LN_Value_ST_VerticalJc_center: //92367
2380 nVA = drawing::TextVerticalAdjust_CENTER;
2381 break;
2382 case NS_ooxml::LN_Value_ST_VerticalJc_both: //92368 - justify
2383 nVA = drawing::TextVerticalAdjust_BLOCK;
2384 break;
2385 case NS_ooxml::LN_Value_ST_VerticalJc_bottom: //92369
2386 nVA = drawing::TextVerticalAdjust_BOTTOM;
2387 break;
2388 default:
2389 break;
2391 pSectionContext->Insert( PROP_TEXT_VERTICAL_ADJUST, uno::makeAny( nVA ), true, PARA_GRAB_BAG );
2394 break;
2395 case NS_ooxml::LN_EG_RPrBase_fitText:
2396 break;
2397 case NS_ooxml::LN_ffdata:
2399 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2400 if (pProperties.get() != nullptr)
2402 FFDataHandler::Pointer_t pFFDataHandler(new FFDataHandler());
2404 pProperties->resolve(*pFFDataHandler);
2405 m_pImpl->SetFieldFFData(pFFDataHandler);
2408 break;
2409 case NS_ooxml::LN_CT_SdtPr_dropDownList:
2410 case NS_ooxml::LN_CT_SdtPr_comboBox:
2412 m_pImpl->m_pSdtHelper->setInsideDropDownControl(true);
2413 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2414 if (pProperties.get() != nullptr)
2415 pProperties->resolve(*this);
2417 break;
2418 case NS_ooxml::LN_CT_SdtDropDownList_listItem:
2420 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2421 if (pProperties.get() != nullptr)
2422 pProperties->resolve(*this);
2424 break;
2425 case NS_ooxml::LN_CT_SdtPr_date:
2427 resolveSprmProps(*this, rSprm);
2428 m_pImpl->m_pSdtHelper->setDateFieldStartRange(GetCurrentTextRange()->getEnd());
2430 break;
2431 case NS_ooxml::LN_CT_SdtDate_dateFormat:
2433 m_pImpl->m_pSdtHelper->getDateFormat().append(sStringValue);
2435 break;
2436 case NS_ooxml::LN_CT_SdtDate_storeMappedDataAs:
2439 break;
2440 case NS_ooxml::LN_CT_SdtDate_calendar:
2443 break;
2444 case NS_ooxml::LN_CT_SdtDate_lid:
2446 m_pImpl->m_pSdtHelper->getLocale().append(sStringValue);
2448 break;
2449 case NS_ooxml::LN_CT_SdtPr_dataBinding:
2450 case NS_ooxml::LN_CT_SdtPr_equation:
2451 case NS_ooxml::LN_CT_SdtPr_checkbox:
2452 case NS_ooxml::LN_CT_SdtPr_docPartObj:
2453 case NS_ooxml::LN_CT_SdtPr_docPartList:
2454 case NS_ooxml::LN_CT_SdtPr_picture:
2455 case NS_ooxml::LN_CT_SdtPr_citation:
2456 case NS_ooxml::LN_CT_SdtPr_group:
2457 case NS_ooxml::LN_CT_SdtPr_text:
2458 case NS_ooxml::LN_CT_SdtPr_id:
2459 case NS_ooxml::LN_CT_SdtPr_alias:
2461 // this is an unsupported SDT property, create a grab bag for it
2462 OUString sName;
2463 switch (nSprmId)
2465 case NS_ooxml::LN_CT_SdtPr_dataBinding: sName = "ooxml:CT_SdtPr_dataBinding"; break;
2466 case NS_ooxml::LN_CT_SdtPr_equation: sName = "ooxml:CT_SdtPr_equation"; break;
2467 case NS_ooxml::LN_CT_SdtPr_checkbox: sName = "ooxml:CT_SdtPr_checkbox"; break;
2468 case NS_ooxml::LN_CT_SdtPr_docPartObj: sName = "ooxml:CT_SdtPr_docPartObj"; break;
2469 case NS_ooxml::LN_CT_SdtPr_docPartList: sName = "ooxml:CT_SdtPr_docPartList"; break;
2470 case NS_ooxml::LN_CT_SdtPr_picture: sName = "ooxml:CT_SdtPr_picture"; break;
2471 case NS_ooxml::LN_CT_SdtPr_citation: sName = "ooxml:CT_SdtPr_citation"; break;
2472 case NS_ooxml::LN_CT_SdtPr_group: sName = "ooxml:CT_SdtPr_group"; break;
2473 case NS_ooxml::LN_CT_SdtPr_text: sName = "ooxml:CT_SdtPr_text"; break;
2474 case NS_ooxml::LN_CT_SdtPr_id: sName = "ooxml:CT_SdtPr_id"; break;
2475 case NS_ooxml::LN_CT_SdtPr_alias: sName = "ooxml:CT_SdtPr_alias"; break;
2476 default: assert(false);
2478 enableInteropGrabBag(sName);
2480 // process subitems
2481 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2482 if (pProperties.get() != nullptr)
2483 pProperties->resolve(*this);
2485 if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias)
2487 beans::PropertyValue aValue;
2488 aValue.Name = sName;
2489 aValue.Value <<= sStringValue;
2490 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
2492 else
2493 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
2494 m_pImpl->m_pSdtHelper->setOutsideAParagraph(m_pImpl->IsOutsideAParagraph());
2495 m_pImpl->disableInteropGrabBag();
2497 break;
2498 case NS_ooxml::LN_CT_SdtCheckbox_checked:
2499 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checked", sStringValue);
2500 break;
2501 case NS_ooxml::LN_CT_SdtCheckbox_checkedState:
2502 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checkedState", sStringValue);
2503 break;
2504 case NS_ooxml::LN_CT_SdtCheckbox_uncheckedState:
2505 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_uncheckedState", sStringValue);
2506 break;
2507 case NS_ooxml::LN_CT_SdtDocPart_docPartGallery:
2508 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartGallery", sStringValue);
2509 break;
2510 case NS_ooxml::LN_CT_SdtDocPart_docPartCategory:
2511 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartCategory", sStringValue);
2512 break;
2513 case NS_ooxml::LN_CT_SdtDocPart_docPartUnique:
2514 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartUnique", sStringValue);
2515 break;
2516 case NS_ooxml::LN_EG_SectPrContents_pgNumType:
2518 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2519 if( pProperties.get())
2521 pProperties->resolve(*this);
2524 break;
2525 case NS_ooxml::LN_tblStart:
2527 if (m_pImpl->hasTableManager())
2529 bool bTableStartsAtCellStart = m_pImpl->m_nTableDepth > 0 && m_pImpl->m_nTableCellDepth > m_pImpl->m_nLastTableCellParagraphDepth + 1;
2530 m_pImpl->getTableManager().setTableStartsAtCellStart(bTableStartsAtCellStart);
2533 * Hack for Importing Section Properties
2534 * LO is not able to import section properties if first element in the
2535 * section is a table. So in case first element is a table add a dummy para
2536 * and remove it again when lcl_endSectionGroup is called
2538 if(m_pImpl->m_nTableDepth == 0 && m_pImpl->GetIsFirstParagraphInSection()
2539 && !m_pImpl->GetIsDummyParaAddedForTableInSection() && !m_pImpl->GetIsTextFrameInserted()
2540 && !IsInHeaderFooter())
2542 m_pImpl->AddDummyParaForTableInSection();
2545 // if first paragraph style in table has break-before-page, transfer that setting to the table itself.
2546 if( m_pImpl->m_nTableDepth == 0 )
2548 const uno::Any aBreakType = uno::makeAny(style::BreakType_PAGE_BEFORE);
2549 const PropertyMapPtr pParagraphProps = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
2550 if( pParagraphProps && pParagraphProps->isSet(PROP_PARA_STYLE_NAME) )
2552 StyleSheetEntryPtr pStyle;
2553 OUString sStyleName;
2554 pParagraphProps->getProperty(PROP_PARA_STYLE_NAME)->second >>= sStyleName;
2555 if( !sStyleName.isEmpty() && GetStyleSheetTable() )
2556 pStyle = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( sStyleName );
2558 if( pStyle && pStyle->pProperties
2559 && pStyle->pProperties->isSet(PROP_BREAK_TYPE)
2560 && pStyle->pProperties->getProperty(PROP_BREAK_TYPE)->second == aBreakType )
2562 pParagraphProps->Insert(PROP_BREAK_TYPE, aBreakType);
2567 m_pImpl->m_nTableDepth++;
2569 break;
2570 case NS_ooxml::LN_tblEnd:
2571 m_pImpl->m_nTableDepth--;
2572 break;
2573 case NS_ooxml::LN_tcStart:
2574 m_pImpl->m_nTableCellDepth++;
2575 break;
2576 case NS_ooxml::LN_tcEnd:
2577 m_pImpl->m_nTableCellDepth--;
2578 m_pImpl->m_nLastTableCellParagraphDepth = 0;
2579 break;
2580 case NS_ooxml::LN_glow_glow:
2581 case NS_ooxml::LN_shadow_shadow:
2582 case NS_ooxml::LN_reflection_reflection:
2583 case NS_ooxml::LN_textOutline_textOutline:
2584 case NS_ooxml::LN_textFill_textFill:
2585 case NS_ooxml::LN_scene3d_scene3d:
2586 case NS_ooxml::LN_props3d_props3d:
2587 case NS_ooxml::LN_ligatures_ligatures:
2588 case NS_ooxml::LN_numForm_numForm:
2589 case NS_ooxml::LN_numSpacing_numSpacing:
2590 case NS_ooxml::LN_stylisticSets_stylisticSets:
2591 case NS_ooxml::LN_cntxtAlts_cntxtAlts:
2593 tools::SvRef<TextEffectsHandler> pTextEffectsHandlerPtr( new TextEffectsHandler(nSprmId) );
2594 boost::optional<PropertyIds> aPropertyId = pTextEffectsHandlerPtr->getGrabBagPropertyId();
2595 if(aPropertyId)
2597 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2598 if( pProperties.get())
2600 pProperties->resolve(*pTextEffectsHandlerPtr);
2602 rContext->Insert(*aPropertyId, uno::makeAny(pTextEffectsHandlerPtr->getInteropGrabBag()), true, CHAR_GRAB_BAG);
2606 break;
2607 case NS_ooxml::LN_CT_SdtPr_rPr:
2609 // Make sure properties from a previous SDT are not merged with the current ones.
2610 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
2612 break;
2613 case NS_ooxml::LN_CT_TblPrBase_tblLook:
2615 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2616 if (pProperties.get())
2618 pProperties->resolve(*this);
2619 m_pImpl->getTableManager().finishTableLook();
2622 break;
2623 case NS_ooxml::LN_CT_TrPrBase_cnfStyle:
2625 m_pImpl->enableInteropGrabBag("cnfStyle");
2626 resolveSprmProps(*this, rSprm);
2628 TablePropertyMapPtr pPropMap(new TablePropertyMap());
2629 pPropMap->Insert(PROP_ROW_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, ROW_GRAB_BAG);
2630 m_pImpl->getTableManager().insertRowProps(pPropMap);
2632 m_pImpl->disableInteropGrabBag();
2634 break;
2635 case NS_ooxml::LN_CT_TcPrBase_cnfStyle:
2637 m_pImpl->enableInteropGrabBag("cnfStyle");
2638 resolveSprmProps(*this, rSprm);
2640 TablePropertyMapPtr pPropMap(new TablePropertyMap());
2641 pPropMap->Insert(PROP_CELL_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, CELL_GRAB_BAG);
2642 m_pImpl->getTableManager().cellProps(pPropMap);
2644 m_pImpl->disableInteropGrabBag();
2646 break;
2647 case NS_ooxml::LN_CT_PPrBase_cnfStyle:
2649 m_pImpl->enableInteropGrabBag("cnfStyle");
2650 resolveSprmProps(*this, rSprm);
2651 rContext->Insert(PROP_PARA_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, PARA_GRAB_BAG);
2652 m_pImpl->disableInteropGrabBag();
2654 break;
2655 case NS_ooxml::LN_EG_RunInnerContent_sym:
2657 resolveSprmProps(*this, rSprm);
2658 SymbolData aSymbolData = m_pImpl->GetSymbolData();
2659 uno::Any aVal = uno::makeAny( aSymbolData.sFont );
2660 if( rContext->GetFootnote().is())
2662 uno::Reference< beans::XPropertySet > xAnchorProps( rContext->GetFootnote()->getAnchor(), uno::UNO_QUERY );
2663 xAnchorProps->setPropertyValue( getPropertyName( PROP_CHAR_FONT_NAME), aVal);
2664 rContext->GetFootnote()->setLabel(OUString( aSymbolData.cSymbol ));
2666 else //it's a _real_ symbol
2668 rContext->Insert(PROP_CHAR_FONT_NAME, aVal);
2669 rContext->Insert(PROP_CHAR_FONT_NAME_ASIAN, aVal);
2670 rContext->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aVal);
2671 rContext->Insert(PROP_CHAR_FONT_CHAR_SET, uno::makeAny(awt::CharSet::SYMBOL));
2672 utext( reinterpret_cast < const sal_uInt8 * >( &(aSymbolData.cSymbol) ), 1 );
2675 break;
2676 case NS_ooxml::LN_EG_RunInnerContent_ruby:
2678 RubyInfo aInfo ;
2679 m_pImpl->SetRubyInfo(aInfo);
2681 break;
2682 case NS_ooxml::LN_CT_RubyPr:
2683 case NS_ooxml::LN_CT_Ruby_rt:
2684 case NS_ooxml::LN_CT_Ruby_rubyBase:
2686 m_pImpl->SetRubySprmId(nSprmId);
2687 if (nSprmId == NS_ooxml::LN_CT_RubyPr)
2689 resolveSprmProps(*this, rSprm);
2692 break;
2693 case NS_ooxml::LN_EG_RubyContent_r:
2695 const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
2696 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase)
2698 rContext->Insert(PROP_RUBY_TEXT, uno::makeAny(aInfo.sRubyText));
2699 rContext->Insert(PROP_RUBY_STYLE, uno::makeAny(aInfo.sRubyStyle));
2700 rContext->Insert(PROP_RUBY_ADJUST, uno::makeAny(static_cast<sal_Int16>(ConversionHelper::convertRubyAlign(aInfo.nRubyAlign))));
2701 if ( aInfo.nRubyAlign == NS_ooxml::LN_Value_ST_RubyAlign_rightVertical )
2702 rContext->Insert(PROP_RUBY_POSITION, uno::makeAny(css::text::RubyPosition::INTER_CHARACTER));
2704 m_pImpl->SetRubySprmId(0);
2707 break;
2708 case NS_ooxml::LN_CT_RubyPr_rubyAlign:
2709 case NS_ooxml::LN_CT_RubyPr_hps:
2710 case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
2712 RubyInfo aInfo = m_pImpl->GetRubyInfo();
2713 switch(nSprmId)
2715 case NS_ooxml::LN_CT_RubyPr_rubyAlign:
2716 aInfo.nRubyAlign = nIntValue;
2717 break;
2718 case NS_ooxml::LN_CT_RubyPr_hps:
2719 aInfo.nHps= nIntValue;
2720 break;
2721 case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
2722 aInfo.nHpsBaseText = nIntValue;
2723 break;
2725 m_pImpl->SetRubyInfo(aInfo);
2727 break;
2728 case NS_ooxml::LN_CT_SmartTagRun_smartTagPr:
2730 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2731 if (pProperties.get() && m_pImpl->GetTopContextType() == CONTEXT_PARAGRAPH)
2732 pProperties->resolve(m_pImpl->getSmartTagHandler());
2734 break;
2735 case NS_ooxml::LN_CT_DocPartPr_name:
2737 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2738 if (pProperties.get() != nullptr)
2739 pProperties->resolve(*this);
2741 break;
2742 case NS_ooxml::LN_CT_DocPartPr_category:
2744 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2745 if (pProperties.get() != nullptr)
2746 pProperties->resolve(*this);
2748 break;
2749 case NS_ooxml::LN_CT_DocPartCategory_gallery:
2751 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
2752 if (pProperties.get() != nullptr)
2753 pProperties->resolve(*this);
2755 break;
2756 default:
2758 #ifdef DEBUG_WRITERFILTER
2759 TagLogger::getInstance().startElement("unhandled");
2760 TagLogger::getInstance().attribute("id", nSprmId);
2761 TagLogger::getInstance().attribute("name", rSprm.getName());
2762 TagLogger::getInstance().endElement();
2763 #endif
2768 void DomainMapper::setInTableStyleRunProps(bool bInTableStyleRunProps)
2770 m_pImpl->m_bInTableStyleRunProps = bInTableStyleRunProps;
2773 void DomainMapper::processDeferredCharacterProperties( const std::map< sal_Int32, uno::Any >& deferredCharacterProperties )
2775 assert( m_pImpl->GetTopContextType() == CONTEXT_CHARACTER );
2776 PropertyMapPtr rContext = m_pImpl->GetTopContext();
2777 for( const auto& rProp : deferredCharacterProperties )
2779 sal_Int32 Id = rProp.first;
2780 sal_Int32 nIntValue = 0;
2781 OUString sStringValue;
2782 rProp.second >>= nIntValue;
2783 rProp.second >>= sStringValue;
2784 switch( Id )
2786 case NS_ooxml::LN_EG_RPrBase_sz:
2787 case NS_ooxml::LN_EG_RPrBase_szCs:
2788 break; // only for use by other properties, ignore here
2789 case NS_ooxml::LN_EG_RPrBase_position:
2791 sal_Int16 nEscapement = 0;
2792 sal_Int8 nProp = 100;
2793 if(nIntValue == 0)
2794 nProp = 0;
2795 else
2797 std::map< sal_Int32, uno::Any >::const_iterator font = deferredCharacterProperties.find( NS_ooxml::LN_EG_RPrBase_sz );
2798 PropertyMapPtr pDefaultCharProps = m_pImpl->GetStyleSheetTable()->GetDefaultCharProps();
2799 boost::optional<PropertyMap::Property> aDefaultFont = pDefaultCharProps->getProperty(PROP_CHAR_HEIGHT);
2800 if( font != deferredCharacterProperties.end())
2802 double fontSize = 0;
2803 font->second >>= fontSize;
2804 if (fontSize != 0.0)
2805 nEscapement = nIntValue * 100 / fontSize;
2807 // TODO if not direct formatting, check the style first, not directly the default char props.
2808 else if (aDefaultFont)
2810 double fHeight = 0;
2811 aDefaultFont->second >>= fHeight;
2812 if (fHeight != 0.0)
2814 // fHeight is in points, nIntValue is in half points, nEscapement is in percents.
2815 nEscapement = nIntValue * 100 / fHeight / 2;
2818 else
2819 { // TODO: Find out the font size. The 58/-58 values were here previous, but I have
2820 // no idea what they are (they are probably some random guess that did fit whatever
2821 // specific case somebody was trying to fix).
2822 nEscapement = ( nIntValue > 0 ) ? 58: -58;
2825 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( nEscapement ) );
2826 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::makeAny( nProp ) );
2828 break;
2829 default:
2830 SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" );
2831 break;
2836 void DomainMapper::lcl_entry(int /*pos*/,
2837 writerfilter::Reference<Properties>::Pointer_t ref)
2839 ref->resolve(*this);
2842 void DomainMapper::data(const sal_uInt8* /*buf*/, size_t /*len*/,
2843 writerfilter::Reference<Properties>::Pointer_t /*ref*/)
2847 void DomainMapper::lcl_startSectionGroup()
2849 if (!m_pImpl->isInIndexContext() && !m_pImpl->isInBibliographyContext())
2851 m_pImpl->PushProperties(CONTEXT_SECTION);
2853 m_pImpl->SetIsFirstParagraphInSection(true);
2856 void DomainMapper::lcl_endSectionGroup()
2858 if (!m_pImpl->isInIndexContext() && !m_pImpl->isInBibliographyContext())
2860 m_pImpl->CheckUnregisteredFrameConversion();
2861 m_pImpl->ExecuteFrameConversion();
2862 // When pasting, it's fine to not have any paragraph inside the document at all.
2863 if (m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->IsNewDoc())
2865 // This section has no paragraph at all (e.g. they are all actually in a frame).
2866 // If this section has a page break, there would be nothing to apply to the page
2867 // style, so force a dummy paragraph.
2868 lcl_startParagraphGroup();
2869 lcl_startCharacterGroup();
2870 sal_uInt8 const sBreak[] = { 0xd };
2871 lcl_text(sBreak, 1);
2872 lcl_endCharacterGroup();
2873 lcl_endParagraphGroup();
2875 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_SECTION);
2876 SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
2877 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2878 if(pSectionContext)
2880 pSectionContext->CloseSectionGroup( *m_pImpl );
2881 // Remove the dummy paragraph if added for
2882 // handling the section properties if section starts with a table
2883 if (m_pImpl->GetIsDummyParaAddedForTableInSection())
2884 m_pImpl->RemoveDummyParaForTableInSection();
2886 m_pImpl->SetIsTextFrameInserted( false );
2887 m_pImpl->PopProperties(CONTEXT_SECTION);
2891 void DomainMapper::lcl_startParagraphGroup()
2893 if (m_pImpl->hasTableManager())
2894 m_pImpl->getTableManager().startParagraphGroup();
2896 * Add new para properties only if paragraph is not split
2897 * or the top context is not of paragraph properties
2898 * Set mbIsSplitPara to false as it has been handled
2900 if (!mbIsSplitPara)
2901 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2902 mbIsSplitPara = false;
2903 if (!(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) == m_pImpl->GetTopContext()))
2904 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2906 if (m_pImpl->GetTopContext())
2908 if (!m_pImpl->IsInShape())
2910 const OUString& sDefaultParaStyle = m_pImpl->GetDefaultParaStyleName();
2911 m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::makeAny( sDefaultParaStyle ) );
2912 m_pImpl->SetCurrentParaStyleName( sDefaultParaStyle );
2914 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
2915 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
2916 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
2917 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
2919 if (m_pImpl->isParaSdtEndDeferred())
2920 m_pImpl->GetTopContext()->Insert(PROP_PARA_SDT_END_BEFORE, uno::makeAny(true), true, PARA_GRAB_BAG);
2922 m_pImpl->SetIsFirstRun(true);
2923 m_pImpl->SetIsOutsideAParagraph(false);
2924 m_pImpl->clearDeferredBreaks();
2925 m_pImpl->setParaSdtEndDeferred(false);
2928 void DomainMapper::lcl_endParagraphGroup()
2930 m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
2931 if (m_pImpl->hasTableManager())
2932 m_pImpl->getTableManager().endParagraphGroup();
2933 //frame conversion has to be executed after table conversion
2934 m_pImpl->ExecuteFrameConversion();
2935 m_pImpl->SetIsOutsideAParagraph(true);
2938 void DomainMapper::markLastParagraphInSection( )
2940 m_pImpl->SetIsLastParagraphInSection( true );
2943 void DomainMapper::markLastSectionGroup( )
2945 m_pImpl->SetIsLastSectionGroup( true );
2948 void DomainMapper::lcl_startShape(uno::Reference<drawing::XShape> const& xShape)
2950 if (m_pImpl->GetTopContext())
2952 // If there is a deferred page break, handle it now, so that the
2953 // started shape will be on the correct page.
2954 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
2956 m_pImpl->clearDeferredBreak(PAGE_BREAK);
2957 lcl_startCharacterGroup();
2958 sal_uInt8 const sBreak[] = { 0xd };
2959 lcl_text(sBreak, 1);
2960 lcl_endCharacterGroup();
2961 lcl_endParagraphGroup();
2962 lcl_startParagraphGroup();
2963 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
2965 m_pImpl->PushShapeContext( xShape );
2966 lcl_startParagraphGroup();
2968 else
2969 // No context? Then this image should not appear directly inside the
2970 // document, just save it for later usage.
2971 m_pImpl->PushPendingShape(xShape);
2973 m_pImpl->SetIsFirstParagraphInShape(true);
2976 void DomainMapper::lcl_endShape( )
2978 if (m_pImpl->GetTopContext())
2980 // End the current table, if there are any. Otherwise the unavoidable
2981 // empty paragraph at the end of the shape text will cause problems: if
2982 // the shape text ends with a table, the extra paragraph will be
2983 // handled as an additional row of the ending table.
2984 if (m_pImpl->hasTableManager())
2985 m_pImpl->getTableManager().endTable();
2987 lcl_endParagraphGroup();
2988 m_pImpl->PopShapeContext( );
2989 // A shape is always inside a shape (anchored or inline).
2990 m_pImpl->SetIsOutsideAParagraph(false);
2994 void DomainMapper::PushStyleSheetProperties( const PropertyMapPtr& pStyleProperties, bool bAffectTableMngr )
2996 m_pImpl->PushStyleProperties( pStyleProperties );
2997 if ( bAffectTableMngr )
2998 m_pImpl->getTableManager( ).SetStyleProperties( pStyleProperties );
3001 void DomainMapper::PopStyleSheetProperties( bool bAffectTableMngr )
3003 m_pImpl->PopProperties( CONTEXT_STYLESHEET );
3004 if ( bAffectTableMngr )
3006 PropertyMapPtr emptyPtr;
3007 m_pImpl->getTableManager( ).SetStyleProperties( emptyPtr );
3011 void DomainMapper::PushListProperties( const ::tools::SvRef<PropertyMap>& pListProperties )
3013 m_pImpl->PushListProperties( pListProperties );
3016 void DomainMapper::PopListProperties()
3018 m_pImpl->PopProperties( CONTEXT_LIST );
3021 void DomainMapper::lcl_startCharacterGroup()
3023 m_pImpl->PushProperties(CONTEXT_CHARACTER);
3024 if (m_pImpl->isSdtEndDeferred())
3026 // Fields have an empty character group before the real one, so don't
3027 // call setSdtEndDeferred(false) here, that will happen only in lcl_utext().
3028 m_pImpl->GetTopContext()->Insert(PROP_SDT_END_BEFORE, uno::makeAny(true), true, CHAR_GRAB_BAG);
3032 void DomainMapper::lcl_endCharacterGroup()
3034 m_pImpl->PopProperties(CONTEXT_CHARACTER);
3037 void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
3039 //TODO: Determine the right text encoding (FIB?)
3040 OUString sText( reinterpret_cast<const char*>(data_), len, RTL_TEXTENCODING_MS_1252 );
3041 #ifdef DEBUG_WRITERFILTER
3042 TagLogger::getInstance().startElement("text");
3043 TagLogger::getInstance().chars(sText);
3044 TagLogger::getInstance().endElement();
3045 #endif
3049 if(len == 1)
3051 switch(*data_)
3053 case 0x02: return; //footnote character
3054 case 0x08: // Lock field if in field context
3055 if (m_pImpl->IsOpenField())
3056 m_pImpl->SetFieldLocked();
3057 return;
3058 case 0x0c: //page break
3059 m_pImpl->deferBreak(PAGE_BREAK);
3060 return;
3061 case 0x0e: //column break
3062 m_pImpl->deferBreak(COLUMN_BREAK);
3063 return;
3064 case 0x07:
3065 m_pImpl->getTableManager().text(data_, len);
3066 return;
3067 case 0x0d:
3069 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3070 if (pContext && m_pImpl->isBreakDeferred(COLUMN_BREAK))
3072 pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
3073 m_pImpl->clearDeferredBreak(COLUMN_BREAK);
3075 finishParagraph();
3076 return;
3078 case cFieldStart:
3079 m_pImpl->PushFieldContext();
3080 return;
3081 case cFieldSep:
3082 // delimiter not necessarily available
3083 // appears only if field contains further content
3084 m_pImpl->CloseFieldCommand();
3085 return;
3086 case cFieldEnd:
3087 // In case there isn't any field separator.
3088 if ( m_pImpl->IsOpenFieldCommand() )
3089 m_pImpl->CloseFieldCommand();
3090 m_pImpl->PopFieldContext();
3091 return;
3092 default:
3093 break;
3097 PropertyMapPtr pContext = m_pImpl->GetTopContext();
3098 if (pContext && !pContext->GetFootnote().is())
3100 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3101 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
3102 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3103 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
3104 m_pImpl->clearDeferredBreaks();
3107 if( pContext->GetFootnote().is() && m_pImpl->IsCustomFtnMark() )
3109 pContext->GetFootnote()->setLabel( sText );
3110 m_pImpl->SetCustomFtnMark( false );
3111 //otherwise ignore sText
3113 else if( m_pImpl->IsOpenFieldCommand() )
3114 m_pImpl->AppendFieldCommand(sText);
3115 else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
3116 /*depending on the success of the field insert operation this result will be
3117 set at the field or directly inserted into the text*/
3118 m_pImpl->AppendFieldResult(sText);
3119 else
3121 if (pContext == nullptr)
3122 pContext = new PropertyMap();
3124 m_pImpl->appendTextPortion( sText, pContext );
3127 catch( const uno::RuntimeException& e )
3129 SAL_WARN("writerfilter", "failed. Message :" << e);
3133 void DomainMapper::lcl_positionOffset(const OUString& rText, bool bVertical)
3135 if (bVertical)
3136 m_pImpl->m_aPositionOffsets.second = rText;
3137 else
3138 m_pImpl->m_aPositionOffsets.first = rText;
3141 awt::Point DomainMapper::getPositionOffset()
3143 awt::Point aRet;
3144 aRet.X = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.first.toInt32());
3145 aRet.Y = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.second.toInt32());
3146 return aRet;
3149 void DomainMapper::lcl_align(const OUString& rText, bool bVertical)
3151 if (bVertical)
3152 m_pImpl->m_aAligns.second = rText;
3153 else
3154 m_pImpl->m_aAligns.first = rText;
3157 void DomainMapper::lcl_positivePercentage(const OUString& rText)
3159 m_pImpl->m_aPositivePercentages.push(rText);
3162 void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
3164 OUString sText(reinterpret_cast<const sal_Unicode *>(data_), len);
3165 const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
3166 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt)
3168 PropertyMapPtr pContext = m_pImpl->GetTopContext();
3169 PropertyValueVector_t aProps = comphelper::sequenceToContainer< PropertyValueVector_t >(pContext->GetPropertyValues());
3170 OUString sStyle = getOrCreateCharStyle(aProps, /*bAlwaysCreate=*/false);
3171 m_pImpl->SetRubyText(sText,sStyle);
3172 return;
3175 if (m_pImpl->isSdtEndDeferred())
3177 // In case we have a field context, then save the property there, so
3178 // SDT's ending right before a field start are handled as well.
3179 PropertyMapPtr pContext = m_pImpl->GetTopContext();
3180 if (m_pImpl->IsOpenField())
3181 pContext = m_pImpl->GetTopFieldContext()->getProperties();
3182 pContext->Insert(PROP_SDT_END_BEFORE, uno::makeAny(true), true, CHAR_GRAB_BAG);
3183 m_pImpl->setSdtEndDeferred(false);
3186 bool bNewLine = len == 1 && (sText[0] == 0x0d || sText[0] == 0x07);
3187 if (m_pImpl->m_pSdtHelper->isInsideDropDownControl())
3189 if (bNewLine)
3190 // Dropdown control has single-line texts, so in case of newline, create the control.
3191 m_pImpl->m_pSdtHelper->createDropDownControl();
3192 else
3194 m_pImpl->m_pSdtHelper->getSdtTexts().append(sText);
3195 return;
3198 else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty())
3200 // Ignore grabbag when we have a date field, it can conflict during export
3201 if(m_pImpl->m_pSdtHelper->validateDateFormat())
3203 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3205 else
3208 // there are unsupported SDT properties in the document
3209 // save them in the paragraph interop grab bag
3210 if (m_pImpl->IsDiscardHeaderFooter())
3212 // Unless we're supposed to ignore this header/footer.
3213 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3214 return;
3216 if((m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") ||
3217 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") ||
3218 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") ||
3219 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") ||
3220 (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") &&
3221 m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph())
3223 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER);
3225 if (m_pImpl->IsOpenField())
3226 // We have a field, insert the SDT properties to the field's grab-bag, so they won't be lost.
3227 pContext = m_pImpl->GetTopFieldContext()->getProperties();
3229 pContext->Insert(PROP_SDTPR, uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, CHAR_GRAB_BAG);
3231 else
3232 m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR,
3233 uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, PARA_GRAB_BAG);
3236 else if (len == 1 && sText[0] == 0x03)
3238 // This is the uFtnEdnSep, remember that the document has a separator.
3239 m_pImpl->m_bHasFtnSep = true;
3240 return;
3242 else if (len == 1 && sText[0] == '\t' )
3244 if ( m_pImpl->m_bCheckFirstFootnoteTab && m_pImpl->IsInFootOrEndnote() )
3246 // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent
3247 m_pImpl->m_bCheckFirstFootnoteTab = false;
3248 sal_Int32 nFirstLineIndent = 0;
3249 m_pImpl->GetAnyProperty(PROP_PARA_FIRST_LINE_INDENT, m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)) >>= nFirstLineIndent;
3250 if ( nFirstLineIndent < 0 )
3251 m_pImpl->m_bIgnoreNextTab = true;
3254 if ( m_pImpl->m_bIgnoreNextTab )
3256 m_pImpl->m_bIgnoreNextTab = false;
3257 return;
3260 else if (m_pImpl->m_pSdtHelper->validateDateFormat())
3262 if(IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
3264 m_pImpl->m_pSdtHelper->getDateFormat().truncate();
3265 m_pImpl->m_pSdtHelper->getLocale().truncate();
3266 return;
3269 if (!m_pImpl->hasTableManager())
3270 return;
3274 m_pImpl->getTableManager().utext(data_, len);
3276 if (bNewLine)
3278 if (m_pImpl->m_bIgnoreNextPara)
3280 m_pImpl->m_bIgnoreNextPara = false;
3281 return;
3284 const bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection();
3285 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3286 if (pContext && !pContext->GetFootnote().is())
3288 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3290 if (m_pImpl->GetSettingsTable()->GetSplitPgBreakAndParaMark())
3292 if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
3294 m_pImpl->m_bIsSplitPara = true;
3295 m_pImpl->finishParagraph( m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) );
3296 lcl_startParagraphGroup();
3299 pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
3300 m_pImpl->clearDeferredBreaks();
3303 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3305 if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
3307 mbIsSplitPara = true;
3308 finishParagraph();
3309 lcl_startParagraphGroup();
3312 pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
3313 m_pImpl->clearDeferredBreaks();
3317 // If the paragraph contains only the section properties and it has
3318 // no runs, we should not create a paragraph for it in Writer, unless that would remove the whole section.
3319 SectionPropertyMap* pSectionContext = m_pImpl->GetSectionContext();
3320 bool bRemove = !m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr()
3321 && !bSingleParagraph
3322 && !m_pImpl->GetIsDummyParaAddedForTableInSection()
3323 && !( pSectionContext && pSectionContext->GetBreakType() != -1 && pContext && pContext->isSet(PROP_BREAK_TYPE) )
3324 && !m_pImpl->GetIsPreviousParagraphFramed();
3326 const bool bNoNumbering = bRemove || (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && bSingleParagraph);
3327 PropertyMapPtr xContext = bNoNumbering ? m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) : PropertyMapPtr();
3328 if (xContext)
3330 // tdf#97417 delete numbering of the paragraph
3331 // it will be deleted anyway, and the numbering would be copied
3332 // to the next paragraph in sw SplitNode and then be applied to
3333 // every following paragraph
3334 xContext->Erase(PROP_NUMBERING_RULES);
3335 xContext->Erase(PROP_NUMBERING_LEVEL);
3337 m_pImpl->SetParaSectpr(false);
3338 finishParagraph(bRemove);
3339 if (bRemove)
3340 m_pImpl->RemoveLastParagraph();
3342 else
3345 PropertyMapPtr pContext = m_pImpl->GetTopContext();
3346 if ( pContext && !pContext->GetFootnote().is() )
3348 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3350 /* If PAGEBREAK appears in first paragraph of the section or
3351 * after first run of any paragraph then need to split paragraph
3352 * to handle it properly.
3354 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
3356 m_pImpl->m_bIsSplitPara = true;
3357 finishParagraph();
3358 lcl_startParagraphGroup();
3360 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE));
3362 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3364 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
3366 mbIsSplitPara = true;
3367 finishParagraph();
3368 lcl_startParagraphGroup();
3370 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE));
3372 m_pImpl->clearDeferredBreaks();
3375 if( pContext && pContext->GetFootnote().is() )
3377 pContext->GetFootnote()->setLabel( sText );
3378 //otherwise ignore sText
3380 else if( m_pImpl->IsOpenFieldCommand() )
3381 m_pImpl->AppendFieldCommand(sText);
3382 else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
3383 /*depending on the success of the field insert operation this result will be
3384 set at the field or directly inserted into the text*/
3385 m_pImpl->AppendFieldResult(sText);
3386 else
3388 if (pContext == nullptr)
3389 pContext = new PropertyMap();
3391 m_pImpl->appendTextPortion( sText, pContext );
3395 m_pImpl->SetIsFirstRun(false);
3397 catch( const uno::RuntimeException& )
3402 void DomainMapper::lcl_props(writerfilter::Reference<Properties>::Pointer_t ref)
3404 ref->resolve(*this);
3407 void DomainMapper::lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t ref)
3409 m_pImpl->SetAnyTableImport(true);
3410 switch(name)
3412 case NS_ooxml::LN_FONTTABLE:
3414 // create a font table object that listens to the attributes
3415 // each entry call inserts a new font entry
3416 ref->resolve( *m_pImpl->GetFontTable() );
3417 break;
3418 case NS_ooxml::LN_STYLESHEET:
3419 //same as above to import style sheets
3420 m_pImpl->SetStyleSheetImport( true );
3421 ref->resolve( *m_pImpl->GetStyleSheetTable() );
3422 m_pImpl->GetStyleSheetTable()->ApplyStyleSheets(m_pImpl->GetFontTable());
3423 m_pImpl->SetStyleSheetImport( false );
3424 break;
3425 case NS_ooxml::LN_NUMBERING:
3428 //the same for list tables
3429 ref->resolve( *m_pImpl->GetListTable() );
3430 m_pImpl->GetListTable( )->CreateNumberingRules( );
3432 break;
3433 case NS_ooxml::LN_THEMETABLE:
3434 m_pImpl->GetThemeTable()->setThemeFontLangProperties(
3435 m_pImpl->GetSettingsTable()->GetThemeFontLangProperties() );
3436 ref->resolve ( *m_pImpl->GetThemeTable() );
3437 break;
3438 case NS_ooxml::LN_settings_settings:
3439 ref->resolve ( *m_pImpl->GetSettingsTable() );
3440 m_pImpl->ApplySettingsTable();
3441 break;
3442 default:
3443 OSL_FAIL( "which table is to be filled here?");
3445 m_pImpl->SetAnyTableImport(false);
3448 void DomainMapper::lcl_substream(Id rName, ::writerfilter::Reference<Stream>::Pointer_t ref)
3450 m_pImpl->substream(rName, ref);
3453 void DomainMapper::lcl_info(const std::string & /*info_*/)
3457 void DomainMapper::lcl_startGlossaryEntry()
3459 uno::Reference< text::XTextRange > xTextRange = GetCurrentTextRange();
3460 m_pImpl->setGlossaryEntryStart(xTextRange);
3463 void DomainMapper::lcl_endGlossaryEntry()
3465 m_pImpl->appendGlossaryEntry();
3468 void DomainMapper::handleUnderlineType(const Id nId, const ::tools::SvRef<PropertyMap>& rContext)
3470 sal_Int16 nUnderline = awt::FontUnderline::NONE;
3472 switch (nId)
3474 case NS_ooxml::LN_Value_ST_Underline_none:
3475 nUnderline = awt::FontUnderline::NONE;
3476 break;
3477 case NS_ooxml::LN_Value_ST_Underline_words:
3478 rContext->Insert(PROP_CHAR_WORD_MODE, uno::makeAny(true));
3479 SAL_FALLTHROUGH;
3480 case NS_ooxml::LN_Value_ST_Underline_single:
3481 nUnderline = awt::FontUnderline::SINGLE;
3482 break;
3483 case NS_ooxml::LN_Value_ST_Underline_double:
3484 nUnderline = awt::FontUnderline::DOUBLE;
3485 break;
3486 case NS_ooxml::LN_Value_ST_Underline_dotted:
3487 nUnderline = awt::FontUnderline::DOTTED;
3488 break;
3489 case NS_ooxml::LN_Value_ST_Underline_dash:
3490 nUnderline = awt::FontUnderline::DASH;
3491 break;
3492 case NS_ooxml::LN_Value_ST_Underline_dotDash:
3493 nUnderline = awt::FontUnderline::DASHDOT;
3494 break;
3495 case NS_ooxml::LN_Value_ST_Underline_dotDotDash:
3496 nUnderline = awt::FontUnderline::DASHDOTDOT;
3497 break;
3498 case NS_ooxml::LN_Value_ST_Underline_thick:
3499 nUnderline = awt::FontUnderline::BOLD;
3500 break;
3501 case NS_ooxml::LN_Value_ST_Underline_wave:
3502 nUnderline = awt::FontUnderline::WAVE;
3503 break;
3504 case NS_ooxml::LN_Value_ST_Underline_dottedHeavy:
3505 nUnderline = awt::FontUnderline::BOLDDOTTED;
3506 break;
3507 case NS_ooxml::LN_Value_ST_Underline_dashedHeavy:
3508 nUnderline = awt::FontUnderline::BOLDDASH;
3509 break;
3510 case NS_ooxml::LN_Value_ST_Underline_dashLong:
3511 nUnderline = awt::FontUnderline::LONGDASH;
3512 break;
3513 case NS_ooxml::LN_Value_ST_Underline_dashLongHeavy:
3514 nUnderline = awt::FontUnderline::BOLDLONGDASH;
3515 break;
3516 case NS_ooxml::LN_Value_ST_Underline_dashDotHeavy:
3517 nUnderline = awt::FontUnderline::BOLDDASHDOT;
3518 break;
3519 case NS_ooxml::LN_Value_ST_Underline_dashDotDotHeavy:
3520 nUnderline = awt::FontUnderline::BOLDDASHDOTDOT;
3521 break;
3522 case NS_ooxml::LN_Value_ST_Underline_wavyHeavy:
3523 nUnderline = awt::FontUnderline::BOLDWAVE;
3524 break;
3525 case NS_ooxml::LN_Value_ST_Underline_wavyDouble:
3526 nUnderline = awt::FontUnderline::DOUBLEWAVE;
3527 break;
3529 rContext->Insert(PROP_CHAR_UNDERLINE, uno::makeAny(nUnderline));
3532 void DomainMapper::handleParaJustification(const sal_Int32 nIntValue, const ::tools::SvRef<PropertyMap>& rContext, const bool bExchangeLeftRight)
3534 style::ParagraphAdjust nAdjust = style::ParagraphAdjust_LEFT;
3535 style::ParagraphAdjust nLastLineAdjust = style::ParagraphAdjust_LEFT;
3536 OUString aStringValue = "left";
3537 switch(nIntValue)
3539 case NS_ooxml::LN_Value_ST_Jc_center:
3540 nAdjust = style::ParagraphAdjust_CENTER;
3541 aStringValue = "center";
3542 break;
3543 case NS_ooxml::LN_Value_ST_Jc_right:
3544 case NS_ooxml::LN_Value_ST_Jc_end:
3545 nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_LEFT : style::ParagraphAdjust_RIGHT;
3546 aStringValue = "right";
3547 break;
3548 case 4:
3549 nLastLineAdjust = style::ParagraphAdjust_BLOCK;
3550 SAL_FALLTHROUGH;
3551 case NS_ooxml::LN_Value_ST_Jc_both:
3552 nAdjust = style::ParagraphAdjust_BLOCK;
3553 aStringValue = "both";
3554 break;
3555 case NS_ooxml::LN_Value_ST_Jc_left:
3556 case NS_ooxml::LN_Value_ST_Jc_start:
3557 default:
3558 nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
3559 break;
3561 rContext->Insert( PROP_PARA_ADJUST, uno::makeAny( nAdjust ) );
3562 rContext->Insert( PROP_PARA_LAST_LINE_ADJUST, uno::makeAny( nLastLineAdjust ) );
3563 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "jc", aStringValue);
3566 bool DomainMapper::getColorFromId(const Id nId, sal_Int32 &nColor)
3568 nColor = 0;
3569 if ((nId < NS_ooxml::LN_Value_ST_HighlightColor_black) || (nId > NS_ooxml::LN_Value_ST_HighlightColor_lightGray))
3570 return false;
3572 switch (nId)
3574 case NS_ooxml::LN_Value_ST_HighlightColor_black: nColor=0x000000; break;
3575 case NS_ooxml::LN_Value_ST_HighlightColor_blue: nColor=0x0000ff; break;
3576 case NS_ooxml::LN_Value_ST_HighlightColor_cyan: nColor=0x00ffff; break;
3577 case NS_ooxml::LN_Value_ST_HighlightColor_green: nColor=0x00ff00; break;
3578 case NS_ooxml::LN_Value_ST_HighlightColor_magenta: nColor=0xff00ff; break;
3579 case NS_ooxml::LN_Value_ST_HighlightColor_red: nColor=0xff0000; break;
3580 case NS_ooxml::LN_Value_ST_HighlightColor_yellow: nColor=0xffff00; break;
3581 case NS_ooxml::LN_Value_ST_HighlightColor_white: nColor=0xffffff; break;
3582 case NS_ooxml::LN_Value_ST_HighlightColor_darkBlue: nColor=0x000080; break;
3583 case NS_ooxml::LN_Value_ST_HighlightColor_darkCyan: nColor=0x008080; break;
3584 case NS_ooxml::LN_Value_ST_HighlightColor_darkGreen: nColor=0x008000; break;
3585 case NS_ooxml::LN_Value_ST_HighlightColor_darkMagenta: nColor=0x800080; break;
3586 case NS_ooxml::LN_Value_ST_HighlightColor_darkRed: nColor=0x800000; break;
3587 case NS_ooxml::LN_Value_ST_HighlightColor_darkYellow: nColor=0x808000; break;
3588 case NS_ooxml::LN_Value_ST_HighlightColor_darkGray: nColor=0x808080; break;
3589 case NS_ooxml::LN_Value_ST_HighlightColor_lightGray: nColor=0xC0C0C0; break;
3590 default:
3591 return false;
3593 return true;
3596 sal_Int16 DomainMapper::getEmphasisValue(const sal_Int32 nIntValue)
3598 switch (nIntValue)
3600 case NS_ooxml::LN_Value_ST_Em_dot:
3601 return text::FontEmphasis::DOT_ABOVE;
3602 case NS_ooxml::LN_Value_ST_Em_comma:
3603 return text::FontEmphasis::ACCENT_ABOVE;
3604 case NS_ooxml::LN_Value_ST_Em_circle:
3605 return text::FontEmphasis::CIRCLE_ABOVE;
3606 case NS_ooxml::LN_Value_ST_Em_underDot:
3607 return text::FontEmphasis::DOT_BELOW;
3608 default:
3609 return text::FontEmphasis::NONE;
3613 OUString DomainMapper::getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix)
3615 switch(nIntValue)
3617 case NS_ooxml::LN_Value_ST_CombineBrackets_round:
3618 if (bIsPrefix)
3619 return OUString( "(" );
3620 return OUString( ")" );
3622 case NS_ooxml::LN_Value_ST_CombineBrackets_square:
3623 if (bIsPrefix)
3624 return OUString( "[" );
3625 return OUString( "]" );
3627 case NS_ooxml::LN_Value_ST_CombineBrackets_angle:
3628 if (bIsPrefix)
3629 return OUString( "<" );
3630 return OUString( ">" );
3632 case NS_ooxml::LN_Value_ST_CombineBrackets_curly:
3633 if (bIsPrefix)
3634 return OUString( "{" );
3635 return OUString( "}" );
3637 case NS_ooxml::LN_Value_ST_CombineBrackets_none:
3638 default:
3639 return OUString();
3643 style::TabAlign DomainMapper::getTabAlignFromValue(const sal_Int32 nIntValue)
3645 switch (nIntValue)
3647 case NS_ooxml::LN_Value_ST_TabJc_start:
3648 case NS_ooxml::LN_Value_ST_TabJc_left:
3649 case NS_ooxml::LN_Value_ST_TabJc_bar: // bar not supported
3650 case NS_ooxml::LN_Value_ST_TabJc_num: // num not supported
3651 return style::TabAlign_LEFT;
3652 case NS_ooxml::LN_Value_ST_TabJc_center:
3653 return style::TabAlign_CENTER;
3654 case NS_ooxml::LN_Value_ST_TabJc_end:
3655 case NS_ooxml::LN_Value_ST_TabJc_right:
3656 return style::TabAlign_RIGHT;
3657 case NS_ooxml::LN_Value_ST_TabJc_decimal:
3658 return style::TabAlign_DECIMAL;
3660 return style::TabAlign_LEFT;
3663 sal_Unicode DomainMapper::getFillCharFromValue(const sal_Int32 nIntValue)
3665 switch (nIntValue)
3667 case NS_ooxml::LN_Value_ST_TabTlc_dot:
3668 return u'.';
3669 case NS_ooxml::LN_Value_ST_TabTlc_hyphen:
3670 return u'-';
3671 case NS_ooxml::LN_Value_ST_TabTlc_underscore:
3672 case NS_ooxml::LN_Value_ST_TabTlc_heavy: // FIXME ???
3673 return u'_';
3674 case NS_ooxml::LN_Value_ST_TabTlc_middleDot: // middleDot
3675 return u'\x00b7';
3676 case NS_ooxml::LN_Value_ST_TabTlc_none:
3677 default:
3678 return u' '; // blank space
3682 bool DomainMapper::IsOOXMLImport() const
3684 return m_pImpl->IsOOXMLImport();
3687 bool DomainMapper::IsRTFImport() const
3689 return m_pImpl->IsRTFImport();
3692 uno::Reference < lang::XMultiServiceFactory > const & DomainMapper::GetTextFactory() const
3694 return m_pImpl->GetTextFactory();
3697 uno::Reference< text::XTextRange > DomainMapper::GetCurrentTextRange()
3699 return m_pImpl->GetTopTextAppend()->getEnd();
3702 OUString DomainMapper::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate )
3704 StyleSheetTablePtr pStyleSheets = m_pImpl->GetStyleSheetTable();
3705 return pStyleSheets->getOrCreateCharStyle( rCharProperties, bAlwaysCreate );
3708 StyleSheetTablePtr const & DomainMapper::GetStyleSheetTable( )
3710 return m_pImpl->GetStyleSheetTable( );
3713 GraphicZOrderHelper* DomainMapper::graphicZOrderHelper()
3715 if (zOrderHelper == nullptr)
3716 zOrderHelper.reset( new GraphicZOrderHelper );
3717 return zOrderHelper.get();
3720 GraphicNamingHelper& DomainMapper::GetGraphicNamingHelper()
3722 if (m_pGraphicNamingHelper == nullptr)
3723 m_pGraphicNamingHelper.reset(new GraphicNamingHelper());
3724 return *m_pGraphicNamingHelper;
3727 uno::Reference<drawing::XShape> DomainMapper::PopPendingShape()
3729 return m_pImpl->PopPendingShape();
3732 bool DomainMapper::IsInHeaderFooter() const
3734 return m_pImpl->IsInHeaderFooter();
3737 bool DomainMapper::IsInTable() const
3739 return m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell();
3742 bool DomainMapper::IsStyleSheetImport() const
3744 return m_pImpl->IsStyleSheetImport();
3747 void DomainMapper::enableInteropGrabBag(const OUString& aName)
3749 m_pImpl->m_aInteropGrabBagName = aName;
3752 beans::PropertyValue DomainMapper::getInteropGrabBag()
3754 beans::PropertyValue aRet;
3755 aRet.Name = m_pImpl->m_aInteropGrabBagName;
3756 aRet.Value <<= comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag);
3758 m_pImpl->m_aInteropGrabBag.clear();
3759 m_pImpl->m_aInteropGrabBagName.clear();
3760 return aRet;
3763 void DomainMapper::HandleRedline( Sprm& rSprm )
3765 sal_uInt32 nSprmId = rSprm.getId();
3767 m_pImpl->AddNewRedline( nSprmId );
3769 if (nSprmId == NS_ooxml::LN_CT_PPr_pPrChange)
3771 m_pImpl->SetCurrentRedlineToken(XML_ParagraphFormat);
3773 else if (nSprmId == NS_ooxml::LN_CT_TrPr_ins)
3775 m_pImpl->SetCurrentRedlineToken(XML_tableRowInsert);
3777 else if (nSprmId == NS_ooxml::LN_CT_TrPr_del)
3779 m_pImpl->SetCurrentRedlineToken(XML_tableRowDelete);
3781 else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellIns)
3783 m_pImpl->SetCurrentRedlineToken(XML_tableCellInsert);
3785 else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellDel)
3787 m_pImpl->SetCurrentRedlineToken(XML_tableCellDelete);
3790 resolveSprmProps(*this, rSprm );
3791 // now the properties author, date and id should be available
3792 sal_Int32 nToken = m_pImpl->GetCurrentRedlineToken();
3793 switch( nToken & 0xffff )
3795 case XML_mod:
3796 case XML_ins:
3797 case XML_del:
3798 case XML_moveTo:
3799 case XML_moveFrom:
3800 case XML_ParagraphFormat:
3801 case XML_tableRowInsert:
3802 case XML_tableRowDelete:
3803 case XML_tableCellInsert:
3804 case XML_tableCellDelete:
3805 break;
3806 default: OSL_FAIL( "redline token other than mod, ins, del, moveTo, moveFrom or table row" ); break;
3808 m_pImpl->EndParaMarkerChange( );
3809 m_pImpl->SetCurrentRedlineIsRead();
3812 void DomainMapper::finishParagraph(const bool bRemove)
3814 if (m_pImpl->m_pSdtHelper->validateDateFormat())
3815 m_pImpl->m_pSdtHelper->createDateContentControl();
3816 m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), bRemove);
3819 } //namespace dmapper
3820 } //namespace writerfilter
3822 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */