LibreOffice Module writerfilter (master) 1
DomainMapper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#include "BorderHandler.hxx"
21
22#include "util.hxx"
23#include "SdtHelper.hxx"
24#include "TagLogger.hxx"
25#include "TDefTableHandler.hxx"
26#include "DomainMapper_Impl.hxx"
27#include "ConversionHelper.hxx"
29#include "MeasureHandler.hxx"
31#include <i18nutil/paper.hxx>
32#include <ooxml/resourceids.hxx>
33#include <oox/token/tokens.hxx>
35#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
36#include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp>
37#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
38#include <com/sun/star/table/BorderLineStyle.hpp>
39#include <com/sun/star/table/ShadowFormat.hpp>
40#include <com/sun/star/text/HoriOrientation.hpp>
41#include <com/sun/star/text/RelOrientation.hpp>
42#include <com/sun/star/text/VertOrientation.hpp>
43#include <com/sun/star/text/WrapTextMode.hpp>
44#include <com/sun/star/text/SizeType.hpp>
45#include <com/sun/star/text/XEndnotesSupplier.hpp>
46#include <com/sun/star/text/XFootnotesSupplier.hpp>
47#include <com/sun/star/text/XLineNumberingProperties.hpp>
48#include <com/sun/star/awt/FontRelief.hpp>
49#include <com/sun/star/awt/FontWeight.hpp>
50#include <com/sun/star/awt/FontUnderline.hpp>
51#include <com/sun/star/awt/FontStrikeout.hpp>
52#include <com/sun/star/awt/FontSlant.hpp>
53#include <com/sun/star/document/XEventBroadcaster.hpp>
54#include <com/sun/star/style/ParagraphAdjust.hpp>
55#include <com/sun/star/style/BreakType.hpp>
56#include <com/sun/star/style/CaseMap.hpp>
57#include <com/sun/star/style/LineSpacing.hpp>
58#include <com/sun/star/style/LineSpacingMode.hpp>
59#include <com/sun/star/text/FootnoteNumbering.hpp>
60#include <com/sun/star/text/TextGridMode.hpp>
61#include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
62#include <com/sun/star/text/XTextFieldsSupplier.hpp>
63#include <com/sun/star/text/WritingMode.hpp>
64#include <com/sun/star/text/WritingMode2.hpp>
65#include <com/sun/star/text/XFootnote.hpp>
66#include <com/sun/star/text/XTextColumns.hpp>
67#include <com/sun/star/text/RubyPosition.hpp>
68#include <com/sun/star/uno/XComponentContext.hpp>
69#include <com/sun/star/text/FontEmphasis.hpp>
70#include <com/sun/star/awt/CharSet.hpp>
71#include <com/sun/star/lang/XMultiServiceFactory.hpp>
72#include <com/sun/star/util/XComplexColor.hpp>
73#include <comphelper/types.hxx>
81
83#include "ThemeColorHandler.hxx"
84#include "CellColorHandler.hxx"
86#include "GraphicHelpers.hxx"
89#include <sal/log.hxx>
91
92using namespace ::com::sun::star;
93using namespace oox;
94
95namespace writerfilter::dmapper{
96
97struct
98{
99 sal_Int32 h;
100 bool orient;
101 sal_Int32 w;
103
104
106 uno::Reference<io::XInputStream> const& xInputStream,
108 bool bRepairStorage,
109 SourceDocumentType eDocumentType,
110 utl::MediaDescriptor const & rMediaDesc) :
111 LoggedProperties("DomainMapper"),
112 LoggedTable("DomainMapper"),
113 LoggedStream("DomainMapper"),
114 m_pImpl(new DomainMapper_Impl(*this, xContext, xModel, eDocumentType, rMediaDesc)),
115 mbIsSplitPara(false),
116 mbHasControls(false),
117 mbWasShapeInPara(false)
118{
119 if (m_pImpl->IsNewDoc())
120 {
121 // #i24363# tab stops relative to indent
122 m_pImpl->SetDocumentSettingsProperty(
124 uno::Any(false));
125 m_pImpl->SetDocumentSettingsProperty(
127 uno::Any(true));
128 m_pImpl->SetDocumentSettingsProperty(
130 uno::Any(true));
131
132 // Don't load the default style definitions to avoid weird mix
133 m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::Any(true));
134 m_pImpl->SetDocumentSettingsProperty("MsWordCompTrailingBlanks", uno::Any(true));
135 m_pImpl->SetDocumentSettingsProperty("HeaderSpacingBelowLastPara",
136 uno::Any(true));
137 m_pImpl->SetDocumentSettingsProperty("FrameAutowidthWithMorePara", uno::Any(true));
138 m_pImpl->SetDocumentSettingsProperty("FootnoteInColumnToPageEnd", uno::Any(true));
139 m_pImpl->SetDocumentSettingsProperty("TabAtLeftIndentForParagraphsInList", uno::Any(true));
140
141 // Enable only for new documents, since pasting from clipboard can influence existing doc
142 m_pImpl->SetDocumentSettingsProperty("NoNumberingShowFollowBy", uno::Any(true));
143 }
144
145 // Initialize RDF metadata, to be able to add statements during the import.
146 try
147 {
148 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY_THROW);
150 OUString aBaseURL = rMediaDesc.getUnpackedValueOrDefault("URL", OUString());
152 uno::UNO_QUERY_THROW);
153 const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xContext, xModel_, aBaseURL, u""));
155 xDocumentMetadataAccess->loadMetadataFromStorage(xStorage, xBaseURI, xHandler);
156 }
157 catch (const uno::Exception&)
158 {
159 DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize RDF metadata");
160 }
161
162 if (eDocumentType == SourceDocumentType::OOXML) {
163 // tdf#108350
164 // In Word since version 2007, the default document font is Calibri 11 pt.
165 // If a DOCX document doesn't contain font information, we should assume
166 // the intended font to provide best layout match.
167 try
168 {
169 uno::Reference< beans::XPropertySet > xDefProps(GetTextFactory()->createInstance("com.sun.star.text.Defaults"),
170 uno::UNO_QUERY_THROW);
171 xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), css::uno::Any(OUString("Calibri")));
172 xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), css::uno::Any(double(11)));
173 }
174 catch (const uno::Exception&)
175 {
176 DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize default font");
177 }
178 }
179
180 //import document properties
181 try
182 {
184 OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xContext, bRepairStorage);
185
186 uno::Reference< uno::XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext(
187 "com.sun.star.document.OOXMLDocumentPropertiesImporter",
188 xContext);
189
190 uno::Reference< document::XOOXMLDocumentPropertiesImporter > xImporter( xTemp, uno::UNO_QUERY_THROW );
191 uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier( xModel, uno::UNO_QUERY_THROW);
192 xImporter->importProperties(m_pImpl->m_xDocumentStorage,
193 xPropSupplier->getDocumentProperties());
194 }
195 catch( const uno::Exception& ) {}
196}
197
199{
200 m_pImpl->setDocumentReference(pDocument);
201}
202
204{
205 try
206 {
207 // Remove temporary footnotes and endnotes
208 m_pImpl->RemoveTemporaryFootOrEndnotes();
209
210 uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
211 sal_Int32 nIndexes = 0;
212 if( xIndexesSupplier.is() )
213 {
214 uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes();
215 nIndexes = xIndexes->getCount();
216 }
217 // If we have page references, those need updating as well, similar to the indexes.
218 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
219 if(xTextFieldsSupplier.is())
220 {
221 uno::Reference<container::XEnumeration> xEnumeration = xTextFieldsSupplier->getTextFields()->createEnumeration();
222 while(xEnumeration->hasMoreElements())
223 {
224 ++nIndexes;
225 xEnumeration->nextElement();
226 }
227 }
228
229 mbHasControls |= m_pImpl->m_pSdtHelper->hasElements();
230 if ( nIndexes || mbHasControls )
231 {
232 //index update has to wait until first view is created
233 uno::Reference< document::XEventBroadcaster > xBroadcaster(xIndexesSupplier, uno::UNO_QUERY);
234 if (xBroadcaster.is())
235 xBroadcaster->addEventListener(uno::Reference< document::XEventListener >(new ModelEventListener(nIndexes, mbHasControls)));
236 }
237
238
239 // Apply the document settings for both DOCX and RTF after everything else
240 m_pImpl->GetSettingsTable()->ApplyProperties( m_pImpl->GetTextDocument( ) );
241
242 // now that importing is finished, re-enable default styles for any that were never defined/imported.
243 m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::Any(false));
244
245 // Grab-bag handling
247
248 // Add the saved w:themeFontLang setting
249 aProperties["ThemeFontLangProps"] <<= m_pImpl->GetSettingsTable()->GetThemeFontLangProperties();
250
251 // Add the saved compat settings
252 aProperties["CompatSettings"] <<= m_pImpl->GetSettingsTable()->GetCompatSettings();
253
254 // Add the saved DocumentProtection settings
255 aProperties["DocumentProtection"] <<= m_pImpl->GetSettingsTable()->GetDocumentProtectionSettings();
256
257 // Add the saved w:doNotHyphenateCaps setting
258 aProperties["NoHyphenateCaps"] <<= m_pImpl->GetSettingsTable()->GetNoHyphenateCaps();
259
260 uno::Reference<beans::XPropertySet> xDocProps(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
261 if (xDocProps.is())
262 {
263 comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue("InteropGrabBag"));
264 aGrabBag.update(aProperties);
265 xDocProps->setPropertyValue("InteropGrabBag", uno::Any(aGrabBag.getAsConstPropertyValueList()));
266 }
267
268 // tdf#138782: for docs created in MS Word 2010 and older (compatibilityMode <= 14)
269 m_pImpl->SetDocumentSettingsProperty(
270 "AddFrameOffsets",
271 uno::Any(14 >= m_pImpl->GetSettingsTable()->GetWordCompatibilityMode()));
272 }
273 catch( const uno::Exception& ) {}
274
275#ifdef DBG_UTIL
277#endif
278}
279
281{
282 if (m_pImpl->hasTableManager() && m_pImpl->getTableManager().attribute(nName, val))
283 return;
284
285 static const int nSingleLineSpacing = 240;
286 sal_Int32 nIntValue = val.getInt();
287 OUString sStringValue = val.getString();
288
289 SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
290 switch( nName )
291 {
292 case NS_ooxml::LN_CT_Lvl_start:
293 break;
294 case NS_ooxml::LN_CT_Lvl_numFmt:
295 break;
296 case NS_ooxml::LN_CT_Lvl_isLgl:
297 break;
298 case NS_ooxml::LN_CT_Lvl_legacy:
299 break;
300 case NS_ooxml::LN_CT_AbstractNum_nsid:
301 break;
302 case NS_ooxml::LN_CT_AbstractNum_tmpl:
303 break;
304 case NS_ooxml::LN_CT_Border_sz:
305 break;
306 case NS_ooxml::LN_CT_Border_val:
307 break;
308 case NS_ooxml::LN_CT_Border_space:
309 break;
310 case NS_ooxml::LN_CT_Border_shadow:
311 break;
312 case NS_ooxml::LN_CT_Border_frame:
313 break;
314 case NS_ooxml::LN_headerr:
315 break;
316 case NS_ooxml::LN_footerr:
317 break;
318 case NS_ooxml::LN_endnote:
319 break;
320 case NS_ooxml::LN_CT_Bookmark_name:
321 m_pImpl->SetBookmarkName( sStringValue );
322 break;
323 case NS_ooxml::LN_CT_MarkupRangeBookmark_id:
324 // add a bookmark range -- this remembers a bookmark starting here
325 // or, if the bookmark was already started or, if the bookmark was
326 // already started before, writes out the bookmark
327 m_pImpl->StartOrEndBookmark( sStringValue );
328 break;
329 case NS_ooxml::LN_CT_MarkupRange_displacedByCustomXml:
330 break;
331 case NS_ooxml::LN_NUMBERING:
332 break;
333 case NS_ooxml::LN_FONTTABLE:
334 break;
335 case NS_ooxml::LN_STYLESHEET:
336 break;
337
338 case NS_ooxml::LN_CT_Sym_char:
339 m_pImpl->SetSymbolChar(nIntValue);
340 break;
341 case NS_ooxml::LN_CT_Sym_font:
342 m_pImpl->SetSymbolFont(sStringValue);
343 break;
344 case NS_ooxml::LN_CT_Underline_val:
345 if (m_pImpl->GetTopContext())
346 handleUnderlineType(nIntValue, m_pImpl->GetTopContext());
347 break;
348 case NS_ooxml::LN_CT_Underline_color:
349 if (m_pImpl->GetTopContext())
350 {
351 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_HAS_COLOR, uno::Any( true ) );
352 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COLOR, uno::Any( nIntValue ) );
353 }
354 break;
355 case NS_ooxml::LN_CT_Underline_themeColor:
356 case NS_ooxml::LN_CT_Underline_themeTint:
357 case NS_ooxml::LN_CT_Underline_themeShade:
358 if (m_pImpl->GetTopContext())
359 {
361 model::ComplexColor aComplexColor;
362
363 PropertyMapPtr pTopContext = m_pImpl->GetTopContext();
364 std::optional<PropertyMap::Property> aValue;
365 if (pTopContext && (aValue = pTopContext->getProperty(PROP_CHAR_UNDERLINE_COMPLEX_COLOR)))
366 {
367 aValue->second >>= xComplexColor;
368 if (xComplexColor.is())
369 aComplexColor = model::color::getFromXComplexColor(xComplexColor);
370 }
371
372 if (nName == NS_ooxml::LN_CT_Underline_themeColor)
373 {
374 auto eThemeColorType = TDefTableHandler::getThemeColorTypeIndex(nIntValue);
375 aComplexColor.setSchemeColor(eThemeColorType);
376 }
377 else if (nName == NS_ooxml::LN_CT_Underline_themeTint)
378 {
379 if (nIntValue > 0)
380 {
381 sal_Int16 nTransformedValue = sal_Int16((255.0 - nIntValue) * 10000.0 / 255.0);
382 aComplexColor.addTransformation({model::TransformationType::Tint, sal_Int16(nTransformedValue)});
383 }
384 }
385 else if (nName == NS_ooxml::LN_CT_Underline_themeShade)
386 {
387 if (nIntValue > 0)
388 {
389 sal_Int16 nTransformedValue = sal_Int16((255.0 - nIntValue) * 10000.0 / 255.0);
390 aComplexColor.addTransformation({model::TransformationType::Shade, sal_Int16(nTransformedValue)});
391 }
392 }
393 xComplexColor = model::color::createXComplexColor(aComplexColor);
394 m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COMPLEX_COLOR, uno::Any(xComplexColor));
395 }
396 break;
397
398 case NS_ooxml::LN_CT_TabStop_val:
399 if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_TabJc_clear)
400 {
401 m_pImpl->m_aCurrentTabStop.bDeleted = true;
402 }
403 else
404 {
405 m_pImpl->m_aCurrentTabStop.bDeleted = false;
406 m_pImpl->m_aCurrentTabStop.Alignment = getTabAlignFromValue(nIntValue);
407 }
408 break;
409 case NS_ooxml::LN_CT_TabStop_leader:
410 m_pImpl->m_aCurrentTabStop.FillChar = getFillCharFromValue(nIntValue);
411 break;
412 case NS_ooxml::LN_CT_TabStop_pos:
413 m_pImpl->m_aCurrentTabStop.Position = ConversionHelper::convertTwipToMM100(nIntValue);
414 break;
415
416 case NS_ooxml::LN_CT_Fonts_ascii:
417 if (m_pImpl->GetTopContext())
418 {
419 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, uno::Any( sStringValue ));
420 }
421 break;
422 case NS_ooxml::LN_CT_Fonts_asciiTheme:
423 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeHandler::getStringForTheme(nIntValue));
424 if (m_pImpl->GetTopContext())
425 {
426 // note: overwrite Fonts_ascii with Fonts_asciiTheme *even if*
427 // theme font is empty - this is apparently what Word 2013 does
428 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
429 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, aPropValue );
430 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_ASCII, aPropValue, true, CHAR_GRAB_BAG );
431 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_ASCII, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
432 }
433 break;
434 case NS_ooxml::LN_CT_Fonts_hAnsi:
435 break;//unsupported
436 case NS_ooxml::LN_CT_Fonts_hAnsiTheme:
437 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeHandler::getStringForTheme(nIntValue));
438 if (m_pImpl->GetTopContext())
439 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_H_ANSI, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
440 break;
441 case NS_ooxml::LN_CT_Fonts_eastAsia:
442 if (m_pImpl->GetTopContext())
443 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::Any( sStringValue ));
444 break;
445 case NS_ooxml::LN_CT_Fonts_eastAsiaTheme:
446 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsiaTheme", ThemeHandler::getStringForTheme(nIntValue));
447 if (m_pImpl->GetTopContext())
448 {
449 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
450 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, aPropValue );
451 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_EAST_ASIA, aPropValue, true, CHAR_GRAB_BAG );
453 }
454 break;
455 case NS_ooxml::LN_CT_Fonts_cs:
456 if (m_pImpl->GetTopContext())
457 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::Any( sStringValue ));
458 break;
459 case NS_ooxml::LN_CT_Fonts_cstheme:
460 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "cstheme", ThemeHandler::getStringForTheme(nIntValue));
461 if (m_pImpl->GetTopContext())
462 {
463 uno::Any aPropValue( m_pImpl->getFontNameForTheme( nIntValue ) );
464 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aPropValue );
465 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_CS, aPropValue, true, CHAR_GRAB_BAG );
466 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_CS, uno::Any( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG);
467 }
468 break;
469 case NS_ooxml::LN_CT_Spacing_before:
470 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "before", OUString::number(nIntValue));
471 if (m_pImpl->GetTopContext())
472 // Don't overwrite NS_ooxml::LN_CT_Spacing_beforeAutospacing.
473 m_pImpl->GetTopContext()->Insert(
475 uno::Any(static_cast<sal_Int32>(convertTwipToMm100(nIntValue))), false);
476 break;
477 case NS_ooxml::LN_CT_Spacing_beforeLines:
478 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "beforeLines", OUString::number(nIntValue));
479 // We would need to make sure that this doesn't overwrite any
480 // NS_ooxml::LN_CT_Spacing_before in parent styles before style
481 // sheet support can be enabled.
482 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
483 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
484 break;
485 case NS_ooxml::LN_CT_Spacing_after:
486 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "after", OUString::number(nIntValue));
487 if (m_pImpl->GetTopContext())
488 {
489 // Don't overwrite NS_ooxml::LN_CT_Spacing_afterAutospacing.
490 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
491
492 uno::Any aContextualSpacingFromStyle = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_CONTEXT_MARGIN);
493 if (aContextualSpacingFromStyle.hasValue())
494 // Setting "after" spacing means Writer doesn't inherit
495 // contextual spacing anymore from style, but Word does.
496 m_pImpl->GetTopContext()->Insert(PROP_PARA_CONTEXT_MARGIN, aContextualSpacingFromStyle);
497 }
498 break;
499 case NS_ooxml::LN_CT_Spacing_afterLines:
500 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "afterLines", OUString::number(nIntValue));
501 // We would need to make sure that this doesn't overwrite any
502 // NS_ooxml::LN_CT_Spacing_after in parent styles before style
503 // sheet support can be enabled.
504 if (m_pImpl->GetTopContext() && !IsStyleSheetImport())
505 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false);
506 break;
507 case NS_ooxml::LN_CT_Spacing_line: //91434
508 case NS_ooxml::LN_CT_Spacing_lineRule: //91435
509 {
510 style::LineSpacing aSpacing;
511 PropertyMapPtr pTopContext = m_pImpl->GetTopContext();
512 std::optional<PropertyMap::Property> aLineSpacingVal;
513 if (pTopContext && (aLineSpacingVal = pTopContext->getProperty(PROP_PARA_LINE_SPACING)) )
514 {
515 aLineSpacingVal->second >>= aSpacing;
516 }
517 else
518 {
519 //default to single line spacing
520 aSpacing.Mode = style::LineSpacingMode::FIX;
521 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
522 }
523 if( nName == NS_ooxml::LN_CT_Spacing_line )
524 {
525 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "line", OUString::number(nIntValue));
526 //now set the value depending on the Mode
527 if( aSpacing.Mode == style::LineSpacingMode::PROP )
528 aSpacing.Height = sal_Int16(nIntValue * 100 / nSingleLineSpacing );
529 else
530 aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nIntValue ));
531 }
532 else //NS_ooxml::LN_CT_Spacing_lineRule:
533 {
534 // exactly, atLeast, auto
535 if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_auto)
536 {
537 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "auto");
538 if (aSpacing.Height >= 0)
539 {
540 aSpacing.Mode = style::LineSpacingMode::PROP;
541 //reinterpret the already set value
542 aSpacing.Height = sal_Int16( aSpacing.Height * 100 / ConversionHelper::convertTwipToMM100( nSingleLineSpacing ));
543 }
544 else
545 {
546 // Negative value still means a positive height,
547 // just the mode is "exact".
548 aSpacing.Mode = style::LineSpacingMode::FIX;
549 aSpacing.Height *= -1;
550 }
551 }
552 else if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast)
553 {
554 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "atLeast");
555 aSpacing.Mode = style::LineSpacingMode::MINIMUM;
556 }
557 else // NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact
558 {
559 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "exact");
560 aSpacing.Mode = style::LineSpacingMode::FIX;
561 }
562 }
563 if (pTopContext)
564 pTopContext->Insert(PROP_PARA_LINE_SPACING, uno::Any( aSpacing ));
565 }
566 break;
567 case NS_ooxml::LN_CT_Ind_start:
568 case NS_ooxml::LN_CT_Ind_left:
569 if (m_pImpl->GetTopContext())
570 {
571 // Word inherits FirstLineIndent property of the numbering, even if ParaLeftMargin is set, Writer does not.
572 // So copy it explicitly, if necessary.
573 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
574 sal_Int32 nIndentAt = m_pImpl->getCurrentNumberingProperty("IndentAt");
575
576 sal_Int32 nParaLeftMargin = ConversionHelper::convertTwipToMM100(nIntValue);
577 if (nParaLeftMargin != 0 && nIndentAt == nParaLeftMargin)
578 // Avoid direct left margin when it's the same as from the
579 // numbering.
580 break;
581
582 if (nFirstLineIndent != 0)
583 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::Any(nFirstLineIndent), /*bOverwrite=*/false);
584
585 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN,
586 uno::Any(nParaLeftMargin));
587 }
588 break;
589 case NS_ooxml::LN_CT_Ind_end:
590 case NS_ooxml::LN_CT_Ind_right:
591 if (m_pImpl->GetTopContext())
592 {
593 // Word inherits FirstLineIndent/ParaLeftMargin property of the numbering, even if ParaRightMargin is set, Writer does not.
594 // So copy it explicitly, if necessary.
595 sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
596 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
597
598 if (nFirstLineIndent != 0)
599 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::Any(nFirstLineIndent), /*bOverwrite=*/false);
600 if (nParaLeftMargin != 0)
601 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::Any(nParaLeftMargin), /*bOverwrite=*/false);
602
603 m_pImpl->GetTopContext()->Insert(
605 }
606 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "right", OUString::number(nIntValue));
607 break;
608 case NS_ooxml::LN_CT_Ind_hanging:
609 if (m_pImpl->GetTopContext())
610 {
611 sal_Int32 nValue = ConversionHelper::convertTwipToMM100( nIntValue );
612 m_pImpl->GetTopContext()->Insert(
614
615 // See above, need to inherit left margin from list style when first is set.
616 sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt");
617 if (nParaLeftMargin != 0)
618 m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::Any(nParaLeftMargin), /*bOverwrite=*/false);
619 }
620 break;
621 case NS_ooxml::LN_CT_Ind_firstLine:
622 if (m_pImpl->GetTopContext())
623 {
624 sal_Int32 nFirstLineIndent
625 = m_pImpl->getCurrentNumberingProperty("FirstLineIndent");
626 sal_Int32 nParaFirstLineIndent = ConversionHelper::convertTwipToMM100(nIntValue);
627 if (nParaFirstLineIndent != 0 && nFirstLineIndent == nParaFirstLineIndent)
628 // Avoid direct first margin when it's the same as from the
629 // numbering.
630 break;
631 m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT,
632 uno::Any(nParaFirstLineIndent));
633 }
634 break;
635 case NS_ooxml::LN_CT_Ind_rightChars:
636 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "rightChars", OUString::number(nIntValue));
637 break;
638
639 case NS_ooxml::LN_CT_EastAsianLayout_id:
640 break;
641 case NS_ooxml::LN_CT_EastAsianLayout_combine:
642 if (m_pImpl->GetTopContext())
643 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_IS_ON, uno::Any ( nIntValue != 0 ));
644 break;
645 case NS_ooxml::LN_CT_EastAsianLayout_combineBrackets:
646 if (m_pImpl->GetTopContext())
647 {
648 OUString sCombinePrefix = getBracketStringFromEnum(nIntValue);
649 OUString sCombineSuffix = getBracketStringFromEnum(nIntValue, false);
650 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_PREFIX, uno::Any ( sCombinePrefix ));
651 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_SUFFIX, uno::Any ( sCombineSuffix ));
652 }
653 break;
654 case NS_ooxml::LN_CT_EastAsianLayout_vert:
655 if (m_pImpl->GetTopContext())
656 {
657 sal_Int16 nRotationAngle = (nIntValue ? 900 : 0);
658 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION, uno::Any ( nRotationAngle ));
659 }
660 break;
661 case NS_ooxml::LN_CT_EastAsianLayout_vertCompress:
662 if (m_pImpl->GetTopContext())
663 m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION_IS_FIT_TO_LINE, uno::Any ( nIntValue != 0 ));
664 break;
665
666 case NS_ooxml::LN_CT_PageSz_code:
667 break;
668 case NS_ooxml::LN_CT_PageSz_h:
669 {
670 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100WithoutLimit(nIntValue);
672 }
673 break;
674 case NS_ooxml::LN_CT_PageSz_orient:
675 CT_PageSz.orient = (nIntValue != NS_ooxml::LN_Value_ST_PageOrientation_portrait);
676 break;
677 case NS_ooxml::LN_CT_PageSz_w:
678 {
679 sal_Int32 nWidth = ConversionHelper::convertTwipToMM100WithoutLimit(nIntValue);
681 }
682 break;
683
684 case NS_ooxml::LN_CT_PageMar_top:
685 m_pImpl->SetPageMarginTwip( PAGE_MAR_TOP, nIntValue );
686 break;
687 case NS_ooxml::LN_CT_PageMar_right:
688 m_pImpl->SetPageMarginTwip( PAGE_MAR_RIGHT, nIntValue );
689 break;
690 case NS_ooxml::LN_CT_PageMar_bottom:
691 m_pImpl->SetPageMarginTwip( PAGE_MAR_BOTTOM, nIntValue );
692 break;
693 case NS_ooxml::LN_CT_PageMar_left:
694 m_pImpl->SetPageMarginTwip( PAGE_MAR_LEFT, nIntValue );
695 break;
696 case NS_ooxml::LN_CT_PageMar_header:
697 m_pImpl->SetPageMarginTwip( PAGE_MAR_HEADER, nIntValue );
698 break;
699 case NS_ooxml::LN_CT_PageMar_footer:
700 m_pImpl->SetPageMarginTwip( PAGE_MAR_FOOTER, nIntValue );
701 break;
702 case NS_ooxml::LN_CT_PageMar_gutter:
703 m_pImpl->SetPageMarginTwip( PAGE_MAR_GUTTER, nIntValue );
704 break;
705 case NS_ooxml::LN_CT_Language_val: //90314
706 case NS_ooxml::LN_CT_Language_eastAsia: //90315
707 case NS_ooxml::LN_CT_Language_bidi: //90316
708 {
709 // store decimal symbol associated to the language of the document
710 if ( m_pImpl->IsDocDefaultsImport() && ( nName == NS_ooxml::LN_CT_Language_val ) )
711 {
712 LanguageTag aLanguageTag( sStringValue );
713 LocaleDataWrapper aLocaleWrapper( std::move(aLanguageTag) );
714 if ( aLocaleWrapper.getNumDecimalSep() == "," )
715 m_pImpl->SetIsDecimalComma();
716
717 }
718 if (nName == NS_ooxml::LN_CT_Language_eastAsia)
719 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsia", sStringValue);
720 else if (nName == NS_ooxml::LN_CT_Language_val)
721 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", sStringValue);
722 else if (nName == NS_ooxml::LN_CT_Language_bidi)
723 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "bidi", sStringValue);
724 lang::Locale aLocale;
725 if (sStringValue.getLength() <= 3 && sStringValue.getLength() >= 1)
726 {
727 // Cheesy Google Docs is known to tag language-only even for
728 // "en" or others that need some region to distinguish language
729 // variants for spell-checker and hyphenation. Obtain our known
730 // fallback to clarify and match. The original value/context is
731 // unknown anyway.
732 LanguageTag aLanguageTag( sStringValue);
733 aLanguageTag.makeFallback();
734 if (aLanguageTag.getLanguage() == sStringValue)
735 aLocale = aLanguageTag.getLocale();
736 else
737 {
738 // Do not fallback for an unknown language, which usually
739 // results in "en-US", or any other non-matching case.
740 aLocale = LanguageTag::convertToLocale( sStringValue);
741 }
742 }
743 else
744 {
745 aLocale = LanguageTag::convertToLocale( sStringValue);
746 }
747 if (m_pImpl->GetTopContext())
748 m_pImpl->GetTopContext()->Insert(NS_ooxml::LN_CT_Language_val== nName ? PROP_CHAR_LOCALE :
749 NS_ooxml::LN_CT_Language_eastAsia == nName ? PROP_CHAR_LOCALE_ASIAN : PROP_CHAR_LOCALE_COMPLEX,
750 uno::Any( aLocale ) );
751 }
752 break;
753 // See SwWW8ImplReader::GetParagraphAutoSpace() on why these are 100 and 280
754 case NS_ooxml::LN_CT_Spacing_beforeAutospacing:
755 {
756 sal_Int32 default_spacing = -1;
757 if (nIntValue)
758 {
759 m_pImpl->SetParaAutoBefore(true);
760
761 default_spacing = 100;
762 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
763 {
764 // 49 is just the old value that should be removed, once the
765 // root cause in SwTabFrm::MakeAll() is fixed.
766 if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
767 default_spacing = 49;
768 else
769 default_spacing = 280;
770 }
771 // required at export (here mainly for StyleSheets) to determine if the setting has changed from grab_bag
772 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(default_spacing)));
773 }
775 }
776 break;
777 case NS_ooxml::LN_CT_Spacing_afterAutospacing:
778 {
779 sal_Int32 default_spacing = -1;
780 if (nIntValue)
781 {
782 default_spacing = 100;
783 if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
784 {
785 if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web)
786 default_spacing = 49;
787 else
788 default_spacing = 280;
789 }
790 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::Any(ConversionHelper::convertTwipToMM100(default_spacing)));
791 }
793 }
794 break;
795 case NS_ooxml::LN_CT_SmartTagRun_uri:
796 m_pImpl->getSmartTagHandler().setURI(val.getString());
797 break;
798 case NS_ooxml::LN_CT_SmartTagRun_element:
799 m_pImpl->getSmartTagHandler().setElement(val.getString());
800 break;
801 case NS_ooxml::LN_CT_Br_type:
802 // Handled in the OOXMLBreakHandler dtor.
803 break;
804 case NS_ooxml::LN_CT_Br_clear:
805 m_pImpl->HandleLineBreakClear(val.getInt());
806 break;
807 case NS_ooxml::LN_CT_Fonts_hint :
808 /* assigns script type to ambiguous characters, values can be:
809 NS_ooxml::LN_Value_ST_Hint_default
810 NS_ooxml::LN_Value_ST_Hint_eastAsia
811 NS_ooxml::LN_Value_ST_Hint_cs
812 */
813 //TODO: unsupported?
814 break;
815 case NS_ooxml::LN_CT_TblBorders_right:
816 case NS_ooxml::LN_CT_TblBorders_top:
817 case NS_ooxml::LN_CT_TblBorders_left:
818 case NS_ooxml::LN_CT_TblBorders_bottom:
819 //todo: handle cell mar
820 break;
821 case NS_ooxml::LN_blip: // contains the binary graphic
822 case NS_ooxml::LN_shape:
823 {
824 //looks a bit like a hack - and it is. The graphic import is split into the inline_inline part and
825 //afterwards the adding of the binary data.
826 m_pImpl->m_eGraphicImportType = IMPORT_AS_DETECTED_INLINE; // really ???
827 m_pImpl->GetGraphicImport()->attribute(nName, val);
828 m_pImpl->ImportGraphic(val.getProperties());
829 }
830 break;
831 case NS_ooxml::LN_Value_math_ST_Jc_centerGroup:
832 case NS_ooxml::LN_Value_math_ST_Jc_center:
833 m_pImpl->appendStarMath(val);
834 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_CENTER));
835 break;
836 case NS_ooxml::LN_Value_math_ST_Jc_left:
837 m_pImpl->appendStarMath(val);
838 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_LEFT));
839 break;
840 case NS_ooxml::LN_Value_math_ST_Jc_right:
841 m_pImpl->appendStarMath(val);
842 m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_RIGHT));
843 break;
844 case NS_ooxml::LN_starmath:
845 m_pImpl->appendStarMath(val);
846 break;
847 case NS_ooxml::LN_CT_FramePr_dropCap:
848 case NS_ooxml::LN_CT_FramePr_lines:
849 case NS_ooxml::LN_CT_FramePr_hAnchor:
850 case NS_ooxml::LN_CT_FramePr_vAnchor:
851 case NS_ooxml::LN_CT_FramePr_x:
852 case NS_ooxml::LN_CT_FramePr_xAlign:
853 case NS_ooxml::LN_CT_FramePr_y:
854 case NS_ooxml::LN_CT_FramePr_yAlign:
855 case NS_ooxml::LN_CT_FramePr_hRule:
856 case NS_ooxml::LN_CT_FramePr_w:
857 case NS_ooxml::LN_CT_FramePr_h:
858 case NS_ooxml::LN_CT_FramePr_wrap:
859 case NS_ooxml::LN_CT_FramePr_hSpace:
860 case NS_ooxml::LN_CT_FramePr_vSpace:
861 {
862 ParagraphPropertiesPropertyMap* pParaProperties = nullptr;
863 // handle frame properties at styles
864 if( m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET )
865 pParaProperties = dynamic_cast< ParagraphPropertiesPropertyMap*>( m_pImpl->GetTopContextOfType( CONTEXT_STYLESHEET ).get() );
866 else
867 pParaProperties = dynamic_cast< ParagraphPropertiesPropertyMap*>( m_pImpl->GetTopContextOfType( CONTEXT_PARAGRAPH ).get() );
868
869 if( pParaProperties )
870 {
871 switch( nName )
872 {
873 case NS_ooxml::LN_CT_FramePr_dropCap:
874 pParaProperties->props().SetDropCap( nIntValue );
875 break;
876 case NS_ooxml::LN_CT_FramePr_lines:
877 pParaProperties->props().SetLines( nIntValue );
878 break;
879 case NS_ooxml::LN_CT_FramePr_hAnchor:
880 switch(nIntValue)
881 {
882 case NS_ooxml::LN_Value_doc_ST_HAnchor_text: //relative to column
883 nIntValue = text::RelOrientation::FRAME; break;
884 case NS_ooxml::LN_Value_doc_ST_HAnchor_margin: nIntValue = text::RelOrientation::PAGE_PRINT_AREA; break;
885 case NS_ooxml::LN_Value_doc_ST_HAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
886 default:;
887 }
888 pParaProperties->props().SethAnchor( nIntValue );
889 break;
890 case NS_ooxml::LN_CT_FramePr_vAnchor:
891 switch(nIntValue)
892 {
893 case NS_ooxml::LN_Value_doc_ST_VAnchor_text: //relative to paragraph
894 nIntValue = text::RelOrientation::FRAME; break;
895 case NS_ooxml::LN_Value_doc_ST_VAnchor_margin:nIntValue = text::RelOrientation::PAGE_PRINT_AREA ; break;
896 case NS_ooxml::LN_Value_doc_ST_VAnchor_page: nIntValue = text::RelOrientation::PAGE_FRAME; break;
897 default:;
898 }
899 pParaProperties->props().SetvAnchor( nIntValue );
900 break;
901 case NS_ooxml::LN_CT_FramePr_x:
902 pParaProperties->props().Setx(
904 pParaProperties->props().SetxAlign( text::HoriOrientation::NONE );
905 break;
906 case NS_ooxml::LN_CT_FramePr_xAlign:
907 switch( nIntValue )
908 {
909 case NS_ooxml::LN_Value_doc_ST_XAlign_center : nIntValue = text::HoriOrientation::CENTER; break;
910 case NS_ooxml::LN_Value_doc_ST_XAlign_right : nIntValue = text::HoriOrientation::RIGHT; break;
911 case NS_ooxml::LN_Value_doc_ST_XAlign_inside : nIntValue = text::HoriOrientation::INSIDE; break;
912 case NS_ooxml::LN_Value_doc_ST_XAlign_outside : nIntValue = text::HoriOrientation::OUTSIDE; break;
913 case NS_ooxml::LN_Value_doc_ST_XAlign_left : nIntValue = text::HoriOrientation::LEFT; break;
914 default: nIntValue = text::HoriOrientation::NONE;
915 }
916 pParaProperties->props().SetxAlign( nIntValue );
917 break;
918 case NS_ooxml::LN_CT_FramePr_y:
919 pParaProperties->props().Sety(
921 pParaProperties->props().SetyAlign( text::VertOrientation::NONE );
922 break;
923 case NS_ooxml::LN_CT_FramePr_yAlign:
924 switch( nIntValue )
925 {
926 case NS_ooxml::LN_Value_doc_ST_YAlign_top :
927 case NS_ooxml::LN_Value_doc_ST_YAlign_inside :nIntValue = text::VertOrientation::TOP; break;
928 case NS_ooxml::LN_Value_doc_ST_YAlign_center :nIntValue = text::VertOrientation::CENTER;break;
929 case NS_ooxml::LN_Value_doc_ST_YAlign_bottom :
930 case NS_ooxml::LN_Value_doc_ST_YAlign_outside :nIntValue = text::VertOrientation::BOTTOM;break;
931 case NS_ooxml::LN_Value_doc_ST_YAlign_inline :
932 {
933 // HACK: This is for bnc#780851, where a table has one cell that has w:framePr,
934 // which causes that paragraph to be converted to a text frame, and the original
935 // paragraph object no longer exists, which makes table creation fail and furthermore
936 // it would be missing in the table layout anyway. So actually no letting that paragraph
937 // be a text frame "fixes" it. I'm not sure what "inline" is supposed to mean in practice
938 // anyway, so as long as this doesn't cause trouble elsewhere ...
939 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
940 if( pContext )
941 {
942 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
943 if (pParaContext)
944 pParaContext->props().SetFrameMode(false);
945 }
946 nIntValue = text::VertOrientation::NONE;
947 break;
948 }
949 default:
950 nIntValue = text::VertOrientation::NONE;
951 break;
952 }
953 pParaProperties->props().SetyAlign( nIntValue );
954 break;
955 case NS_ooxml::LN_CT_FramePr_hRule:
956 switch( nIntValue )
957 {
958 case NS_ooxml::LN_Value_doc_ST_HeightRule_exact:
959 nIntValue = text::SizeType::FIX;
960 break;
961 case NS_ooxml::LN_Value_doc_ST_HeightRule_atLeast:
962 nIntValue = text::SizeType::MIN;
963 break;
964 case NS_ooxml::LN_Value_doc_ST_HeightRule_auto:
965 //no break;
966 default:;
967 nIntValue = text::SizeType::VARIABLE;
968 }
969 pParaProperties->props().SethRule( nIntValue );
970 break;
971 case NS_ooxml::LN_CT_FramePr_wrap:
972 {
973 //should be either LN_Value_doc_ST_Wrap_notBeside or LN_Value_doc_ST_Wrap_around or LN_Value_doc_ST_Wrap_auto
974 OSL_ENSURE( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
975 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_notBeside ||
976 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
977 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none ||
978 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto,
979 "wrap not around, not_Beside, through, none or auto?");
980 if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
981 sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto )
982 pParaProperties->props().SetWrap ( text::WrapTextMode_DYNAMIC ) ;
983 else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around)
984 pParaProperties->props().SetWrap(text::WrapTextMode_PARALLEL);
985 else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none)
986 pParaProperties->props().SetWrap ( text::WrapTextMode_THROUGH ) ;
987 else
988 pParaProperties->props().SetWrap ( text::WrapTextMode_NONE ) ;
989 }
990 break;
991 case NS_ooxml::LN_CT_FramePr_w:
992 pParaProperties->props().Setw(
994 break;
995 case NS_ooxml::LN_CT_FramePr_h:
996 pParaProperties->props().Seth(
998 break;
999 case NS_ooxml::LN_CT_FramePr_hSpace:
1000 pParaProperties->props().SethSpace(
1002 break;
1003 case NS_ooxml::LN_CT_FramePr_vSpace:
1004 pParaProperties->props().SetvSpace(
1006 break;
1007 default:;
1008 }
1009 }
1010 }
1011 break;
1012 case NS_ooxml::LN_CT_TrackChange_author:
1013 m_pImpl->SetCurrentRedlineAuthor( sStringValue );
1014 break;
1015 case NS_ooxml::LN_CT_TrackChange_date:
1016 m_pImpl->SetCurrentRedlineDate( sStringValue );
1017 break;
1018 case NS_ooxml::LN_CT_Markup_id:
1019 m_pImpl->SetCurrentRedlineId( nIntValue );
1020 break;
1021 case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart:
1022 m_pImpl->AddAnnotationPosition( true, nIntValue );
1023 break;
1024 case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd:
1025 m_pImpl->AddAnnotationPosition( false, nIntValue );
1026 break;
1027 case NS_ooxml::LN_CT_Comment_initials:
1028 m_pImpl->SetCurrentRedlineInitials(sStringValue);
1029 break;
1030 case NS_ooxml::LN_token:
1031 m_pImpl->SetCurrentRedlineToken( nIntValue );
1032 break;
1033 case NS_ooxml::LN_CT_LineNumber_start:
1034 case NS_ooxml::LN_CT_LineNumber_distance:
1035 case NS_ooxml::LN_CT_LineNumber_countBy:
1036 case NS_ooxml::LN_CT_LineNumber_restart:
1037 {
1038 //line numbering in Writer is a global document setting
1039 //in Word is a section setting
1040 //if line numbering is switched on anywhere in the document it's set at the global settings
1041 LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
1042 switch( nName )
1043 {
1044 case NS_ooxml::LN_CT_LineNumber_countBy:
1045 aSettings.nInterval = nIntValue;
1046 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1047 if( pSectionContext )
1048 pSectionContext->SetLnnMod( nIntValue );
1049 break;
1050 case NS_ooxml::LN_CT_LineNumber_start:
1051 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1052 if( pSectionContext )
1053 pSectionContext->SetLnnMin( nIntValue );
1054 break;
1055 case NS_ooxml::LN_CT_LineNumber_distance:
1056 aSettings.nDistance = ConversionHelper::convertTwipToMM100( nIntValue );
1057 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1058 if( pSectionContext )
1059 pSectionContext->SetdxaLnn( nIntValue );
1060 break;
1061 case NS_ooxml::LN_CT_LineNumber_restart:
1062 aSettings.bRestartAtEachPage = nIntValue == NS_ooxml::LN_Value_ST_LineNumberRestart_newPage;
1063 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1064 if( pSectionContext )
1065 pSectionContext->SetLnc( nIntValue );
1066 break;
1067 default:;
1068 }
1069 m_pImpl->SetLineNumberSettings( aSettings );
1070 }
1071 break;
1072 case NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows:
1073 m_pImpl->StartCustomFootnote(m_pImpl->GetTopContext());
1074 break;
1075 case NS_ooxml::LN_CT_FtnEdnRef_id:
1076 // footnote or endnote reference id - not needed
1077 break;
1078 case NS_ooxml::LN_CT_DocGrid_linePitch:
1079 {
1080 //see SwWW8ImplReader::SetDocumentGrid
1081 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1082 if(pSectionContext)
1083 {
1084 pSectionContext->SetGridLinePitch( ConversionHelper::convertTwipToMM100( nIntValue ) );
1085 }
1086 }
1087 break;
1088 case NS_ooxml::LN_CT_DocGrid_charSpace:
1089 {
1090 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
1091 if(pSectionContext)
1092 {
1093 pSectionContext->SetDxtCharSpace( nIntValue );
1094 }
1095 }
1096 break;
1097 case NS_ooxml::LN_CT_DocGrid_type:
1098 {
1099 if (pSectionContext != nullptr)
1100 {
1101 switch( nIntValue )
1102 {
1103 case NS_ooxml::LN_Value_doc_ST_DocGrid_default:
1104 pSectionContext->SetGridType(text::TextGridMode::NONE);
1105 break;
1106 case NS_ooxml::LN_Value_doc_ST_DocGrid_lines:
1107 pSectionContext->SetGridType(text::TextGridMode::LINES);
1108 break;
1109 case NS_ooxml::LN_Value_doc_ST_DocGrid_linesAndChars:
1110 pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
1111 pSectionContext->SetGridSnapToChars( false );
1112 break;
1113 case NS_ooxml::LN_Value_doc_ST_DocGrid_snapToChars:
1114 pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS);
1115 pSectionContext->SetGridSnapToChars( true );
1116 break;
1117 default :
1118 OSL_FAIL("unknown SwTextGrid value");
1119 }
1120 }
1121 }
1122 break;
1123 case NS_ooxml::LN_CT_SdtBlock_sdtContent:
1124 case NS_ooxml::LN_CT_SdtRun_sdtContent:
1125 {
1126 m_pImpl->m_pSdtHelper->SetSdtType(nName);
1127
1128 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::unknown)
1129 {
1130 // Still not determined content type? and it is even not unsupported? Then it is plain text field
1131 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::plainText);
1132 }
1133 if (nName == NS_ooxml::LN_CT_SdtRun_sdtContent)
1134 {
1135 if (m_pImpl->GetSdtStarts().empty() && !m_pImpl->m_pSdtHelper->getSdtTexts().isEmpty())
1136 {
1137 // A non-inline SDT is already started, first convert that to a field and only
1138 // then map the inline SDT to a content control.
1139 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText)
1140 {
1141 m_pImpl->m_pSdtHelper->createPlainTextControl();
1142 }
1143 }
1144
1145 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
1146 if (pContext && m_pImpl->isBreakDeferred(PAGE_BREAK))
1147 {
1148 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape()
1149 && !m_pImpl->IsInComments())
1150 {
1151 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
1152 {
1153 m_pImpl->m_bIsSplitPara = true;
1156 }
1157 else // IsFirstRun
1158 {
1159 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
1160 {
1161 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
1162 }
1163 }
1164
1165 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
1166 m_pImpl->clearDeferredBreaks();
1167 }
1168 }
1169 else if (pContext && m_pImpl->isBreakDeferred(COLUMN_BREAK))
1170 {
1171 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
1172 {
1173 mbIsSplitPara = true;
1174 m_pImpl->m_bIsSplitPara = true;
1177 }
1178 else // IsFirstRun
1179 {
1180 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
1181 {
1182 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
1183 }
1184 }
1185
1186 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
1187 m_pImpl->clearDeferredBreaks();
1188 }
1189
1190 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::richText);
1191 m_pImpl->PushSdt();
1192 break;
1193 }
1194 m_pImpl->SetSdt(true);
1195 }
1196 break;
1197 case NS_ooxml::LN_CT_SdtBlock_sdtEndContent:
1198 case NS_ooxml::LN_CT_SdtRun_sdtEndContent:
1199 if (nName == NS_ooxml::LN_CT_SdtRun_sdtEndContent)
1200 {
1201 // Inline SDT.
1202 switch (m_pImpl->m_pSdtHelper->getControlType())
1203 {
1211 m_pImpl->PopSdt();
1212 break;
1213 default:
1214 break;
1215 }
1216 }
1217
1218 m_pImpl->SetSdt(false);
1219
1220 // It's not possible to insert the relevant property to the character context here:
1221 // the previous, already sent character context may be still active, so the property would be lost.
1222 if (m_pImpl->m_pSdtHelper->isOutsideAParagraph())
1223 m_pImpl->setParaSdtEndDeferred(true);
1224 else
1225 m_pImpl->setSdtEndDeferred(true);
1226
1227 switch (m_pImpl->m_pSdtHelper->getControlType())
1228 {
1231 m_pImpl->m_pSdtHelper->createDropDownControl();
1232 break;
1234 m_pImpl->m_pSdtHelper->createPlainTextControl();
1235 break;
1237 m_pImpl->m_pSdtHelper->createDateContentControl();
1238 break;
1240 default:;
1241 }
1242 break;
1243 case NS_ooxml::LN_CT_SdtListItem_displayText:
1244 m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().push_back(sStringValue);
1245 break;
1246 case NS_ooxml::LN_CT_SdtListItem_value:
1247 m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue);
1248 break;
1249 case NS_ooxml::LN_CT_SdtDate_fullDate:
1250 m_pImpl->m_pSdtHelper->getDate().append(sStringValue);
1251 break;
1252 case NS_ooxml::LN_CT_Background_color:
1253 if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape())
1254 m_pImpl->m_oBackgroundColor = nIntValue;
1255 break;
1256 case NS_ooxml::LN_CT_PageNumber_start:
1257 if (pSectionContext != nullptr && !m_pImpl->IsAltChunk())
1258 pSectionContext->SetPageNumber(nIntValue);
1259 break;
1260 case NS_ooxml::LN_CT_PageNumber_fmt:
1261 if (pSectionContext)
1262 {
1263 sal_Int16 nNumberType = ConversionHelper::ConvertNumberingType(nIntValue, -1);
1264 if (nNumberType != -1)
1265 pSectionContext->SetPageNumberType(nNumberType);
1266 }
1267 break;
1268 case NS_ooxml::LN_CT_FtnEdn_type:
1269 // This is the "separator" footnote, ignore its linebreaks/text.
1270 if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator)
1271 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::ON );
1272 else
1273 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
1274 break;
1275 case NS_ooxml::LN_CT_FtnEdn_id:
1276 {
1277 SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
1278 if ( eSkip == SkipFootnoteSeparator::ON )
1279 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
1280 else if ( eSkip == SkipFootnoteSeparator::SKIPPING )
1281 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
1282 }
1283 break;
1284 case NS_ooxml::LN_CT_DataBinding_prefixMappings:
1285 m_pImpl->m_pSdtHelper->setDataBindingPrefixMapping(sStringValue);
1286 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_prefixMappings", sStringValue);
1287 break;
1288 case NS_ooxml::LN_CT_DataBinding_xpath:
1289 m_pImpl->m_pSdtHelper->setDataBindingXPath(sStringValue);
1290 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_xpath", sStringValue);
1291 break;
1292 case NS_ooxml::LN_CT_DataBinding_storeItemID:
1293 m_pImpl->m_pSdtHelper->setDataBindingStoreItemID(sStringValue);
1294 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_storeItemID", sStringValue);
1295 break;
1296 case NS_ooxml::LN_CT_SdtPlaceholder_docPart_val:
1297 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtPlaceholder_docPart_val", sStringValue);
1298 m_pImpl->m_pSdtHelper->SetPlaceholderDocPart(sStringValue);
1299 break;
1300 case NS_ooxml::LN_CT_SdtColor_val:
1301 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtColor_val", sStringValue);
1302 m_pImpl->m_pSdtHelper->SetColor(sStringValue);
1303 break;
1304 case NS_ooxml::LN_CT_SdtAppearance_val:
1305 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtAppearance_val", sStringValue);
1306 m_pImpl->m_pSdtHelper->SetAppearance(sStringValue);
1307 break;
1308 case NS_ooxml::LN_CT_SdtText_multiLine:
1309 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtText_multiLine", sStringValue);
1310 break;
1311 case NS_ooxml::LN_CT_PTab_leader:
1312 case NS_ooxml::LN_CT_PTab_relativeTo:
1313 break;
1314 case NS_ooxml::LN_CT_PTab_alignment:
1315 m_pImpl->HandlePTab(nIntValue);
1316 break;
1317 case NS_ooxml::LN_CT_Cnf_lastRowLastColumn:
1318 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowLastColumn", OUString::number(nIntValue));
1319 break;
1320 case NS_ooxml::LN_CT_Cnf_lastRowFirstColumn:
1321 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowFirstColumn", OUString::number(nIntValue));
1322 break;
1323 case NS_ooxml::LN_CT_Cnf_firstRowLastColumn:
1324 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowLastColumn", OUString::number(nIntValue));
1325 break;
1326 case NS_ooxml::LN_CT_Cnf_oddHBand:
1327 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddHBand", OUString::number(nIntValue));
1328 break;
1329 case NS_ooxml::LN_CT_Cnf_firstRowFirstColumn:
1330 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowFirstColumn", OUString::number(nIntValue));
1331 break;
1332 case NS_ooxml::LN_CT_Cnf_evenVBand:
1333 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenVBand", OUString::number(nIntValue));
1334 break;
1335 case NS_ooxml::LN_CT_Cnf_evenHBand:
1336 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenHBand", OUString::number(nIntValue));
1337 break;
1338 case NS_ooxml::LN_CT_Cnf_lastColumn:
1339 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastColumn", OUString::number(nIntValue));
1340 break;
1341 case NS_ooxml::LN_CT_Cnf_firstColumn:
1342 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstColumn", OUString::number(nIntValue));
1343 break;
1344 case NS_ooxml::LN_CT_Cnf_oddVBand:
1345 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddVBand", OUString::number(nIntValue));
1346 break;
1347 case NS_ooxml::LN_CT_Cnf_lastRow:
1348 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRow", OUString::number(nIntValue));
1349 break;
1350 case NS_ooxml::LN_CT_Cnf_firstRow:
1351 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRow", OUString::number(nIntValue));
1352 break;
1353 case NS_ooxml::LN_CT_Cnf_val:
1354 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "val", sStringValue);
1355 break;
1356 case NS_ooxml::LN_CT_DocPartName_val:
1357 {
1358 m_sGlossaryEntryName = sStringValue;
1359 break;
1360 }
1361 case NS_ooxml::LN_CT_DocPartGallery_val:
1362 {
1363 const OUString& sGlossaryEntryGallery = sStringValue;
1364 if(m_pImpl->GetTopContext())
1365 {
1366 OUString sName = sGlossaryEntryGallery + ":" + m_sGlossaryEntryName;
1367 // Add glossary entry name as a first paragraph in section
1368 m_pImpl->appendTextPortion(sName, m_pImpl->GetTopContext());
1369 }
1370 break;
1371 }
1372 case NS_ooxml::LN_CT_PermStart_ed:
1373 {
1374 m_pImpl->setPermissionRangeEd(sStringValue);
1375 break;
1376 }
1377 case NS_ooxml::LN_CT_PermStart_edGrp:
1378 {
1379 m_pImpl->setPermissionRangeEdGrp(sStringValue);
1380 break;
1381 }
1382 case NS_ooxml::LN_CT_PermStart_id:
1383 {
1384 m_pImpl->startOrEndPermissionRange(nIntValue);
1385 break;
1386 }
1387 case NS_ooxml::LN_CT_PermEnd_id:
1388 {
1389 m_pImpl->startOrEndPermissionRange(nIntValue);
1390 break;
1391 }
1392 case NS_ooxml::LN_CT_NumFmt_val:
1393 {
1394 try
1395 {
1397 if (m_pImpl->IsInFootnoteProperties())
1398 {
1400 m_pImpl->GetTextDocument(), uno::UNO_QUERY);
1401 if (xFootnotesSupplier.is())
1402 xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings();
1403 }
1404 else
1405 {
1407 m_pImpl->GetTextDocument(), uno::UNO_QUERY);
1408 if (xEndnotesSupplier.is())
1409 xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings();
1410 }
1411 if (xFtnEdnSettings.is())
1412 {
1413 sal_Int16 nNumType = ConversionHelper::ConvertNumberingType(nIntValue);
1414 xFtnEdnSettings->setPropertyValue(getPropertyName(PROP_NUMBERING_TYPE),
1416 }
1417 }
1418 catch (const uno::Exception&)
1419 {
1420 }
1421 }
1422 break;
1423 case NS_ooxml::LN_CT_AltChunk:
1424 {
1425 m_pImpl->HandleAltChunk(sStringValue);
1426 }
1427 break;
1428 case NS_ooxml::LN_AG_Parids_paraId:
1429 if (ParagraphPropertyMap* pParaContext
1430 = dynamic_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContext().get()))
1431 {
1432 pParaContext->props().SetParaId(sStringValue);
1433 }
1434 break;
1435 case NS_ooxml::LN_OfficeArtExtension_Decorative_val:
1436 m_pImpl->GetGraphicImport()->attribute(nName, val);
1437 break;
1438 default:
1439 SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName);
1440 }
1441}
1442
1444{
1445 if (!m_pImpl->hasTableManager() || !m_pImpl->getTableManager().sprm(rSprm))
1446 sprmWithProps(rSprm, m_pImpl->GetTopContext());
1447}
1448
1449// In rtl-paragraphs the meaning of left/right are to be exchanged
1450static bool ExchangeLeftRight(const PropertyMapPtr& rContext, DomainMapper_Impl& rImpl)
1451{
1452 bool bExchangeLeftRight = false;
1453 sal_Int32 aAdjust;
1454 uno::Any aPropPara = rImpl.GetAnyProperty(PROP_WRITING_MODE, rContext);
1455 if( (aPropPara >>= aAdjust) && aAdjust == text::WritingMode2::RL_TB )
1456 bExchangeLeftRight = true;
1457 return bExchangeLeftRight;
1458}
1459
1460void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
1461{
1462 // These SPRM's are not specific to any section, so it's expected that there is no context yet.
1463 switch (rSprm.getId())
1464 {
1465 case NS_ooxml::LN_background_background:
1466 return;
1467 default:
1468 break;
1469 }
1470
1471 OSL_ENSURE(rContext, "PropertyMap has to be valid!");
1472 if(!rContext)
1473 return ;
1474
1475 sal_uInt32 nSprmId = rSprm.getId();
1476 //needed for page properties
1477 SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext();
1478 Value::Pointer_t pValue = rSprm.getValue();
1479 sal_Int32 nIntValue = pValue->getInt();
1480 const OUString sStringValue = pValue->getString();
1481
1482 switch(nSprmId)
1483 {
1484 case NS_ooxml::LN_CT_PPrBase_jc:
1485 {
1486 bool bExchangeLeftRight = !IsRTFImport() && !m_pImpl->IsInComments() && ExchangeLeftRight(rContext, *m_pImpl);
1487 handleParaJustification(nIntValue, rContext, bExchangeLeftRight);
1488 break;
1489 }
1490 case NS_ooxml::LN_CT_PPrBase_keepLines:
1491 rContext->Insert(PROP_PARA_SPLIT, uno::Any(nIntValue == 0));
1492 break;
1493 case NS_ooxml::LN_CT_PPrBase_keepNext:
1494 rContext->Insert(PROP_PARA_KEEP_TOGETHER, uno::Any( nIntValue != 0 ) );
1495 break;
1496 case NS_ooxml::LN_CT_PPrBase_pageBreakBefore:
1497 rContext->Insert(PROP_BREAK_TYPE, uno::Any(nIntValue ? style::BreakType_PAGE_BEFORE : style::BreakType_NONE), /*bOverwrite=*/bool(nIntValue));
1498 break;
1499 case NS_ooxml::LN_CT_NumPr_ilvl:
1500 if (nIntValue < 0 || 10 <= nIntValue)
1501 {
1502 SAL_INFO("writerfilter",
1503 "unsupported numbering level " << nIntValue);
1504 break;
1505 }
1506 if( IsStyleSheetImport() )
1507 {
1508 //style sheets cannot have a numbering rule attached
1509 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1510 if (pStyleSheetPropertyMap)
1511 pStyleSheetPropertyMap->SetListLevel( static_cast<sal_Int16>(nIntValue) );
1512 }
1513 // 0-8 are the 9 levels that Microsoft supports. (LO supports 10 levels).
1514 // 9 indicates "no numbering", for which LO has no corresponding concept,
1515 // and so it will be treated as the 10th level.
1516 // finishParagraph() will convert the 9 into "no numbering" for direct formatting.
1517 // (Styles only use this PROP for round-tripping and UI, but cannot trust it for import)
1518 if (!IsStyleSheetImport() || nIntValue != 9)
1519 rContext->Insert(PROP_NUMBERING_LEVEL, uno::Any(static_cast<sal_Int16>(nIntValue)));
1520 break;
1521 case NS_ooxml::LN_CT_NumPr_numId:
1522 {
1523 //convert the ListTable entry to a NumberingRules property and apply it
1524 ListsManager::Pointer pListTable = m_pImpl->GetListTable();
1525 ListDef::Pointer pList = pListTable->GetList( nIntValue );
1526 if( IsStyleSheetImport() )
1527 {
1528 //style sheets cannot have a numbering rule attached
1529 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1530 if (pStyleSheetPropertyMap)
1531 pStyleSheetPropertyMap->props().SetListId( nIntValue );
1532 }
1533 if( pList )
1534 {
1535 if( !IsStyleSheetImport() )
1536 {
1537 uno::Any aRules( pList->GetNumberingRules( ) );
1538 rContext->Insert( PROP_NUMBERING_RULES, aRules );
1539 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
1540 if (pContext)
1541 {
1542 assert(dynamic_cast<ParagraphPropertyMap*>(pContext.get()));
1543 static_cast<ParagraphPropertyMap*>(pContext.get())->props().SetListId(pList->GetId());
1544 }
1545
1546 // Indentation can came from:
1547 // 1) Paragraph style's numbering's indentation: the current non-style numId has priority over it.
1548 // 2) Numbering's indentation: Writer handles that natively, so it should not be set on rContext.
1549 // 3) Paragraph style's indentation: ditto.
1550 // 4) Direct paragraph formatting: that will came later.
1551 // So no situation where keeping indentation at this point would make sense -> erase.
1552 rContext->Erase(PROP_PARA_FIRST_LINE_INDENT);
1553 rContext->Erase(PROP_PARA_LEFT_MARGIN);
1554 rContext->Erase(PROP_PARA_RIGHT_MARGIN);
1555 }
1556 }
1557 else
1558 {
1559 if( !IsStyleSheetImport() )
1560 {
1561 // eg. disabled numbering using non-existent numId "0"
1562 rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::Any( OUString() ) );
1563 // disable inheritance of indentation of parent styles
1564 rContext->Insert( PROP_PARA_LEFT_MARGIN, uno::Any( sal_Int32(0) ), /*bOverwrite=*/false);
1565 rContext->Insert( PROP_PARA_FIRST_LINE_INDENT,
1566 uno::Any( sal_Int32(0) ), /*bOverwrite=*/false);
1567 }
1568 }
1569 }
1570 break;
1571 case NS_ooxml::LN_CT_PPrBase_suppressLineNumbers:
1572 rContext->Insert(PROP_PARA_LINE_NUMBER_COUNT, uno::Any( nIntValue == 0 ) );
1573 break;
1574 case NS_ooxml::LN_inTbl:
1575 break;
1576 case NS_ooxml::LN_tblDepth:
1577 //not handled via sprm but via text( 0x07 )
1578 break;
1579 case NS_ooxml::LN_CT_FramePr_w:
1580 break;
1581 case NS_ooxml::LN_CT_FramePr_wrap:
1582 break;
1583
1584 case NS_ooxml::LN_CT_PrBase_pBdr: //paragraph border
1585 resolveSprmProps(*this, rSprm);
1586 break;
1587 case NS_ooxml::LN_CT_PBdr_top:
1588 case NS_ooxml::LN_CT_PBdr_left:
1589 case NS_ooxml::LN_CT_PBdr_bottom:
1590 case NS_ooxml::LN_CT_PBdr_right:
1591 case NS_ooxml::LN_CT_PBdr_between:
1592 {
1594 if( pProperties )
1595 {
1596 auto pBorderHandler = std::make_shared<BorderHandler>( true );
1597 pProperties->resolve(*pBorderHandler);
1599 PropertyIds eBorderComplexColorId = PropertyIds::INVALID;
1600 PropertyIds eBorderDistId = PropertyIds::INVALID;
1601 switch( nSprmId )
1602 {
1603 case NS_ooxml::LN_CT_PBdr_top:
1604 eBorderId = PROP_TOP_BORDER;
1605 eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
1606 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
1607 break;
1608 case NS_ooxml::LN_CT_PBdr_left:
1609 eBorderId = PROP_LEFT_BORDER;
1610 eBorderComplexColorId = PROP_BORDER_LEFT_COMPLEX_COLOR;
1611 eBorderDistId = PROP_LEFT_BORDER_DISTANCE;
1612 break;
1613 case NS_ooxml::LN_CT_PBdr_bottom:
1614 eBorderId = PROP_BOTTOM_BORDER;
1615 eBorderComplexColorId = PROP_BORDER_BOTTOM_COMPLEX_COLOR;
1616 eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE;
1617 break;
1618 case NS_ooxml::LN_CT_PBdr_right:
1619 eBorderId = PROP_RIGHT_BORDER;
1620 eBorderComplexColorId = PROP_BORDER_RIGHT_COMPLEX_COLOR;
1621 eBorderDistId = PROP_RIGHT_BORDER_DISTANCE;
1622 break;
1623 case NS_ooxml::LN_CT_PBdr_between:
1624 if (m_pImpl->handlePreviousParagraphBorderInBetween())
1625 {
1626 // If previous paragraph also had border in between property
1627 // then it is possible to emulate this border as top border
1628 // for current paragraph
1629 eBorderId = PROP_TOP_BORDER;
1630 eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
1631 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
1632 }
1633 // Since there are borders in between, each paragraph will have own borders. No more joining
1634 rContext->Insert(PROP_PARA_CONNECT_BORDERS, uno::Any(false));
1635 break;
1636 default:;
1637 }
1638
1639 if (eBorderId != PropertyIds::INVALID)
1640 {
1641 rContext->Insert(eBorderId, uno::Any(pBorderHandler->getBorderLine()));
1642 }
1643 if (eBorderComplexColorId != PropertyIds::INVALID)
1644 {
1645 auto aComplexColor = pBorderHandler->getComplexColor();
1646 auto xComplexColor = model::color::createXComplexColor(aComplexColor);
1647 rContext->Insert(eBorderComplexColorId, uno::Any(xComplexColor));
1648 }
1649 if (eBorderDistId != PropertyIds::INVALID)
1650 {
1651 rContext->Insert(eBorderDistId, uno::Any(pBorderHandler->getLineDistance()));
1652 }
1653 if ( nSprmId == NS_ooxml::LN_CT_PBdr_right )
1654 {
1655 table::ShadowFormat aFormat;
1656 // Word only allows shadows on visible borders
1657 if ( pBorderHandler->getShadow() && pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE )
1658 aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
1659 rContext->Insert(PROP_PARA_SHADOW_FORMAT, uno::Any(aFormat));
1660 }
1661 }
1662 }
1663 break;
1664 case NS_ooxml::LN_CT_PBdr_bar:
1665 break;
1666 case NS_ooxml::LN_CT_PPrBase_suppressAutoHyphens:
1667 rContext->Insert(PROP_PARA_IS_HYPHENATION, uno::Any( nIntValue == 0 ));
1668 break;
1669 case NS_ooxml::LN_CT_FramePr_h:
1670 break;
1671 case NS_ooxml::LN_CT_PrBase_shd:
1672 {
1673 //contains fore color, back color and shadow percentage, results in a brush
1675 if( pProperties )
1676 {
1677 auto pCellColorHandler = std::make_shared<CellColorHandler>();
1678 pCellColorHandler->setOutputFormat( CellColorHandler::Paragraph );
1679 bool bEnableTempGrabBag = !pCellColorHandler->isInteropGrabBagEnabled();
1680 if( bEnableTempGrabBag )
1681 pCellColorHandler->enableInteropGrabBag( "TempShdPropsGrabBag" );
1682
1683 pProperties->resolve(*pCellColorHandler);
1684 rContext->InsertProps(pCellColorHandler->getProperties().get());
1685
1686 rContext->Insert(PROP_CHAR_THEME_FILL, pCellColorHandler->getInteropGrabBag().Value, true, PARA_GRAB_BAG);
1687 if(bEnableTempGrabBag)
1688 pCellColorHandler->disableInteropGrabBag();
1689 }
1690 }
1691 break;
1692 case NS_ooxml::LN_CT_FramePr_vSpace:
1693 break; // sprmPDyaFromText
1694 case NS_ooxml::LN_CT_FramePr_hSpace:
1695 break; // sprmPDxaFromText
1696 case NS_ooxml::LN_CT_FramePr_anchorLock:
1697 break;
1698 case NS_ooxml::LN_CT_PPrBase_widowControl:
1699 {
1700 uno::Any aVal( uno::Any( sal_Int8(nIntValue ? 2 : 0 )));
1701 rContext->Insert( PROP_PARA_WIDOWS, aVal );
1702 rContext->Insert( PROP_PARA_ORPHANS, aVal );
1703 }
1704 break; // sprmPFWidowControl
1705 case NS_ooxml::LN_CT_PPrBase_overflowPunct:
1706 rContext->Insert(PROP_PARA_IS_HANGING_PUNCTUATION, uno::Any( nIntValue == 0 ));
1707 break;
1708 case NS_ooxml::LN_CT_PPrBase_topLinePunct:
1709 break;
1710 case NS_ooxml::LN_CT_PPrBase_autoSpaceDE:
1711 break;
1712 case NS_ooxml::LN_CT_PPrBase_autoSpaceDN:
1713 break;
1714 case NS_ooxml::LN_CT_PPrBase_textAlignment:
1715 {
1716 sal_Int16 nAlignment = 0;
1717 switch (nIntValue)
1718 {
1719 case NS_ooxml::LN_Value_doc_ST_TextAlignment_top:
1720 nAlignment = 2;
1721 break;
1722 case NS_ooxml::LN_Value_doc_ST_TextAlignment_center:
1723 nAlignment = 3;
1724 break;
1725 case NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline:
1726 nAlignment = 1;
1727 break;
1728 case NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom:
1729 nAlignment = 4;
1730 break;
1731 case NS_ooxml::LN_Value_doc_ST_TextAlignment_auto:
1732 default:
1733 break;
1734 }
1735 rContext->Insert( PROP_PARA_VERT_ALIGNMENT, uno::Any( nAlignment) );
1736 }
1737 break;
1738 case NS_ooxml::LN_CT_PPrBase_textDirection:
1739 {
1740 switch (nIntValue)
1741 {
1742 case NS_ooxml::LN_Value_ST_TextDirection_tbRl: // ~ vert="eaVert"
1743 {
1744 m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL);
1745 break;
1746 }
1747 case NS_ooxml::LN_Value_ST_TextDirection_btLr: // ~ vert="vert270"
1748 {
1749 m_pImpl->SetFrameDirection(text::WritingMode2::BT_LR);
1750 break;
1751 }
1752 case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
1753 {
1754 // East Asian character rotation is not implemented in LO, use ordinary LR_TB instead.
1755 m_pImpl->SetFrameDirection(text::WritingMode2::LR_TB);
1756 break;
1757 }
1758 case NS_ooxml::LN_Value_ST_TextDirection_tbRlV: // ~ vert="vert"
1759 {
1760 m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL90);
1761 break;
1762 }
1763 case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
1764 // default in LO. Do not overwrite RL_TB set by bidi.
1765 break;
1766 case NS_ooxml::LN_Value_ST_TextDirection_tbLrV: // ~ vert="mongolianVert"
1767 {
1768 m_pImpl->SetFrameDirection(text::WritingMode2::TB_LR);
1769 break;
1770 }
1771 default:
1772 SAL_WARN("writerfilter", "DomainMapper::sprmWithProps: unhandled textDirection");
1773 }
1774 }
1775 break;
1776 case NS_ooxml::LN_CT_PPrBase_outlineLvl:
1777 {
1778 if (nIntValue < WW_OUTLINE_MIN || nIntValue > WW_OUTLINE_MAX)
1779 break; // invalid value is ignored by MS Word
1780
1781 if( IsStyleSheetImport() )
1782 {
1783 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
1784 if (pStyleSheetPropertyMap)
1785 pStyleSheetPropertyMap->SetOutlineLevel(nIntValue);
1786 }
1787 else
1788 {
1789 // convert MS body level (9) to LO body level (0) and equivalent outline levels
1790 sal_Int16 nLvl = nIntValue == WW_OUTLINE_MAX ? 0 : nIntValue + 1;
1791 rContext->Insert(PROP_OUTLINE_LEVEL, uno::Any ( nLvl ));
1792 }
1793 }
1794 break;
1795 case NS_ooxml::LN_CT_PPrBase_bidi:
1796 {
1797 // Four situations to handle:
1798 // 1.) bidi same as previous setting: no adjust change
1799 // 2.) no previous adjust: set appropriate default for this bidi
1800 // 3.) previous adjust and bidi different from previous: swap adjusts
1801 // 4.) previous adjust and no previous bidi: RTL swaps adjust
1802
1803 const sal_Int16 nWritingMode = nIntValue ? text::WritingMode2::RL_TB : text::WritingMode2::LR_TB;
1804 sal_Int16 nParentBidi = -1;
1805 m_pImpl->GetPropertyFromParaStyleSheet(PROP_WRITING_MODE) >>= nParentBidi;
1806 // Paragraph justification reverses its meaning in an RTL context.
1807 // 1. Only make adjustments if the BiDi changes.
1808 if (nParentBidi != nWritingMode && !IsRTFImport() && !m_pImpl->IsInComments())
1809 {
1810 style::ParagraphAdjust eAdjust = style::ParagraphAdjust(-1);
1811 // 2. no adjust property exists yet
1812 if ( !(m_pImpl->GetAnyProperty(PROP_PARA_ADJUST, rContext) >>= eAdjust) )
1813 {
1814 // RTL defaults to right adjust
1815 eAdjust = nIntValue ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
1816 rContext->Insert(PROP_PARA_ADJUST, uno::Any( eAdjust ), /*bOverwrite=*/false);
1817 }
1818 // 3,4. existing adjust: if RTL, then swap. If LTR, but previous was RTL, also swap.
1819 else if ( nIntValue || nParentBidi == sal_Int16(text::WritingMode2::RL_TB) )
1820 {
1821 if ( eAdjust == style::ParagraphAdjust_RIGHT )
1822 rContext->Insert(PROP_PARA_ADJUST, uno::Any( style::ParagraphAdjust_LEFT ));
1823 else if ( eAdjust == style::ParagraphAdjust_LEFT )
1824 rContext->Insert(PROP_PARA_ADJUST, uno::Any( style::ParagraphAdjust_RIGHT ));
1825 }
1826 }
1827 rContext->Insert(PROP_WRITING_MODE, uno::Any( nWritingMode ));
1828 }
1829
1830 break;
1831 case NS_ooxml::LN_EG_SectPrContents_bidi:
1832 if (pSectionContext != nullptr)
1833 {
1834 const sal_Int16 writingMode = (nIntValue != 0) ? sal_Int16(text::WritingMode2::RL_TB) : sal_Int16(text::WritingMode2::LR_TB);
1835 pSectionContext->Insert(PROP_WRITING_MODE, uno::Any(writingMode));
1836 }
1837 break;
1838 case NS_ooxml::LN_EG_SectPrContents_rtlGutter:
1839 if (pSectionContext != nullptr)
1840 {
1841 bool bRtlGutter = nIntValue != 0;
1842 pSectionContext->Insert(PROP_RTL_GUTTER, uno::Any(bRtlGutter));
1843 }
1844 break;
1845 case NS_ooxml::LN_EG_RPrBase_highlight:
1846 {
1847 // MS Word completely ignores character highlighting in character styles.
1848 if ( IsStyleSheetImport() )
1849 {
1850 const StyleSheetEntryPtr pCurrStyle = GetStyleSheetTable()->GetCurrentEntry();
1851 if ( pCurrStyle && pCurrStyle->m_nStyleTypeCode == STYLE_TYPE_CHAR )
1852 break;
1853 }
1854
1855 PropertyIds ePropertyId = m_pImpl->IsInComments() ? PROP_CHAR_BACK_COLOR : PROP_CHAR_HIGHLIGHT;
1856
1857 // OOXML import uses an ID
1858 if( IsOOXMLImport() )
1859 {
1860 sal_Int32 nColor = 0;
1861 if( getColorFromId(nIntValue, nColor) )
1862 rContext->Insert(ePropertyId, uno::Any(nColor));
1863 }
1864 // RTF import uses the actual color value
1865 else if( IsRTFImport() )
1866 {
1867 rContext->Insert(ePropertyId, uno::Any(nIntValue));
1868 }
1869 }
1870 break;
1871 case NS_ooxml::LN_EG_RPrBase_em:
1872 rContext->Insert(PROP_CHAR_EMPHASIS, uno::Any ( getEmphasisValue (nIntValue)));
1873 break;
1874 case NS_ooxml::LN_EG_RPrBase_emboss:
1875 case NS_ooxml::LN_EG_RPrBase_b:
1876 case NS_ooxml::LN_EG_RPrBase_bCs:
1877 case NS_ooxml::LN_EG_RPrBase_i:
1878 case NS_ooxml::LN_EG_RPrBase_iCs:
1879 case NS_ooxml::LN_EG_RPrBase_strike:
1880 case NS_ooxml::LN_EG_RPrBase_dstrike:
1881 case NS_ooxml::LN_EG_RPrBase_outline:
1882 case NS_ooxml::LN_EG_RPrBase_shadow:
1883 case NS_ooxml::LN_EG_RPrBase_caps:
1884 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1885 case NS_ooxml::LN_EG_RPrBase_vanish:
1886 case NS_ooxml::LN_EG_RPrBase_webHidden:
1887 {
1888 PropertyIds ePropertyId = PROP_CHAR_WEIGHT; //initialized to prevent warning!
1889 switch( nSprmId )
1890 {
1891 case NS_ooxml::LN_EG_RPrBase_b:
1892 case NS_ooxml::LN_EG_RPrBase_bCs:
1893 ePropertyId = nSprmId != NS_ooxml::LN_EG_RPrBase_bCs ? PROP_CHAR_WEIGHT : PROP_CHAR_WEIGHT_COMPLEX;
1894 break;
1895 case NS_ooxml::LN_EG_RPrBase_i:
1896 case NS_ooxml::LN_EG_RPrBase_iCs:
1897 ePropertyId = nSprmId == NS_ooxml::LN_EG_RPrBase_i ? PROP_CHAR_POSTURE : PROP_CHAR_POSTURE_COMPLEX;
1898 break;
1899 case NS_ooxml::LN_EG_RPrBase_strike:
1900 case NS_ooxml::LN_EG_RPrBase_dstrike:
1901 ePropertyId = PROP_CHAR_STRIKEOUT;
1902 break;
1903 case NS_ooxml::LN_EG_RPrBase_outline:
1904 ePropertyId = PROP_CHAR_CONTOURED;
1905 break;
1906 case NS_ooxml::LN_EG_RPrBase_shadow:
1907 ePropertyId = PROP_CHAR_SHADOWED;
1908 break;
1909 case NS_ooxml::LN_EG_RPrBase_caps:
1910 case NS_ooxml::LN_EG_RPrBase_smallCaps:
1911 ePropertyId = PROP_CHAR_CASE_MAP;
1912 break;
1913 case NS_ooxml::LN_EG_RPrBase_vanish:
1914 case NS_ooxml::LN_EG_RPrBase_webHidden:
1915 ePropertyId = PROP_CHAR_HIDDEN;
1916 break;
1917 case NS_ooxml::LN_EG_RPrBase_emboss:
1918 ePropertyId = PROP_CHAR_RELIEF;
1919 break;
1920 }
1921 //expected: 0,1,128,129
1922 if(nIntValue != 128) //inherited from paragraph - ignore
1923 {
1924 if( nIntValue == 129) //inverted style sheet value
1925 {
1926 //get value from style sheet and invert it
1927 sal_Int16 nStyleValue = 0;
1928 uno::Any aStyleVal = m_pImpl->GetPropertyFromParaStyleSheet(ePropertyId);
1929 if( !aStyleVal.hasValue() )
1930 {
1931 nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
1932 4 : 1;
1933 }
1934 else if(aStyleVal.getValueTypeClass() == uno::TypeClass_FLOAT )
1935 {
1936 double fDoubleValue = 0;
1937 //only in case of awt::FontWeight
1938 aStyleVal >>= fDoubleValue;
1939 nIntValue = fDoubleValue > 100. ? 0 : 1;
1940 }
1941 else if((aStyleVal >>= nStyleValue) ||
1942 (nStyleValue = static_cast<sal_Int16>(comphelper::getEnumAsINT32(aStyleVal))) >= 0 )
1943 {
1944 nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ?
1945 nStyleValue ? 0 : 4 :
1946 nStyleValue ? 0 : 1;
1947 }
1948 else
1949 {
1950 OSL_FAIL( "what type was it");
1951 }
1952 }
1953
1954 switch( nSprmId )
1955 {
1956 case NS_ooxml::LN_EG_RPrBase_b:
1957 case NS_ooxml::LN_EG_RPrBase_bCs:
1958 {
1959 uno::Any aBold( uno::Any( nIntValue ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL ) );
1960
1961 rContext->Insert(ePropertyId, aBold );
1962 if( nSprmId != NS_ooxml::LN_EG_RPrBase_bCs )
1963 rContext->Insert(PROP_CHAR_WEIGHT_ASIAN, aBold );
1964
1965 if (nSprmId == NS_ooxml::LN_EG_RPrBase_b)
1966 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "b", OUString::number(nIntValue));
1967 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_bCs)
1968 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "bCs", OUString::number(nIntValue));
1969 }
1970 break;
1971 case NS_ooxml::LN_EG_RPrBase_i:
1972 case NS_ooxml::LN_EG_RPrBase_iCs:
1973 {
1974 uno::Any aPosture( uno::Any( nIntValue ? awt::FontSlant_ITALIC : awt::FontSlant_NONE ) );
1975 rContext->Insert( ePropertyId, aPosture );
1976 if (nSprmId != NS_ooxml::LN_EG_RPrBase_iCs)
1977 rContext->Insert(PROP_CHAR_POSTURE_ASIAN, aPosture );
1978 if (nSprmId == NS_ooxml::LN_EG_RPrBase_i)
1979 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "i", OUString::number(nIntValue));
1980 }
1981 break;
1982 case NS_ooxml::LN_EG_RPrBase_strike:
1983 {
1984 const auto eStrike
1985 = nIntValue ? awt::FontStrikeout::SINGLE : awt::FontStrikeout::NONE;
1986 const bool bOverwrite(nIntValue);
1987 rContext->Insert(ePropertyId, uno::Any(eStrike), bOverwrite);
1988 }
1989 break;
1990 case NS_ooxml::LN_EG_RPrBase_dstrike:
1991 {
1992 const auto eStrike
1993 = nIntValue ? awt::FontStrikeout::DOUBLE : awt::FontStrikeout::NONE;
1994 const bool bOverwrite(nIntValue);
1995 rContext->Insert(ePropertyId, uno::Any(eStrike), bOverwrite);
1996 }
1997 break;
1998 case NS_ooxml::LN_EG_RPrBase_outline:
1999 case NS_ooxml::LN_EG_RPrBase_shadow:
2000 case NS_ooxml::LN_EG_RPrBase_vanish:
2001 case NS_ooxml::LN_EG_RPrBase_webHidden:
2002 rContext->Insert(ePropertyId, uno::Any( nIntValue != 0 ));
2003 break;
2004 case NS_ooxml::LN_EG_RPrBase_smallCaps:
2005 // If smallcaps would be just disabled and another casemap is already inserted, don't do anything.
2006 if (nIntValue || !rContext->isSet(ePropertyId) )
2007 rContext->Insert(ePropertyId, uno::Any( nIntValue ? style::CaseMap::SMALLCAPS : style::CaseMap::NONE));
2008 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "smallCaps", OUString::number(nIntValue));
2009 break;
2010 case NS_ooxml::LN_EG_RPrBase_caps:
2011 rContext->Insert(ePropertyId,
2012 uno::Any( nIntValue ? style::CaseMap::UPPERCASE : style::CaseMap::NONE));
2013 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "caps", OUString::number(nIntValue));
2014 break;
2015 case NS_ooxml::LN_EG_RPrBase_emboss:
2016 rContext->Insert(ePropertyId,
2017 uno::Any( nIntValue ? awt::FontRelief::EMBOSSED : awt::FontRelief::NONE ));
2018 break;
2019
2020 }
2021 }
2022 }
2023 break;
2024 case NS_ooxml::LN_EG_RPrBase_sz:
2025 case NS_ooxml::LN_EG_RPrBase_szCs:
2026 {
2027 //multiples of half points (12pt == 24)
2028 double fVal = double(nIntValue) / 2.;
2029 uno::Any aVal( fVal );
2030 if( NS_ooxml::LN_EG_RPrBase_szCs == nSprmId )
2031 {
2032 rContext->Insert( PROP_CHAR_HEIGHT_COMPLEX, aVal );
2033 }
2034 else
2035 {
2036 const RubyInfo &aInfo = m_pImpl->GetRubyInfo();
2037 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt && aInfo.nHps > 0 )
2038 {
2039 fVal = double(aInfo.nHps) / 2.;
2040 aVal <<= fVal;
2041 }
2042 else if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase && aInfo.nHpsBaseText > 0 )
2043 {
2044 fVal = double(aInfo.nHpsBaseText) / 2.;
2045 aVal <<= fVal;
2046 }
2047 //Asian get the same value as Western
2048 rContext->Insert( PROP_CHAR_HEIGHT, aVal );
2049 rContext->Insert( PROP_CHAR_HEIGHT_ASIAN, aVal );
2050 }
2051 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, (nSprmId == NS_ooxml::LN_EG_RPrBase_sz ? OUString("sz") : OUString("szCs")), OUString::number(nIntValue));
2052 }
2053 break;
2054 case NS_ooxml::LN_EG_RPrBase_position:
2055 // The spec says 0 is the same as the lack of the value, so don't parse that.
2056 if ( nIntValue )
2057 {
2059 m_pImpl->deferCharacterProperty( nSprmId, uno::Any( nIntValue ));
2060 else if (!m_pImpl->IsDocDefaultsImport())
2061 {
2062 // For some undocumented reason, MS Word seems to ignore this in docDefaults
2063
2064 const StyleSheetEntryPtr pCurrStyle = GetStyleSheetTable()->GetCurrentEntry();
2065 if (pCurrStyle && pCurrStyle->m_nStyleTypeCode == STYLE_TYPE_PARA && nIntValue < 0)
2066 {
2067 m_pImpl->deferCharacterProperty(nSprmId, uno::Any(nIntValue));
2068 break;
2069 }
2070
2071 // DON'T FIXME: Truly calculating this for Character Styles will be tricky,
2072 // because it depends on the final fontsize - regardless of
2073 // where it is set. So at the style level,
2074 // the escapement value would need to be grabbagged.
2075 // At appendText time the final fontsize needs to be determined, and then
2076 // the escapement can be calculated from the grabbag'd half-point value
2077 // and directly applied. Yuck.
2078 // It seems best to just treat charstyle escapement like
2079 // pre-commit e70df84352d3670508a4666c97df44f82c1ce934
2080 // which just assigned default values and ignored the actual/given escapement.
2081 sal_Int16 nEscapement = nIntValue > 0 ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB;
2082 sal_Int8 nProp = DFLT_ESC_PROP;
2083 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( nEscapement ) );
2084 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
2085 }
2086 }
2087 break;
2088 case NS_ooxml::LN_EG_RPrBase_spacing:
2089 {
2090 //Kerning half point values
2091 //TODO: there are two kerning values -
2092 // in ww8par6.cxx NS_sprm::LN_CHpsKern is used as boolean AutoKerning
2093 sal_Int16 nResult = static_cast<sal_Int16>(ConversionHelper::convertTwipToMM100(nIntValue));
2094 if (m_pImpl->IsInComments())
2095 {
2096 nResult = static_cast<sal_Int16>(nIntValue);
2097 }
2098 rContext->Insert(PROP_CHAR_CHAR_KERNING, uno::Any(nResult));
2099 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", OUString::number(nIntValue));
2100 }
2101 break;
2102 case NS_ooxml::LN_EG_RPrBase_kern: // auto kerning is bound to a minimum font size in Word - but not in Writer :-(
2103 rContext->Insert(PROP_CHAR_AUTO_KERNING, uno::Any( nIntValue != 0 ) );
2104 break;
2105 case NS_ooxml::LN_EG_RPrBase_w:
2106 // ST_TextScale must fall between 1% and 600% according to spec, otherwise resets to 100% according to experience
2107 if ((1 <= nIntValue) && (nIntValue <= 600))
2108 {
2109 rContext->Insert(PROP_CHAR_SCALE_WIDTH,
2110 uno::Any( sal_Int16(nIntValue) ));
2111 }
2112 else
2113 {
2114 rContext->Insert(PROP_CHAR_SCALE_WIDTH,
2115 uno::Any( sal_Int16(100) ));
2116 }
2117 break;
2118 case NS_ooxml::LN_EG_RPrBase_imprint:
2119 // FontRelief: NONE, EMBOSSED, ENGRAVED
2120 rContext->Insert(PROP_CHAR_RELIEF,
2121 uno::Any( nIntValue ? awt::FontRelief::ENGRAVED : awt::FontRelief::NONE ));
2122 break;
2123 case NS_ooxml::LN_EG_RPrBase_effect:
2124 // The file-format has many character animations. We have only
2125 // one, so we use it always. Suboptimal solution though.
2126 if (nIntValue != NS_ooxml::LN_Value_ST_TextEffect_none)
2127 rContext->Insert(PROP_CHAR_FLASH, uno::Any( true ));
2128 else
2129 rContext->Insert(PROP_CHAR_FLASH, uno::Any( false ));
2130 break;
2131 case NS_ooxml::LN_EG_RPrBase_rtl:
2132 break;
2133 case NS_ooxml::LN_EG_RPrBase_shd:
2134 {
2135 //contains fore color, back color and shadow percentage, results in a brush
2137 if( pProperties )
2138 {
2139 auto pCellColorHandler = std::make_shared<CellColorHandler>();
2140 pCellColorHandler->setOutputFormat( CellColorHandler::Character );
2141 pProperties->resolve(*pCellColorHandler);
2142 rContext->InsertProps(pCellColorHandler->getProperties().get());
2143 m_pImpl->GetTopContext()->Insert(PROP_CHAR_SHADING_MARKER, uno::Any(true), true, CHAR_GRAB_BAG );
2144
2145 // EditEng doesn't have a corresponding property for Shading Value, so eliminate it.
2146 if (m_pImpl->IsInComments())
2147 rContext->Erase(PROP_CHAR_SHADING_VALUE);
2148 }
2149 break;
2150 }
2151 case NS_ooxml::LN_EG_SectPrContents_type:
2152 /* break type
2153 0 - No break
2154 1 - New Column
2155 2 - New page
2156 3 - Even page
2157 4 - odd page
2158 */
2159 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2160 if(pSectionContext)
2161 {
2162 //continuous break only allowed if it is not the only section break
2163 SectionPropertyMap* pLastContext = m_pImpl->GetLastSectionContext();
2164 if ( nIntValue != NS_ooxml::LN_Value_ST_SectionMark_continuous || pLastContext || m_pImpl->GetParaSectpr() )
2165 pSectionContext->SetBreakType( nIntValue );
2166 }
2167 break;
2168 case NS_ooxml::LN_EG_SectPrContents_titlePg:
2169 {
2170 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2171 if(pSectionContext)
2172 pSectionContext->SetTitlePage( nIntValue > 0 );//section has title page
2173 }
2174 break;
2175 case 165:
2176 {
2177 //page height, rounded to default values, default: 0x3dc0 twip
2178 sal_Int32 nHeight = ConversionHelper::convertTwipToMM100( nIntValue );
2179 rContext->Insert( PROP_HEIGHT, uno::Any( PaperInfo::sloppyFitPageDimension( nHeight ) ) );
2180 }
2181 break;
2182 case NS_ooxml::LN_EG_SectPrContents_textDirection:
2183 {
2184 sal_Int16 nDirection = text::WritingMode2::LR_TB;
2185 switch( nIntValue )
2186 {
2187 // East Asian 270deg rotation in lrTbV is not implemented in LO
2188 case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
2189 case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
2190 nDirection = text::WritingMode2::LR_TB; // =0
2191 break;
2192 case NS_ooxml::LN_Value_ST_TextDirection_tbRl:
2193 nDirection = text::WritingMode2::TB_RL; // =2
2194 break;
2195 // Word does not write btLr in sections, but LO would be able to use it.
2196 case NS_ooxml::LN_Value_ST_TextDirection_btLr:
2197 nDirection = text::WritingMode2::BT_LR; // =5
2198 break;
2199 // Word maps mongolian direction to tbRlV in sections in file save, as of Aug 2022.
2200 // From point of OOXML standard it would be tbLrV. Since tbRlV is currently not
2201 // implemented in LO for text direction in page styles, we follow Word here.
2202 case NS_ooxml::LN_Value_ST_TextDirection_tbRlV:
2203 case NS_ooxml::LN_Value_ST_TextDirection_tbLrV:
2204 nDirection = text::WritingMode2::TB_LR; // =3
2205 break;
2206 default:;
2207 }
2208
2209 PropertyMap * pTargetContext = rContext.get();
2210
2211 if (pSectionContext)
2212 {
2213 pTargetContext = pSectionContext;
2214 }
2215
2216 pTargetContext->Insert(PROP_WRITING_MODE, uno::Any( sal_Int16(nDirection) ) );
2217 }
2218 break; // sprmSTextFlow
2219 // the following are not part of the official documentation
2220 case NS_ooxml::LN_CT_Tabs_tab:
2221 resolveSprmProps(*this, rSprm);
2222 m_pImpl->IncorporateTabStop(m_pImpl->m_aCurrentTabStop);
2223 m_pImpl->m_aCurrentTabStop = DeletableTabStop();
2224 break;
2225 case NS_ooxml::LN_CT_PPrBase_tabs:
2226 {
2227 // Initialize tab stop vector from style sheet
2228 // fdo#81033: for RTF, a tab stop is inherited from the style if it
2229 // is also applied to the paragraph directly, and cleared if it is
2230 // not applied to the paragraph directly => don't InitTabStopFromStyle
2231 if ( !IsRTFImport() )
2232 {
2233 uno::Any aValue = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_TAB_STOPS);
2234 uno::Sequence< style::TabStop > aStyleTabStops;
2235 if(aValue >>= aStyleTabStops)
2236 {
2237 m_pImpl->InitTabStopFromStyle( aStyleTabStops );
2238 }
2239 }
2240 resolveSprmProps(*this, rSprm);
2241 rContext->Insert(PROP_PARA_TAB_STOPS, uno::Any( m_pImpl->GetCurrentTabStopAndClear()));
2242 }
2243 break;
2244
2245 case NS_ooxml::LN_CT_DocDefaults_pPrDefault:
2246 case NS_ooxml::LN_CT_DocDefaults_rPrDefault:
2247 GetStyleSheetTable()->sprm( rSprm );
2248 break;
2249 case NS_ooxml::LN_EG_RPrBase_bdr:
2250 {
2252 if( pProperties )
2253 {
2254 auto pBorderHandler = std::make_shared<BorderHandler>( true );
2255 pProperties->resolve(*pBorderHandler);
2256
2257 rContext->Insert( PROP_CHAR_TOP_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2258 rContext->Insert( PROP_CHAR_BOTTOM_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2259 rContext->Insert( PROP_CHAR_LEFT_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2260 rContext->Insert( PROP_CHAR_RIGHT_BORDER, uno::Any( pBorderHandler->getBorderLine()));
2261
2262 rContext->Insert( PROP_CHAR_TOP_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2263 rContext->Insert( PROP_CHAR_BOTTOM_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2264 rContext->Insert( PROP_CHAR_LEFT_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2265 rContext->Insert( PROP_CHAR_RIGHT_BORDER_DISTANCE, uno::Any( pBorderHandler->getLineDistance()));
2266
2267 auto xComplexColor = model::color::createXComplexColor(pBorderHandler->getComplexColor());
2268
2269 rContext->Insert( PROP_CHAR_BORDER_TOP_COMPLEX_COLOR, uno::Any(xComplexColor));
2270 rContext->Insert( PROP_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, uno::Any(xComplexColor));
2271 rContext->Insert( PROP_CHAR_BORDER_LEFT_COMPLEX_COLOR, uno::Any(xComplexColor));
2272 rContext->Insert( PROP_CHAR_BORDER_RIGHT_COMPLEX_COLOR, uno::Any(xComplexColor));
2273
2274 table::ShadowFormat aFormat;
2275 // Word only allows shadows on visible borders
2276 if ( pBorderHandler->getShadow() && pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE )
2277 aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine());
2278 rContext->Insert(PROP_CHAR_SHADOW_FORMAT, uno::Any(aFormat));
2279 }
2280 }
2281 break;
2282 case NS_ooxml::LN_EG_RPrBase_color:
2283 {
2285 if (pProperties)
2286 {
2287 auto pThemeColorHandler = std::make_shared<ThemeColorHandler>();
2288 pProperties->resolve(*pThemeColorHandler);
2289
2290 uno::Any aThemeColorName(TDefTableHandler::getThemeColorTypeString(pThemeColorHandler->mnIndex));
2291 uno::Any aThemeColorTint(OUString::number(pThemeColorHandler->mnTint, 16));
2292 uno::Any aThemeColorShade(OUString::number(pThemeColorHandler->mnShade, 16));
2293
2294 if (m_pImpl->GetTopContext())
2295 {
2296 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR, uno::Any(pThemeColorHandler->mnColor));
2297
2298 auto eType = TDefTableHandler::getThemeColorTypeIndex(pThemeColorHandler->mnIndex);
2300 {
2301
2302 model::ComplexColor aComplexColor;
2303 aComplexColor.setSchemeColor(eType);
2304
2305 auto eUsage = TDefTableHandler::getThemeColorUsage(pThemeColorHandler->mnIndex);
2306 aComplexColor.meThemeColorUsage = eUsage;
2307
2308 if (pThemeColorHandler->mnTint > 0 )
2309 {
2310 sal_Int16 nTint = sal_Int16((255 - pThemeColorHandler->mnTint) * 10000 / 255);
2311 aComplexColor.addTransformation({model::TransformationType::Tint, nTint});
2312 }
2313 if (pThemeColorHandler->mnShade > 0)
2314 {
2315 sal_Int16 nShade = sal_Int16((255 - pThemeColorHandler->mnShade) * 10000 / 255);
2316 aComplexColor.addTransformation({model::TransformationType::Shade, nShade});
2317 }
2318
2319 auto xComplexColor = model::color::createXComplexColor(aComplexColor);
2320 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMPLEX_COLOR, uno::Any(xComplexColor));
2321 }
2322
2323 uno::Any aColorAny(msfilter::util::ConvertColorOU(Color(ColorTransparency, pThemeColorHandler->mnColor)));
2324 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_ORIGINAL_COLOR, aColorAny, true, CHAR_GRAB_BAG);
2325
2326 if (pThemeColorHandler->mnIndex >= 0)
2327 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR, aThemeColorName, true, CHAR_GRAB_BAG);
2328
2329 if (pThemeColorHandler->mnTint > 0)
2330 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_TINT, aThemeColorTint, true, CHAR_GRAB_BAG);
2331
2332 if (pThemeColorHandler->mnShade > 0)
2333 m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_SHADE, aThemeColorShade, true, CHAR_GRAB_BAG);
2334 }
2335 {
2336 if (pThemeColorHandler->mnIndex >= 0)
2337 {
2338 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeColor", aThemeColorName.get<OUString>());
2339 if (pThemeColorHandler->mnTint > 0)
2340 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeTint", aThemeColorTint.get<OUString>());
2341 if (pThemeColorHandler->mnShade > 0)
2342 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeShade", aThemeColorShade.get<OUString>());
2343 }
2344 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "color", m_pImpl->m_aSubInteropGrabBag);
2345 }
2346 }
2347 }
2348 break;
2349 case NS_ooxml::LN_CT_PPr_sectPr:
2350 case NS_ooxml::LN_EG_RPrBase_rFonts:
2351 case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
2352 case NS_ooxml::LN_EG_RPrBase_u:
2353 case NS_ooxml::LN_EG_RPrBase_lang:
2354 case NS_ooxml::LN_CT_PPrBase_spacing:
2355 case NS_ooxml::LN_CT_PPrBase_ind:
2356 case NS_ooxml::LN_CT_RPrDefault_rPr:
2357 case NS_ooxml::LN_CT_PPrDefault_pPr:
2358 case NS_ooxml::LN_CT_Style_pPr:
2359 case NS_ooxml::LN_CT_Style_rPr:
2360 case NS_ooxml::LN_CT_PPr_rPr:
2361 case NS_ooxml::LN_CT_PPrBase_numPr:
2362 {
2363 if (nSprmId == NS_ooxml::LN_CT_PPr_sectPr)
2364 m_pImpl->SetParaSectpr(true);
2365 resolveSprmProps(*this, rSprm);
2366 if (nSprmId == NS_ooxml::LN_CT_PPrBase_spacing)
2367 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", m_pImpl->m_aSubInteropGrabBag);
2368 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_rFonts)
2369 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "rFonts", m_pImpl->m_aSubInteropGrabBag);
2370 else if (nSprmId == NS_ooxml::LN_EG_RPrBase_lang)
2371 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lang", m_pImpl->m_aSubInteropGrabBag);
2372 else if (nSprmId == NS_ooxml::LN_CT_PPrBase_ind)
2373 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ind", m_pImpl->m_aSubInteropGrabBag);
2374 }
2375 break;
2376 case NS_ooxml::LN_CT_PPrBase_wordWrap:
2377 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "wordWrap", "");
2378 break;
2379 case NS_ooxml::LN_EG_SectPrContents_footnotePr:
2380 case NS_ooxml::LN_EG_SectPrContents_endnotePr:
2381 m_pImpl->SetInFootnoteProperties( NS_ooxml::LN_EG_SectPrContents_footnotePr == nSprmId );
2382 resolveSprmProps(*this, rSprm);
2383 break;
2384 case NS_ooxml::LN_EG_SectPrContents_lnNumType:
2385 {
2386 resolveSprmProps(*this, rSprm);
2387 LineNumberSettings aSettings = m_pImpl->GetLineNumberSettings();
2388 m_pImpl->SetLineNumberSettings( aSettings );
2389 //apply settings at XLineNumberingProperties
2390 try
2391 {
2392 uno::Reference< text::XLineNumberingProperties > xLineNumberingProperties( m_pImpl->GetTextDocument(), uno::UNO_QUERY_THROW );
2393 uno::Reference< beans::XPropertySet > xLineNumberingPropSet = xLineNumberingProperties->getLineNumberingProperties();
2394 if( aSettings.nInterval == 0 )
2395 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::Any(false) );
2396 else
2397 {
2398 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::Any(true) );
2399 if( aSettings.nInterval )
2400 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_INTERVAL ), uno::Any(static_cast<sal_Int16>(aSettings.nInterval)) );
2401 if( aSettings.nDistance != -1 )
2402 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::Any(aSettings.nDistance) );
2403 else
2404 {
2405 // set Auto value (0.5 cm)
2406 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::Any(static_cast<sal_Int32>(500)) );
2407 if( pSectionContext )
2408 pSectionContext->SetdxaLnn( static_cast<sal_Int32>(283) );
2409 }
2410 xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_RESTART_AT_EACH_PAGE ), uno::Any(aSettings.bRestartAtEachPage) );
2411 }
2412 }
2413 catch( const uno::Exception& )
2414 {
2415 }
2416
2417 }
2418 break;
2419 case NS_ooxml::LN_CT_PPrBase_framePr:
2420 // Avoid frames if we're inside a structured document tag, would just cause outer tables fail to create.
2421 if (!m_pImpl->GetSdt())
2422 {
2423 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
2424 if( pContext )
2425 {
2426 // If there is a deferred page break applied to this framed paragraph,
2427 // create a dummy paragraph without extra properties,
2428 // so that the anchored frame will be on the correct page (similar to shapes).
2429 if (pContext->isSet(PROP_BREAK_TYPE))
2430 {
2431 pContext->Erase(PROP_BREAK_TYPE);
2432
2434 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
2436 sal_uInt8 const sBreak[] = { 0xd };
2437 lcl_text(sBreak, 1);
2440 }
2441
2442 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() );
2443 if (pParaContext)
2444 pParaContext->props().SetFrameMode();
2445
2446 if (!IsInHeaderFooter())
2447 m_pImpl->m_bIsActualParagraphFramed = true;
2448 }
2449 else
2450 {
2451 //TODO: What about style sheet import of frame properties
2452 }
2453 m_pImpl->NewFrameDirection();
2454 resolveSprmProps(*this, rSprm);
2455 }
2456 break;
2457 case NS_ooxml::LN_EG_SectPrContents_pgSz:
2458 {
2459 PaperInfo aLetter(PAPER_LETTER);
2460 CT_PageSz.w = aLetter.getWidth();
2461 CT_PageSz.h = aLetter.getHeight();
2462 }
2463 CT_PageSz.orient = false;
2464 resolveSprmProps(*this, rSprm);
2465 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2466 if(pSectionContext)
2467 {
2468 if (!m_pImpl->IsAltChunk())
2469 {
2470 pSectionContext->Insert(PROP_HEIGHT, uno::Any(CT_PageSz.h));
2471 }
2472 pSectionContext->Insert( PROP_IS_LANDSCAPE, uno::Any( CT_PageSz.orient ));
2473 if (!m_pImpl->IsAltChunk())
2474 {
2475 pSectionContext->Insert(PROP_WIDTH, uno::Any(CT_PageSz.w));
2476 }
2477 }
2478 break;
2479
2480 case NS_ooxml::LN_EG_SectPrContents_pgMar:
2481 m_pImpl->InitPageMargins();
2482 resolveSprmProps(*this, rSprm);
2483 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2484 if(pSectionContext)
2485 {
2486 const PageMar& rPageMar = m_pImpl->GetPageMargins();
2487 pSectionContext->SetTopMargin( rPageMar.top );
2488 pSectionContext->SetRightMargin( rPageMar.right );
2489 pSectionContext->SetBottomMargin( rPageMar.bottom );
2490 pSectionContext->SetLeftMargin( rPageMar.left );
2491 pSectionContext->SetHeaderTop( rPageMar.header );
2492 pSectionContext->SetHeaderBottom( rPageMar.footer );
2493 pSectionContext->SetGutterMargin(rPageMar.gutter);
2494 }
2495 break;
2496
2497 case NS_ooxml::LN_EG_SectPrContents_cols:
2498 {
2500 if( pProperties )
2501 {
2502
2504 pProperties->resolve(*pSectHdl);
2505 if(pSectionContext && !m_pImpl->isInIndexContext())
2506 {
2507 sal_Int16 nColumnCount = pSectHdl->GetNum() == 1 ? 0 : pSectHdl->GetNum();
2508 if( pSectHdl->IsEqualWidth() )
2509 {
2510 pSectionContext->SetEvenlySpaced( true );
2511 pSectionContext->SetColumnCount( nColumnCount );
2512 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2513 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2514 }
2515 else if( !pSectHdl->GetColumns().empty() )
2516 {
2517 pSectionContext->SetEvenlySpaced( false );
2518 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2519 nColumnCount = pSectHdl->GetColumns().size();
2520 pSectionContext->SetColumnCount( nColumnCount == 1 ? 0 : nColumnCount );
2521 std::vector<Column_>::const_iterator tmpIter = pSectHdl->GetColumns().begin();
2522 for (; tmpIter != pSectHdl->GetColumns().end(); ++tmpIter)
2523 {
2524 pSectionContext->AppendColumnWidth( tmpIter->nWidth );
2525 if ((tmpIter != pSectHdl->GetColumns().end() - 1) || (tmpIter->nSpace > 0))
2526 pSectionContext->AppendColumnSpacing( tmpIter->nSpace );
2527 }
2528 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2529 }
2530 else if( nColumnCount )
2531 {
2532 pSectionContext->SetColumnCount( nColumnCount );
2533 pSectionContext->SetColumnDistance( pSectHdl->GetSpace() );
2534 pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() );
2535 }
2536 }
2537
2538 else if ( pSectionContext )
2539 {
2540 FieldContextPtr pContext = m_pImpl->GetTopFieldContext();
2541 uno::Reference< beans::XPropertySet > xTOC = pContext->GetTOC();
2542 if( xTOC.is() )
2543 {
2545 xTOC->getPropertyValue(getPropertyName( PROP_TEXT_COLUMNS )) >>= xTextColumns;
2546 if (xTextColumns.is())
2547 {
2548 uno::Reference< beans::XPropertySet > xColumnPropSet( xTextColumns, uno::UNO_QUERY_THROW );
2549 xColumnPropSet->setPropertyValue( getPropertyName( PROP_AUTOMATIC_DISTANCE ), uno::Any( pSectHdl->GetSpace() ));
2550 xTOC->setPropertyValue( getPropertyName( PROP_TEXT_COLUMNS ), uno::Any( xTextColumns ) );
2551 }
2552 }
2553 }
2554 }
2555 }
2556 break;
2557 case NS_ooxml::LN_EG_SectPrContents_docGrid:
2558 resolveSprmProps(*this, rSprm);
2559 break;
2560 case NS_ooxml::LN_EG_SectPrContents_pgBorders:
2561 {
2563 if( pProperties && pSectionContext )
2564 {
2566 pProperties->resolve( *pHandler );
2567
2568 // Set the borders to the context and apply them to the styles
2569 pHandler->SetBorders( pSectionContext );
2570 }
2571 }
2572 break;
2573
2574 case NS_ooxml::LN_CT_PPrBase_snapToGrid:
2575 if (!IsStyleSheetImport()||!m_pImpl->isInteropGrabBagEnabled())
2576 {
2577 rContext->Insert( PROP_SNAP_TO_GRID, uno::Any(bool(nIntValue)));
2578 }
2579 else
2580 {
2581 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "snapToGrid", OUString::number(nIntValue));
2582 }
2583 break;
2584 case NS_ooxml::LN_CT_PPrBase_pStyle:
2585 {
2586 StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable();
2587 const OUString sConvertedStyleName = pStyleTable->ConvertStyleName( sStringValue, true );
2588 m_pImpl->SetCurrentParaStyleName( sConvertedStyleName );
2589 if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION)
2590 m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::Any( sConvertedStyleName ));
2591 }
2592 break;
2593 case NS_ooxml::LN_EG_RPrBase_rStyle:
2594 {
2595 OUString sConvertedName( m_pImpl->GetStyleSheetTable()->ConvertStyleName( sStringValue, true ) );
2596 if (m_pImpl->CheckFootnoteStyle() && m_pImpl->GetFootnoteContext())
2597 m_pImpl->SetHasFootnoteStyle(m_pImpl->GetFootnoteContext()->GetFootnoteStyle() == sConvertedName);
2598
2599 // First check if the style exists in the document.
2600 StyleSheetEntryPtr pEntry = m_pImpl->GetStyleSheetTable( )->FindStyleSheetByConvertedStyleName( sConvertedName );
2601 bool bExists = pEntry && ( pEntry->m_nStyleTypeCode == STYLE_TYPE_CHAR );
2602 // Add the property if the style exists, but do not add it elements in TOC:
2603 // they will receive later another style references from TOC
2604 if ( bExists && m_pImpl->GetTopContext() && !m_pImpl->IsInTOC())
2605 m_pImpl->GetTopContext()->Insert( PROP_CHAR_STYLE_NAME, uno::Any( sConvertedName ) );
2606 }
2607 break;
2608 case NS_ooxml::LN_CT_TblPrBase_tblCellMar: //cell margins
2609 {
2610 resolveSprmProps(*this, rSprm);//contains LN_CT_TblCellMar_top, LN_CT_TblCellMar_left, LN_CT_TblCellMar_bottom, LN_CT_TblCellMar_right
2611 }
2612 break;
2613 case NS_ooxml::LN_CT_TblCellMar_top:
2614 case NS_ooxml::LN_CT_TblCellMar_start:
2615 case NS_ooxml::LN_CT_TblCellMar_left:
2616 case NS_ooxml::LN_CT_TblCellMar_bottom:
2617 case NS_ooxml::LN_CT_TblCellMar_end:
2618 case NS_ooxml::LN_CT_TblCellMar_right:
2619 {
2621 if( pProperties )
2622 {
2623 MeasureHandlerPtr pMeasureHandler( new MeasureHandler );
2624 pProperties->resolve(*pMeasureHandler);
2625 sal_Int32 nMeasureValue = pMeasureHandler->getMeasureValue();
2627 bool rtl = false; // TODO
2628 switch(nSprmId)
2629 {
2630 case NS_ooxml::LN_CT_TblCellMar_top:
2631 break;
2632 case NS_ooxml::LN_CT_TblCellMar_start:
2634 break;
2635 case NS_ooxml::LN_CT_TblCellMar_left:
2637 break;
2638 case NS_ooxml::LN_CT_TblCellMar_bottom:
2640 break;
2641 case NS_ooxml::LN_CT_TblCellMar_end:
2643 break;
2644 case NS_ooxml::LN_CT_TblCellMar_right:
2646 break;
2647 default:;
2648 }
2649 rContext->Insert( eId, uno::Any(nMeasureValue), false);
2650 }
2651 }
2652 break;
2653 case NS_ooxml::LN_EG_RPrBase_noProof: // no grammar and spell checking, unsupported
2654 break;
2655 case NS_ooxml::LN_anchor_anchor: // at_character drawing
2656 case NS_ooxml::LN_inline_inline: // as_character drawing
2657 {
2658 if ( m_pImpl->IsDiscardHeaderFooter() )
2659 break;
2660 //tdf112342: Break before images as well, if there are page break
2661 if (m_pImpl->isBreakDeferred(BreakType::PAGE_BREAK)
2662 && nSprmId == NS_ooxml::LN_inline_inline && !m_pImpl->IsInShape())
2663 {
2664 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
2665 {
2666 m_pImpl->m_bIsSplitPara = true;
2669 }
2670 else
2671 {
2672 m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)
2673 ->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
2674 m_pImpl->clearDeferredBreak(PAGE_BREAK);
2675 }
2676 }
2677
2679 if( pProperties )
2680 {
2681 m_pImpl->m_eGraphicImportType =
2682 (NS_ooxml::LN_anchor_anchor ==
2683 sal::static_int_cast<Id>(nSprmId)) ?
2686 GraphicImportPtr pGraphicImport = m_pImpl->GetGraphicImport();
2687 pProperties->resolve(*pGraphicImport);
2688 m_pImpl->ImportGraphic(pProperties);
2689 if( !pGraphicImport->IsGraphic() )
2690 {
2691 m_pImpl->ResetGraphicImport();
2692 // todo: It's a shape, now start shape import
2693 }
2694 }
2695 }
2696 break;
2697 case NS_ooxml::LN_EG_RPrBase_vertAlign:
2698 {
2699 sal_Int16 nEscapement = 0;
2700 sal_Int8 nProp = DFLT_ESC_PROP;
2701 if ( sStringValue == "superscript" )
2702 nEscapement = DFLT_ESC_AUTO_SUPER;
2703 else if ( sStringValue == "subscript" )
2704 nEscapement = DFLT_ESC_AUTO_SUB;
2705 else
2706 nProp = 100;
2707
2708 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( nEscapement ) );
2709 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
2710 }
2711 break;
2712 case NS_ooxml::LN_CT_FtnProps_pos:
2713 //footnotes in word can be at page end or beneath text - writer supports only the first
2714 //endnotes in word can be at section end or document end - writer supports only the latter
2715 // -> so this property can be ignored
2716 break;
2717 case NS_ooxml::LN_CT_FtnProps_numFmt:
2718 case NS_ooxml::LN_CT_EdnProps_numFmt:
2719 {
2721 if (pProperties)
2722 {
2723 pProperties->resolve(*this);
2724 }
2725 }
2726 break;
2727 case NS_ooxml::LN_EG_FtnEdnNumProps_numStart:
2728 case NS_ooxml::LN_EG_FtnEdnNumProps_numRestart:
2729 {
2730 try
2731 {
2733 if( m_pImpl->IsInFootnoteProperties() )
2734 {
2735 uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2736 if (xFootnotesSupplier.is())
2737 xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings();
2738 }
2739 else
2740 {
2741 uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY );
2742 if (xEndnotesSupplier.is())
2743 xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings();
2744 }
2745 if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId && xFtnEdnSettings.is())
2746 {
2747 xFtnEdnSettings->setPropertyValue(
2749 uno::Any( sal_Int16( nIntValue - 1 )));
2750 }
2751 else if( NS_ooxml::LN_EG_FtnEdnNumProps_numRestart == nSprmId && xFtnEdnSettings.is())
2752 {
2753 sal_Int16 nFootnoteCounting = 0;
2754 switch (nIntValue)
2755 {
2756 case NS_ooxml::LN_Value_ST_RestartNumber_continuous: nFootnoteCounting = text::FootnoteNumbering::PER_DOCUMENT; break;
2757 case NS_ooxml::LN_Value_ST_RestartNumber_eachPage: nFootnoteCounting = text::FootnoteNumbering::PER_PAGE; break;
2758 case NS_ooxml::LN_Value_ST_RestartNumber_eachSect: nFootnoteCounting = text::FootnoteNumbering::PER_CHAPTER; break;
2759 default: break;
2760 }
2761 xFtnEdnSettings->setPropertyValue(
2763 uno::Any( nFootnoteCounting ));
2764 }
2765 else if (xFtnEdnSettings.is())
2766 {
2767 sal_Int16 nNumType = ConversionHelper::ConvertNumberingType( nIntValue );
2768 xFtnEdnSettings->setPropertyValue(
2770 uno::Any( nNumType ));
2771 }
2772 }
2773 catch( const uno::Exception& )
2774 {
2775 }
2776 }
2777 break;
2778 case NS_ooxml::LN_EG_RangeMarkupElements_moveFromRangeStart:
2779 m_pImpl->SetMoveBookmark(/*bIsFrom=*/true);
2780 if (m_pImpl->hasTableManager())
2781 m_pImpl->getTableManager().setMoved( getPropertyName(PROP_TABLE_ROW_DELETE) );
2782 break;
2783 case NS_ooxml::LN_EG_RangeMarkupElements_moveToRangeStart:
2784 m_pImpl->SetMoveBookmark(/*bIsFrom=*/false);
2785 if (m_pImpl->hasTableManager())
2786 m_pImpl->getTableManager().setMoved( getPropertyName(PROP_TABLE_ROW_INSERT) );
2787 break;
2788 case NS_ooxml::LN_EG_RangeMarkupElements_moveFromRangeEnd:
2789 case NS_ooxml::LN_EG_RangeMarkupElements_moveToRangeEnd:
2790 if (m_pImpl->hasTableManager())
2791 m_pImpl->getTableManager().setMoved( OUString() );
2792 break;
2793 case NS_ooxml::LN_CT_ParaRPr_moveFrom:
2794 case NS_ooxml::LN_CT_ParaRPr_moveTo:
2795 m_pImpl->StartParaMarkerMove( );
2796 break;
2797 case NS_ooxml::LN_paratrackchange:
2798 m_pImpl->StartParaMarkerChange( );
2799 [[fallthrough]];
2800 case NS_ooxml::LN_CT_PPr_pPrChange:
2801 case NS_ooxml::LN_CT_ParaRPr_rPrChange:
2802 case NS_ooxml::LN_trackchange:
2803 case NS_ooxml::LN_EG_RPrContent_rPrChange:
2804 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeStart:
2805 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeEnd:
2806 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeStart:
2807 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeEnd:
2808 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeStart:
2809 case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeEnd:
2810 {
2811 HandleRedline( rSprm );
2812 }
2813 break;
2814 case NS_ooxml::LN_endtrackchange:
2815 m_pImpl->RemoveTopRedline();
2816 break;
2817 case NS_ooxml::LN_CT_RPrChange_rPr:
2818 {
2819 // Push all the current 'Character' properties to the stack, so that we don't store them
2820 // as 'tracked changes' by mistake
2821 m_pImpl->PushProperties(CONTEXT_CHARACTER);
2822
2823 // Resolve all the properties that are under the 'rPrChange'->'rPr' XML node
2824 resolveSprmProps(*this, rSprm );
2825
2826 // Get all the properties that were processed in the 'rPrChange'->'rPr' XML node
2827 uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2828
2829 // Pop back out the character properties that were on the run
2830 m_pImpl->PopProperties(CONTEXT_CHARACTER);
2831
2832 // Store these properties in the current redline object (do it after the PopProperties() above, since
2833 // otherwise it'd be stored in the content dropped there).
2834 m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2835 }
2836 break;
2837 case NS_ooxml::LN_CT_PPrChange_pPr:
2838 {
2839 // Push all the current 'Paragraph' properties to the stack, so that we don't store them
2840 // as 'tracked changes' by mistake
2841 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
2842
2843 // Resolve all the properties that are under the 'pPrChange'->'pPr' XML node
2844 resolveSprmProps(*this, rSprm );
2845
2846 // Get all the properties that were processed in the 'pPrChange'->'pPr' XML node
2847 uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues();
2848
2849 // Pop back out the character properties that were on the run
2850 m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
2851
2852 // Store these properties in the current redline object (do it after the PopProperties() above, since
2853 // otherwise it'd be stored in the content dropped there).
2854 m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties );
2855 }
2856 break;
2857 case NS_ooxml::LN_object:
2858 {
2860 if( pProperties )
2861 {
2862 auto pOLEHandler = std::make_shared<OLEHandler>(*this);
2863 pProperties->resolve(*pOLEHandler);
2864 if ( pOLEHandler->isOLEObject( ) )
2865 {
2866 OUString sStreamName = pOLEHandler->copyOLEOStream( m_pImpl->GetTextDocument() );
2867 if( !sStreamName.isEmpty() )
2868 {
2869 m_pImpl->appendOLE( sStreamName, pOLEHandler );
2870 }
2871 }
2872 }
2873 }
2874 break;
2875 case NS_ooxml::LN_EG_HdrFtrReferences_headerReference: // header reference - not needed
2876 case NS_ooxml::LN_EG_HdrFtrReferences_footerReference: // footer reference - not needed
2877 break;
2878 case NS_ooxml::LN_EG_RPrBase_snapToGrid: // "Use document grid settings for inter-paragraph spacing"
2879 break;
2880 case NS_ooxml::LN_CT_PPrBase_contextualSpacing:
2881 rContext->Insert(PROP_PARA_CONTEXT_MARGIN, uno::Any( nIntValue != 0 ));
2882 break;
2883 case NS_ooxml::LN_CT_PPrBase_mirrorIndents: // mirrorIndents
2884 rContext->Insert(PROP_MIRROR_INDENTS, uno::Any( nIntValue != 0 ), true, PARA_GRAB_BAG);
2885 break;
2886 case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection
2887 {
2888 if( pSectionContext )
2889 pSectionContext->Insert( PROP_IS_PROTECTED, uno::Any( bool(nIntValue) ) );
2890 }
2891 break;
2892 case NS_ooxml::LN_EG_SectPrContents_vAlign:
2893 {
2894 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
2895 if( pSectionContext )
2896 {
2897 drawing::TextVerticalAdjust nVA = drawing::TextVerticalAdjust_TOP;
2898 switch( nIntValue )
2899 {
2900 case NS_ooxml::LN_Value_ST_VerticalJc_center: //92367
2901 nVA = drawing::TextVerticalAdjust_CENTER;
2902 break;
2903 case NS_ooxml::LN_Value_ST_VerticalJc_both: //92368 - justify
2904 nVA = drawing::TextVerticalAdjust_BLOCK;
2905 break;
2906 case NS_ooxml::LN_Value_ST_VerticalJc_bottom: //92369
2907 nVA = drawing::TextVerticalAdjust_BOTTOM;
2908 break;
2909 default:
2910 break;
2911 }
2912 pSectionContext->Insert( PROP_TEXT_VERTICAL_ADJUST, uno::Any( nVA ), true, PARA_GRAB_BAG );
2913 }
2914 }
2915 break;
2916 case NS_ooxml::LN_EG_RPrBase_fitText:
2917 break;
2918 case NS_ooxml::LN_ffdata:
2919 {
2921 if (pProperties)
2922 {
2923 FFDataHandler::Pointer_t pFFDataHandler(new FFDataHandler());
2924
2925 pProperties->resolve(*pFFDataHandler);
2926 m_pImpl->SetFieldFFData(pFFDataHandler);
2927 }
2928 }
2929 break;
2930 case NS_ooxml::LN_CT_SdtPr_comboBox:
2931 {
2932 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::comboBox);
2934 if (pProperties)
2935 pProperties->resolve(*this);
2936 }
2937 break;
2938 case NS_ooxml::LN_CT_SdtPr_dropDownList:
2939 {
2940 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::dropDown);
2942 if (pProperties)
2943 pProperties->resolve(*this);
2944 }
2945 break;
2946 case NS_ooxml::LN_CT_SdtDropDownList_listItem:
2947 {
2949
2950 size_t nDropDownDisplayTexts = m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().size();
2951 size_t nDropDownItems = m_pImpl->m_pSdtHelper->getDropDownItems().size();
2952
2953 if (pProperties)
2954 pProperties->resolve(*this);
2955
2956 if (m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().size() != nDropDownDisplayTexts + 1)
2957 {
2958 // w:displayText="..." is optional, add empty value if it was not provided.
2959 m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().push_back(OUString());
2960 }
2961 if (m_pImpl->m_pSdtHelper->getDropDownItems().size() != nDropDownItems + 1)
2962 {
2963 // w:value="..." is optional, add empty value if it was not provided.
2964 m_pImpl->m_pSdtHelper->getDropDownItems().push_back(OUString());
2965 }
2966 }
2967 break;
2968 case NS_ooxml::LN_CT_SdtPr_placeholder:
2969 {
2971 if (pProperties)
2972 pProperties->resolve(*this);
2973 }
2974 break;
2975 break;
2976 case NS_ooxml::LN_CT_SdtPr_date:
2977 {
2978 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::datePicker);
2979 resolveSprmProps(*this, rSprm);
2980 m_pImpl->m_pSdtHelper->setDateFieldStartRange(GetCurrentTextRange()->getEnd());
2981 }
2982 break;
2983 case NS_ooxml::LN_CT_SdtDate_dateFormat:
2984 {
2985 m_pImpl->m_pSdtHelper->getDateFormat().append(sStringValue);
2986 }
2987 break;
2988 case NS_ooxml::LN_CT_SdtDate_storeMappedDataAs:
2989 {
2990 }
2991 break;
2992 case NS_ooxml::LN_CT_SdtDate_calendar:
2993 {
2994 }
2995 break;
2996 case NS_ooxml::LN_CT_SdtDate_lid:
2997 {
2998 m_pImpl->m_pSdtHelper->getLocale().append(sStringValue);
2999 }
3000 break;
3001 case NS_ooxml::LN_CT_SdtPr_text:
3002 {
3003 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::plainText);
3004 if (m_pImpl->m_pSdtHelper->GetSdtType() == NS_ooxml::LN_CT_SdtRun_sdtContent)
3005 {
3006 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3007 break;
3008 }
3009 enableInteropGrabBag("ooxml:CT_SdtPr_text");
3011 if (pProperties)
3012 pProperties->resolve(*this);
3013 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
3014 m_pImpl->disableInteropGrabBag();
3015 }
3016 break;
3017 case NS_ooxml::LN_CT_SdtPr_dataBinding:
3018 case NS_ooxml::LN_CT_SdtPr_equation:
3019 case NS_ooxml::LN_CT_SdtPr_checkbox:
3020 case NS_ooxml::LN_CT_SdtPr_docPartObj:
3021 case NS_ooxml::LN_CT_SdtPr_docPartList:
3022 case NS_ooxml::LN_CT_SdtPr_picture:
3023 case NS_ooxml::LN_CT_SdtPr_citation:
3024 case NS_ooxml::LN_CT_SdtPr_group:
3025 case NS_ooxml::LN_CT_SdtPr_id:
3026 case NS_ooxml::LN_CT_SdtPr_alias:
3027 case NS_ooxml::LN_CT_SdtPlaceholder_docPart:
3028 case NS_ooxml::LN_CT_SdtPr_showingPlcHdr:
3029 case NS_ooxml::LN_CT_SdtPr_color:
3030 case NS_ooxml::LN_CT_SdtPr_appearance:
3031 case NS_ooxml::LN_CT_SdtPr_tag:
3032 case NS_ooxml::LN_CT_SdtPr_tabIndex:
3033 case NS_ooxml::LN_CT_SdtPr_lock:
3034 {
3035 if (!m_pImpl->GetSdtStarts().empty())
3036 {
3037 if (nSprmId == NS_ooxml::LN_CT_SdtPr_showingPlcHdr)
3038 {
3039 if (nIntValue)
3040 m_pImpl->m_pSdtHelper->SetShowingPlcHdr();
3041 }
3042
3043 if (nSprmId == NS_ooxml::LN_CT_SdtPr_color)
3044 {
3046 if (pProperties)
3047 {
3048 pProperties->resolve(*this);
3049 }
3050 break;
3051 }
3052
3053 if (nSprmId == NS_ooxml::LN_CT_SdtPr_appearance)
3054 {
3056 if (pProperties)
3057 {
3058 pProperties->resolve(*this);
3059 }
3060 break;
3061 }
3062
3063 if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias)
3064 {
3065 m_pImpl->m_pSdtHelper->SetAlias(sStringValue);
3066 break;
3067 }
3068
3069 if (nSprmId == NS_ooxml::LN_CT_SdtPr_tag)
3070 {
3071 m_pImpl->m_pSdtHelper->SetTag(sStringValue);
3072 break;
3073 }
3074
3075 if (nSprmId == NS_ooxml::LN_CT_SdtPr_id)
3076 {
3077 m_pImpl->m_pSdtHelper->SetId(nIntValue);
3078 break;
3079 }
3080
3081 if (nSprmId == NS_ooxml::LN_CT_SdtPr_tabIndex)
3082 {
3083 m_pImpl->m_pSdtHelper->SetTabIndex(nIntValue);
3084 break;
3085 }
3086
3087 if (nSprmId == NS_ooxml::LN_CT_SdtPr_lock)
3088 {
3089 m_pImpl->m_pSdtHelper->SetLock(sStringValue);
3090 break;
3091 }
3092
3093 if (nSprmId == NS_ooxml::LN_CT_SdtPr_checkbox)
3094 {
3095 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::checkBox);
3097 if (pProperties)
3098 {
3099 pProperties->resolve(*this);
3100 }
3101 break;
3102 }
3103 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_picture)
3104 {
3105 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::picture);
3107 if (pProperties)
3108 {
3109 pProperties->resolve(*this);
3110 }
3111 break;
3112 }
3113 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_date)
3114 {
3115 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::datePicker);
3117 if (pProperties)
3118 {
3119 pProperties->resolve(*this);
3120 }
3121 break;
3122 }
3123 }
3124
3125 // this is an unsupported SDT property, create a grab bag for it
3126 OUString sName;
3127 switch (nSprmId)
3128 {
3129 case NS_ooxml::LN_CT_SdtPr_dataBinding: sName = "ooxml:CT_SdtPr_dataBinding"; break;
3130 case NS_ooxml::LN_CT_SdtPr_equation: sName = "ooxml:CT_SdtPr_equation"; break;
3131 case NS_ooxml::LN_CT_SdtPr_checkbox: sName = "ooxml:CT_SdtPr_checkbox"; break;
3132 case NS_ooxml::LN_CT_SdtPr_docPartObj: sName = "ooxml:CT_SdtPr_docPartObj"; break;
3133 case NS_ooxml::LN_CT_SdtPr_docPartList: sName = "ooxml:CT_SdtPr_docPartList"; break;
3134 case NS_ooxml::LN_CT_SdtPr_picture: sName = "ooxml:CT_SdtPr_picture"; break;
3135 case NS_ooxml::LN_CT_SdtPr_citation: sName = "ooxml:CT_SdtPr_citation"; break;
3136 case NS_ooxml::LN_CT_SdtPr_group: sName = "ooxml:CT_SdtPr_group"; break;
3137 case NS_ooxml::LN_CT_SdtPr_id: sName = "ooxml:CT_SdtPr_id"; break;
3138 case NS_ooxml::LN_CT_SdtPr_alias: sName = "ooxml:CT_SdtPr_alias"; break;
3139 case NS_ooxml::LN_CT_SdtPr_tag: sName = "ooxml:CT_SdtPr_tag"; break;
3140 case NS_ooxml::LN_CT_SdtPr_tabIndex: sName = "ooxml:CT_SdtPr_tabIndex"; break;
3141 case NS_ooxml::LN_CT_SdtPr_lock: sName = "ooxml:CT_SdtPr_lock"; break;
3142 case NS_ooxml::LN_CT_SdtPlaceholder_docPart: sName = "ooxml:CT_SdtPlaceholder_docPart"; break;
3143 case NS_ooxml::LN_CT_SdtPr_showingPlcHdr: sName = "ooxml:CT_SdtPr_showingPlcHdr"; break;
3144 case NS_ooxml::LN_CT_SdtPr_color: sName = "ooxml:CT_SdtPr_color"; break;
3145 case NS_ooxml::LN_CT_SdtPr_appearance: sName = "ooxml:CT_SdtPr_appearance"; break;
3146 default: assert(false);
3147 };
3148 if (
3149 nSprmId == NS_ooxml::LN_CT_SdtPr_checkbox ||
3150 nSprmId == NS_ooxml::LN_CT_SdtPr_docPartObj ||
3151 nSprmId == NS_ooxml::LN_CT_SdtPr_docPartList ||
3152 nSprmId == NS_ooxml::LN_CT_SdtPr_picture ||
3153 nSprmId == NS_ooxml::LN_CT_SdtPr_citation)
3154 {
3155 m_pImpl->m_pSdtHelper->setControlType(SdtControlType::unsupported);
3156 }
3158
3159 // process subitems
3161 if (pProperties)
3162 pProperties->resolve(*this);
3163
3164 if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias || nSprmId == NS_ooxml::LN_CT_SdtPr_tag
3165 || nSprmId == NS_ooxml::LN_CT_SdtPr_lock)
3166 {
3167 // Grabbag string values
3168 beans::PropertyValue aValue;
3169 aValue.Name = sName;
3170 aValue.Value <<= sStringValue;
3171 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3172 }
3173 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_showingPlcHdr)
3174 {
3175 // Grabbag boolean values
3176 beans::PropertyValue aValue;
3177 aValue.Name = sName;
3178 aValue.Value <<= bool(nIntValue);
3179 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3180 }
3181 else if (nSprmId == NS_ooxml::LN_CT_SdtPr_id || nSprmId == NS_ooxml::LN_CT_SdtPr_tabIndex)
3182 {
3183 // Grabbag integer values
3184 beans::PropertyValue aValue;
3185 aValue.Name = sName;
3186 aValue.Value <<= nIntValue;
3187 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue);
3188 }
3189 else
3190 m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
3191 m_pImpl->m_pSdtHelper->setOutsideAParagraph(m_pImpl->IsOutsideAParagraph());
3192 m_pImpl->disableInteropGrabBag();
3193 }
3194 break;
3195 case NS_ooxml::LN_CT_SdtCheckbox_checked:
3196 if (!m_pImpl->GetSdtStarts().empty())
3197 {
3198 // nIntValue is not just 0 or 1, because we're in the w14 namespace's ST_OnOff.
3199 if (nIntValue == NS_ooxml::LN_ST_OnOff_true || nIntValue == NS_ooxml::LN_ST_OnOff_1)
3200 {
3201 m_pImpl->m_pSdtHelper->SetChecked();
3202 }
3203 }
3204 else
3205 {
3206 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checked",
3208 }
3209 break;
3210 case NS_ooxml::LN_CT_SdtCheckbox_checkedState:
3211 if (!m_pImpl->GetSdtStarts().empty())
3212 {
3213 m_pImpl->m_pSdtHelper->SetCheckedState(OUString(sal_Unicode(sStringValue.toInt32(16))));
3214 }
3215 else
3216 {
3217 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checkedState",
3218 sStringValue);
3219 }
3220 break;
3221 case NS_ooxml::LN_CT_SdtCheckbox_uncheckedState:
3222 if (!m_pImpl->GetSdtStarts().empty())
3223 {
3224 m_pImpl->m_pSdtHelper->SetUncheckedState(
3225 OUString(sal_Unicode(sStringValue.toInt32(16))));
3226 }
3227 else
3228 {
3229 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag,
3230 "ooxml:CT_SdtCheckbox_uncheckedState", sStringValue);
3231 }
3232 break;
3233 case NS_ooxml::LN_CT_SdtDocPart_docPartGallery:
3234 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartGallery", sStringValue);
3235 break;
3236 case NS_ooxml::LN_CT_SdtDocPart_docPartCategory:
3237 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartCategory", sStringValue);
3238 break;
3239 case NS_ooxml::LN_CT_SdtDocPart_docPartUnique:
3240 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartUnique", sStringValue);
3241 break;
3242 case NS_ooxml::LN_EG_SectPrContents_pgNumType:
3243 {
3245 if( pProperties )
3246 {
3247 pProperties->resolve(*this);
3248 }
3249 }
3250 break;
3251 case NS_ooxml::LN_tblStart:
3252 {
3253 if (m_pImpl->hasTableManager())
3254 {
3255 bool bTableStartsAtCellStart = m_pImpl->m_nTableDepth > 0 && m_pImpl->m_nTableCellDepth > m_pImpl->m_nLastTableCellParagraphDepth + 1;
3256 m_pImpl->getTableManager().setTableStartsAtCellStart(bTableStartsAtCellStart);
3257 }
3258 /*
3259 * Hack for Importing Section Properties
3260 * LO is not able to import section properties if first element in the
3261 * section is a table. So in case first element is a table add a dummy para
3262 * and remove it again when lcl_endSectionGroup is called
3263 */
3264 if(m_pImpl->m_nTableDepth == 0 && m_pImpl->GetIsFirstParagraphInSection()
3265 && !m_pImpl->GetIsDummyParaAddedForTableInSection() && !m_pImpl->GetIsTextFrameInserted()
3266 && !m_pImpl->GetIsPreviousParagraphFramed() && !IsInHeaderFooter())
3267 {
3268 m_pImpl->AddDummyParaForTableInSection();
3269 }
3270
3271 // if first paragraph style in table has break-before-page, transfer that setting to the table itself.
3272 if( m_pImpl->m_nTableDepth == 0 )
3273 {
3274 const uno::Any aBreakType(style::BreakType_PAGE_BEFORE);
3275 const PropertyMapPtr pParagraphProps = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3276 if( pParagraphProps && pParagraphProps->isSet(PROP_PARA_STYLE_NAME) )
3277 {
3278 StyleSheetEntryPtr pStyle;
3279 OUString sStyleName;
3280 pParagraphProps->getProperty(PROP_PARA_STYLE_NAME)->second >>= sStyleName;
3281 if( !sStyleName.isEmpty() && GetStyleSheetTable() )
3282 pStyle = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( sStyleName );
3283
3284 if( pStyle && pStyle->m_pProperties
3285 && pStyle->m_pProperties->isSet(PROP_BREAK_TYPE)
3286 && pStyle->m_pProperties->getProperty(PROP_BREAK_TYPE)->second == aBreakType )
3287 {
3288 pParagraphProps->Insert(PROP_BREAK_TYPE, aBreakType);
3289 }
3290 }
3291 }
3292
3293 m_pImpl->m_nTableDepth++;
3294 }
3295 break;
3296 case NS_ooxml::LN_tblEnd:
3297 m_pImpl->m_nTableDepth--;
3298 break;
3299 case NS_ooxml::LN_tcStart:
3300 m_pImpl->m_nTableCellDepth++;
3301 break;
3302 case NS_ooxml::LN_tcEnd:
3303 m_pImpl->m_nTableCellDepth--;
3304 m_pImpl->m_nLastTableCellParagraphDepth = 0;
3305 break;
3306 case NS_ooxml::LN_glow_glow:
3307 case NS_ooxml::LN_shadow_shadow:
3308 case NS_ooxml::LN_reflection_reflection:
3309 case NS_ooxml::LN_textOutline_textOutline:
3310 case NS_ooxml::LN_textFill_textFill:
3311 case NS_ooxml::LN_scene3d_scene3d:
3312 case NS_ooxml::LN_props3d_props3d:
3313 case NS_ooxml::LN_ligatures_ligatures:
3314 case NS_ooxml::LN_numForm_numForm:
3315 case NS_ooxml::LN_numSpacing_numSpacing:
3316 case NS_ooxml::LN_stylisticSets_stylisticSets:
3317 case NS_ooxml::LN_cntxtAlts_cntxtAlts:
3318 {
3319 tools::SvRef<TextEffectsHandler> pTextEffectsHandlerPtr( new TextEffectsHandler(nSprmId) );
3320 std::optional<PropertyIds> aPropertyId = pTextEffectsHandlerPtr->getGrabBagPropertyId();
3321 if(aPropertyId)
3322 {
3324 if( pProperties )
3325 {
3326 pProperties->resolve(*pTextEffectsHandlerPtr);
3327
3328 beans::PropertyValue aGrabBag = pTextEffectsHandlerPtr->getInteropGrabBag();
3329 rContext->Insert(*aPropertyId, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
3330
3331 sal_Int16 nTransparency = TextEffectsHandler::GetTextFillSolidFillAlpha(aGrabBag);
3332 if (nTransparency != 0)
3333 {
3334 rContext->Insert(PROP_CHAR_TRANSPARENCE, uno::Any(nTransparency));
3335 }
3336 }
3337 else if (nSprmId == NS_ooxml::LN_cntxtAlts_cntxtAlts)
3338 {
3339 pTextEffectsHandlerPtr->lcl_sprm(rSprm);
3340 beans::PropertyValue aGrabBag = pTextEffectsHandlerPtr->getInteropGrabBag();
3341 rContext->Insert(*aPropertyId, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
3342 }
3343 }
3344 }
3345 break;
3346 case NS_ooxml::LN_CT_SdtPr_rPr:
3347 {
3348 // Make sure properties from a previous SDT are not merged with the current ones.
3349 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
3350 }
3351 break;
3352 case NS_ooxml::LN_CT_TblPrBase_tblLook:
3353 {
3355 if (pProperties)
3356 {
3357 pProperties->resolve(*this);
3358 m_pImpl->getTableManager().finishTableLook();
3359 }
3360 }
3361 break;
3362 case NS_ooxml::LN_CT_TrPrBase_cnfStyle:
3363 {
3364 m_pImpl->enableInteropGrabBag("cnfStyle");
3365 resolveSprmProps(*this, rSprm);
3366
3367 TablePropertyMapPtr pPropMap(new TablePropertyMap());
3368 pPropMap->Insert(PROP_ROW_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, ROW_GRAB_BAG);
3369 m_pImpl->getTableManager().insertRowProps(pPropMap);
3370
3371 m_pImpl->disableInteropGrabBag();
3372 }
3373 break;
3374 case NS_ooxml::LN_CT_TcPrBase_cnfStyle:
3375 {
3376 m_pImpl->enableInteropGrabBag("cnfStyle");
3377 resolveSprmProps(*this, rSprm);
3378
3379 TablePropertyMapPtr pPropMap(new TablePropertyMap());
3380 pPropMap->Insert(PROP_CELL_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, CELL_GRAB_BAG);
3381 m_pImpl->getTableManager().cellProps(pPropMap);
3382
3383 m_pImpl->disableInteropGrabBag();
3384 }
3385 break;
3386 case NS_ooxml::LN_CT_PPrBase_cnfStyle:
3387 {
3388 m_pImpl->enableInteropGrabBag("cnfStyle");
3389 resolveSprmProps(*this, rSprm);
3390 rContext->Insert(PROP_PARA_CNF_STYLE, uno::Any(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, PARA_GRAB_BAG);
3391 m_pImpl->disableInteropGrabBag();
3392 }
3393 break;
3394 case NS_ooxml::LN_EG_RunInnerContent_sym:
3395 {
3396 resolveSprmProps(*this, rSprm);
3397 SymbolData aSymbolData = m_pImpl->GetSymbolData();
3398 uno::Any aVal( aSymbolData.sFont );
3399 auto xFootnote = rContext->GetFootnote();
3400 if (!xFootnote.is() && m_pImpl->IsInCustomFootnote())
3401 xFootnote = m_pImpl->GetFootnoteContext()->GetFootnote();
3402 if (xFootnote.is())
3403 {
3404 // DOCX can have different labels for the footnote reference and the footnote area.
3405 // This skips the one from the footnote area and just uses the reference one.
3406 if (!m_pImpl->IsInFootOrEndnote())
3407 {
3408 auto xAnchorRange = xFootnote->getAnchor();
3409 auto xAnchorCursor(xAnchorRange->getText()->createTextCursorByRange(xAnchorRange));
3410
3411 // append a dummy character, so the following properties will be set as
3412 // as SwpHints::SwTextAttr instead of the SwAttrSet of the paragraph,
3413 // which would be removed by SwXText::Impl::finishOrAppendParagraph
3414 xAnchorCursor->collapseToEnd();
3415 uno::Reference<text::XTextRange> xHackRange(xAnchorCursor, uno::UNO_QUERY);
3416 xHackRange->setString("x");
3417
3418 uno::Reference<beans::XPropertySet> xAnchorProps(xAnchorRange, uno::UNO_QUERY);
3419 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), aVal);
3420 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_ASIAN), aVal);
3421 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_COMPLEX), aVal);
3422 xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_CHAR_SET), uno::Any(awt::CharSet::SYMBOL));
3423
3424 // remove the dummy char
3425 xHackRange->setString("");
3426
3427 OUString sLabel = xFootnote->getLabel() + OUStringChar(aSymbolData.cSymbol);
3428 xFootnote->setLabel(sLabel);
3429 }
3430 }
3431 else //it's a _real_ symbol
3432 {
3433 rContext->Insert(PROP_CHAR_FONT_NAME, aVal);
3434 rContext->Insert(PROP_CHAR_FONT_NAME_ASIAN, aVal);
3435 rContext->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aVal);
3436 rContext->Insert(PROP_CHAR_FONT_CHAR_SET, uno::Any(awt::CharSet::SYMBOL));
3437 utext( reinterpret_cast < const sal_uInt8 * >( &(aSymbolData.cSymbol) ), 1 );
3438 }
3439 }
3440 break;
3441 case NS_ooxml::LN_EG_RunInnerContent_ruby:
3442 {
3443 RubyInfo aInfo ;
3444 m_pImpl->SetRubyInfo(aInfo);
3445 }
3446 break;
3447 case NS_ooxml::LN_CT_RubyPr:
3448 case NS_ooxml::LN_CT_Ruby_rt:
3449 case NS_ooxml::LN_CT_Ruby_rubyBase:
3450 {
3451 m_pImpl->SetRubySprmId(nSprmId);
3452 if (nSprmId == NS_ooxml::LN_CT_RubyPr)
3453 {
3454 resolveSprmProps(*this, rSprm);
3455 }
3456 }
3457 break;
3458 case NS_ooxml::LN_EG_RubyContent_r:
3459 {
3460 const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
3461 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase)
3462 {
3463 rContext->Insert(PROP_RUBY_TEXT, uno::Any(aInfo.sRubyText));
3464 rContext->Insert(PROP_RUBY_STYLE, uno::Any(aInfo.sRubyStyle));
3465 rContext->Insert(PROP_RUBY_ADJUST, uno::Any(static_cast<sal_Int16>(ConversionHelper::convertRubyAlign(aInfo.nRubyAlign))));
3466 if ( aInfo.nRubyAlign == NS_ooxml::LN_Value_ST_RubyAlign_rightVertical )
3467 rContext->Insert(PROP_RUBY_POSITION, uno::Any(css::text::RubyPosition::INTER_CHARACTER));
3468
3469 m_pImpl->SetRubySprmId(0);
3470 }
3471 }
3472 break;
3473 case NS_ooxml::LN_CT_RubyPr_rubyAlign:
3474 case NS_ooxml::LN_CT_RubyPr_hps:
3475 case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
3476 {
3477 RubyInfo aInfo = m_pImpl->GetRubyInfo();
3478 switch(nSprmId)
3479 {
3480 case NS_ooxml::LN_CT_RubyPr_rubyAlign:
3481 aInfo.nRubyAlign = nIntValue;
3482 break;
3483 case NS_ooxml::LN_CT_RubyPr_hps:
3484 aInfo.nHps= nIntValue;
3485 break;
3486 case NS_ooxml::LN_CT_RubyPr_hpsBaseText:
3487 aInfo.nHpsBaseText = nIntValue;
3488 break;
3489 }
3490 m_pImpl->SetRubyInfo(aInfo);
3491 }
3492 break;
3493 case NS_ooxml::LN_CT_SmartTagRun_smartTagPr:
3494 {
3496 if (pProperties && m_pImpl->GetTopContextType() == CONTEXT_PARAGRAPH)
3497 pProperties->resolve(m_pImpl->getSmartTagHandler());
3498 }
3499 break;
3500 case NS_ooxml::LN_CT_DocPartPr_name:
3501 {
3503 if (pProperties)
3504 pProperties->resolve(*this);
3505 }
3506 break;
3507 case NS_ooxml::LN_CT_DocPartPr_category:
3508 {
3510 if (pProperties)
3511 pProperties->resolve(*this);
3512 }
3513 break;
3514 case NS_ooxml::LN_CT_DocPartCategory_gallery:
3515 {
3517 if (pProperties)
3518 pProperties->resolve(*this);
3519 }
3520 break;
3521 case NS_ooxml::LN_EG_RunInnerContent_instrText:
3522 {
3523 m_pImpl->SetIsTextDeleted(false);
3524 }
3525 break;
3526 case NS_ooxml::LN_EG_RunInnerContent_delText:
3527 case NS_ooxml::LN_EG_RunInnerContent_delInstrText:
3528 {
3529 m_pImpl->SetIsTextDeleted(true);
3530 }
3531 break;
3532 default:
3533 {
3534#ifdef DBG_UTIL
3535 TagLogger::getInstance().startElement("unhandled");
3536 TagLogger::getInstance().attribute("id", nSprmId);
3537 TagLogger::getInstance().attribute("name", rSprm.getName());
3539#endif
3540 }
3541 }
3542}
3543
3545{
3546 assert(m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET);
3547 m_pImpl->processDeferredCharacterProperties(false);
3548}
3549
3551 const std::map<sal_Int32, uno::Any>& deferredCharacterProperties, bool bCharContext)
3552{
3553 if (bCharContext)
3554 {
3555 assert(m_pImpl->GetTopContextType() == CONTEXT_CHARACTER);
3556 }
3557 PropertyMapPtr rContext = m_pImpl->GetTopContext();
3558 for( const auto& rProp : deferredCharacterProperties )
3559 {
3560 sal_Int32 Id = rProp.first;
3561 sal_Int32 nIntValue = 0;
3562 OUString sStringValue;
3563 rProp.second >>= nIntValue;
3564 rProp.second >>= sStringValue;
3565 switch( Id )
3566 {
3567 case NS_ooxml::LN_EG_RPrBase_position:
3568 {
3569 double nEscapement = 0;
3570 sal_Int8 nProp = 0;
3571 if ( nIntValue )
3572 {
3573 nProp = 100;
3574 double fFontSize = 0;
3575 m_pImpl->GetAnyProperty(PROP_CHAR_HEIGHT, rContext) >>= fFontSize;
3576 if ( fFontSize )
3577 // nIntValue is in half-points, fontsize is in points, escapement is a percentage.
3578 nEscapement = round( nIntValue/2.0 / fFontSize * 100 );
3579 else
3580 nEscapement = nIntValue > 0 ? DFLT_ESC_SUPER : DFLT_ESC_SUB;
3581 }
3582 if ( nEscapement > MAX_ESC_POS )
3583 nEscapement = MAX_ESC_POS;
3584 else if ( nEscapement < -MAX_ESC_POS )
3585 nEscapement = -MAX_ESC_POS;
3586
3587 rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::Any( sal_Int16(nEscapement) ) );
3588 rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::Any( nProp ) );
3589 }
3590 break;
3591 default:
3592 SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" );
3593 break;
3594 }
3595 }
3596}
3597
3599{
3600 ref->resolve(*this);
3601}
3602
3603void DomainMapper::data(const sal_uInt8* /*buf*/, size_t /*len*/)
3604{
3605}
3606
3608{
3609 if (!m_pImpl->isInIndexContext() && !m_pImpl->isInBibliographyContext())
3610 {
3611 m_pImpl->PushProperties(CONTEXT_SECTION);
3612 }
3613 m_pImpl->SetIsFirstParagraphInSection(true);
3614 m_pImpl->SetIsFirstParagraphInSectionAfterRedline(true);
3615}
3616
3618{
3619 if (m_pImpl->isInIndexContext() || m_pImpl->isInBibliographyContext())
3620 return;
3621
3622 m_pImpl->CheckUnregisteredFrameConversion();
3623 m_pImpl->ExecuteFrameConversion();
3624 // When pasting, it's fine to not have any paragraph inside the document at all.
3625 if (m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->IsNewDoc())
3626 {
3627 // This section has no paragraph at all (e.g. they are all actually in a frame).
3628 // If this section has a page break, there would be nothing to apply to the page
3629 // style, so force a dummy paragraph.
3632 sal_uInt8 const sBreak[] = { 0xd };
3633 lcl_text(sBreak, 1);
3636 }
3637 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_SECTION);
3638 SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
3639 OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
3640 if(pSectionContext)
3641 {
3642 pSectionContext->CloseSectionGroup( *m_pImpl );
3643 // Remove the dummy paragraph if added for
3644 // handling the section properties if section starts with a table
3645 // tdf#135786: Added annotation condition
3646 if (m_pImpl->GetIsDummyParaAddedForTableInSection() && (m_pImpl->GetAnnotationId() < 0))
3647 m_pImpl->RemoveDummyParaForTableInSection();
3648 }
3649 m_pImpl->SetIsTextFrameInserted( false );
3650 m_pImpl->PopProperties(CONTEXT_SECTION);
3651}
3652
3654{
3655 if (m_pImpl->hasTableManager())
3656 m_pImpl->getTableManager().startParagraphGroup();
3657 /*
3658 * Add new para properties only if paragraph is not split
3659 * or the top context is not of paragraph properties
3660 * Set mbIsSplitPara to false as it has been handled
3661 */
3662 if (!mbIsSplitPara)
3663 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
3664 mbIsSplitPara = false;
3665 if (m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) != m_pImpl->GetTopContext())
3666 m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
3667
3668 if (!m_pImpl->IsInShape() && !m_pImpl->IsInComments())
3669 {
3670 if (m_pImpl->GetTopContext())
3671 {
3672 const OUString& sDefaultParaStyle = m_pImpl->GetDefaultParaStyleName();
3673 auto pContext = static_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContext().get());
3674 m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::Any( sDefaultParaStyle ) );
3675 m_pImpl->SetCurrentParaStyleName( sDefaultParaStyle );
3676
3677 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3678 {
3679 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
3680
3681 // With a w:br at the start of a paragraph, compat14 apparently doesn't apply.
3682 // It works to insert a zero margin before importing paragraph properties because
3683 // TopMargin typically imports without overwrite any existing value. Very handy.
3684 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
3685 }
3686 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3687 {
3688 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
3689
3690 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
3691 {
3692 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
3693 }
3694 }
3695
3696 mbWasShapeInPara = false;
3697 }
3698 m_pImpl->clearDeferredBreaks();
3699 }
3700
3701 if (m_pImpl->isParaSdtEndDeferred() && m_pImpl->GetTopContext())
3702 m_pImpl->GetTopContext()->Insert(PROP_PARA_SDT_END_BEFORE, uno::Any(true), true, PARA_GRAB_BAG);
3703 m_pImpl->setParaSdtEndDeferred(false);
3704
3705 m_pImpl->SetIsFirstRun(true);
3706 m_pImpl->SetIsOutsideAParagraph(false);
3707}
3708
3710{
3711 if (m_pImpl->isBreakDeferred(LINE_BREAK))
3712 {
3713 if (m_pImpl->GetIsLastParagraphInSection())
3714 m_pImpl->clearDeferredBreak(LINE_BREAK);
3715
3716 while (m_pImpl->isBreakDeferred(LINE_BREAK))
3717 {
3718 m_pImpl->clearDeferredBreak(LINE_BREAK);
3719 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
3720 }
3721 }
3722
3723 m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
3724 if (m_pImpl->hasTableManager())
3725 m_pImpl->getTableManager().endParagraphGroup();
3726 //frame conversion has to be executed after table conversion
3727 m_pImpl->ExecuteFrameConversion();
3728 m_pImpl->SetIsOutsideAParagraph(true);
3729}
3730
3732{
3733 m_pImpl->SetIsLastParagraphInSection( true );
3734}
3735
3737{
3738 m_pImpl->SetIsLastSectionGroup( true );
3739}
3740
3742{
3743 assert(xShape.is());
3744
3745 m_pImpl->AttachTextBoxContentToShape(xShape);
3746 if (m_pImpl->GetTopContext())
3747 {
3748 // If there is a deferred page break, handle it now, so that the
3749 // started shape will be on the correct page.
3750 if (m_pImpl->isBreakDeferred(PAGE_BREAK) && !m_pImpl->IsBreakDeferredByAnchor())
3751 {
3752 // RTF doesn't properly report IsFirstRun, so in order to prevent regressions
3753 // always split the paragraph for RTF since that is the way it has been done lately.
3754 if (!m_pImpl->IsFirstRun() || IsRTFImport())
3755 {
3756 m_pImpl->m_bIsSplitPara = true;
3759 }
3760 else
3761 m_pImpl->SetIsBreakDeferredByAnchor();
3762
3763 }
3764 m_pImpl->PushShapeContext( xShape );
3766 }
3767 else
3768 {
3769 // No context? Then this image should not appear directly inside the
3770 // document, just save it for later usage.
3771 m_pImpl->PushPendingShape(xShape);
3772 }
3773
3774 m_pImpl->SetIsFirstParagraphInShape(true);
3775 mbWasShapeInPara = true;
3776}
3777
3779{
3780 if (!m_pImpl->GetTopContext())
3781 return;
3782
3783 // End the current table, if there are any. Otherwise the unavoidable
3784 // empty paragraph at the end of the shape text will cause problems: if
3785 // the shape text ends with a table, the extra paragraph will be
3786 // handled as an additional row of the ending table.
3787 if (m_pImpl->hasTableManager())
3788 m_pImpl->getTableManager().endTable();
3789
3791 m_pImpl->PopShapeContext( );
3792 // A shape is always inside a paragraph (anchored or inline).
3793 m_pImpl->SetIsOutsideAParagraph(false);
3794}
3795
3797{
3798 m_pImpl->PushTextBoxContent();
3799}
3800
3802{
3803 m_pImpl->PopTextBoxContent();
3804}
3805
3806void DomainMapper::PushStyleSheetProperties( const PropertyMapPtr& pStyleProperties, bool bAffectTableMngr )
3807{
3808 m_pImpl->PushStyleProperties( pStyleProperties );
3809 if ( bAffectTableMngr )
3810 m_pImpl->getTableManager( ).SetStyleProperties( pStyleProperties );
3811}
3812
3813void DomainMapper::PopStyleSheetProperties( bool bAffectTableMngr )
3814{
3815 m_pImpl->PopProperties( CONTEXT_STYLESHEET );
3816 if ( bAffectTableMngr )
3817 {
3818 PropertyMapPtr emptyPtr;
3819 m_pImpl->getTableManager( ).SetStyleProperties( emptyPtr );
3820 }
3821}
3822
3823void DomainMapper::PushListProperties( const ::tools::SvRef<PropertyMap>& pListProperties )
3824{
3825 m_pImpl->PushListProperties( pListProperties );
3826}
3827
3829{
3830 m_pImpl->PopProperties( CONTEXT_LIST );
3831}
3832
3834{
3835 m_pImpl->PushProperties(CONTEXT_CHARACTER);
3836 if (m_pImpl->isSdtEndDeferred())
3837 {
3838 // Fields have an empty character group before the real one, so don't
3839 // call setSdtEndDeferred(false) here, that will happen only in lcl_utext().
3840 m_pImpl->GetTopContext()->Insert(PROP_SDT_END_BEFORE, uno::Any(true), true, CHAR_GRAB_BAG);
3841 }
3842}
3843
3845{
3846 if (m_pImpl->CheckFootnoteStyle())
3847 {
3848 m_pImpl->SetCheckFootnoteStyle(m_pImpl->IsInCustomFootnote());
3849 m_pImpl->SetHasFootnoteStyle(false);
3850 }
3851 m_pImpl->PopProperties(CONTEXT_CHARACTER);
3852}
3853
3854void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
3855{
3856 //TODO: Determine the right text encoding (FIB?)
3857 OUString sText( reinterpret_cast<const char*>(data_), len, RTL_TEXTENCODING_MS_1252 );
3858#ifdef DBG_UTIL
3862#endif
3863
3864 try
3865 {
3866 if(len == 1)
3867 {
3868 switch(*data_)
3869 {
3870 case 0x02: return; //footnote character
3871 case 0x08: // Lock field if in field context
3872 if (m_pImpl->IsOpenField())
3873 m_pImpl->SetFieldLocked();
3874 return;
3875 case 0x0c: //page break
3876 // page breaks aren't supported in footnotes and endnotes
3877 if (!m_pImpl->IsInFootOrEndnote())
3878 {
3879 m_pImpl->deferBreak(PAGE_BREAK);
3880 m_pImpl->SetIsDummyParaAddedForTableInSectionPage(false);
3881 }
3882 return;
3883 case 0x0e: //column break
3884 m_pImpl->deferBreak(COLUMN_BREAK);
3885 return;
3886 case 0x0a: //line break
3887 if (m_pImpl->GetIsLastParagraphInSection())
3888 {
3889 m_pImpl->deferBreak(LINE_BREAK);
3890 return;
3891 }
3892 break;
3893 case 0x07:
3894 m_pImpl->getTableManager().text(data_, len);
3895 return;
3896 case 0x0d:
3897 {
3898 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
3899 if (pContext && m_pImpl->isBreakDeferred(COLUMN_BREAK))
3900 {
3901 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
3902 m_pImpl->clearDeferredBreak(COLUMN_BREAK);
3903 }
3905 return;
3906 }
3907 case cFieldStart:
3908 m_pImpl->PushFieldContext();
3909 return;
3910 case cFieldSep:
3911 // delimiter not necessarily available
3912 // appears only if field contains further content
3913 m_pImpl->CloseFieldCommand();
3914 return;
3915 case cFieldEnd:
3916 m_pImpl->PopFieldContext();
3917 return;
3918 default:
3919 break;
3920 }
3921 }
3922
3923 // GetTopContext() is changed by inserted breaks, but we want to keep the current context
3924 PropertyMapPtr pContext = m_pImpl->GetTopContext();
3925
3926 while (m_pImpl->isBreakDeferred(LINE_BREAK))
3927 {
3928 m_pImpl->clearDeferredBreak(LINE_BREAK);
3929 m_pImpl->appendTextPortion("\n", pContext);
3930 }
3931
3932 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
3933 {
3934 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
3935 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
3936 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
3937 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
3938 m_pImpl->clearDeferredBreaks();
3939 }
3940
3941 if (pContext && pContext->GetFootnote().is() && m_pImpl->IsInCustomFootnote())
3942 {
3943 pContext->GetFootnote()->setLabel(sText);
3944 m_pImpl->EndCustomFootnote();
3945 //otherwise ignore sText
3946 }
3947 else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields())
3948 {
3949 m_pImpl->AppendFieldCommand(sText);
3950 }
3951 else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
3952 /*depending on the success of the field insert operation this result will be
3953 set at the field or directly inserted into the text*/
3954 m_pImpl->AppendFieldResult(sText);
3955 else
3956 {
3957 if (pContext == nullptr)
3958 pContext = new PropertyMap();
3959
3960 if (sText == "\n")
3961 {
3962 m_pImpl->HandleLineBreak(pContext);
3963 }
3964 else
3965 {
3966 m_pImpl->appendTextPortion(sText, pContext);
3967 }
3968 }
3969 }
3970 catch( const uno::RuntimeException& )
3971 {
3972 TOOLS_WARN_EXCEPTION("writerfilter", "");
3973 }
3974}
3975
3976void DomainMapper::lcl_positionOffset(const OUString& rText, bool bVertical)
3977{
3978 if (bVertical)
3979 m_pImpl->m_aPositionOffsets.second = rText;
3980 else
3981 m_pImpl->m_aPositionOffsets.first = rText;
3982}
3983
3985{
3986 awt::Point aRet;
3987 aRet.X = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.first.toInt32());
3988 aRet.Y = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.second.toInt32());
3989 return aRet;
3990}
3991
3992void DomainMapper::lcl_align(const OUString& rText, bool bVertical)
3993{
3994 if (bVertical)
3995 m_pImpl->m_aAligns.second = rText;
3996 else
3997 m_pImpl->m_aAligns.first = rText;
3998}
3999
4000void DomainMapper::lcl_positivePercentage(const OUString& rText)
4001{
4002 m_pImpl->m_aPositivePercentages.push(rText);
4003}
4004
4005void DomainMapper::lcl_checkId(const sal_Int32 nId)
4006{
4007 if (m_pImpl->IsInFootnote())
4008 {
4009 m_pImpl->m_aFootnoteIds.push_back(nId);
4010 // keep only the first real footnote
4011 if (m_pImpl->GetFootnoteCount() == -1 && m_pImpl->m_aFootnoteIds.size() == 2)
4012 m_pImpl->m_aFootnoteIds.pop_front();
4013 }
4014 else
4015 {
4016 m_pImpl->m_aEndnoteIds.push_back(nId);
4017 // keep only the first real endnote
4018 if (m_pImpl->GetEndnoteCount() == -1 && m_pImpl->m_aEndnoteIds.size() == 2)
4019 m_pImpl->m_aEndnoteIds.pop_front();
4020 }
4021}
4022
4023void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
4024{
4025 // All these fixed values are defined as static const sal_Unicode codepoints in the fast parser,
4026 // like uFtnEdnRef = 0x2, uFtnEdnSep = 0x3, ... and have a len of 1, if they aren't valid unicode.
4027
4028 OUString sText(reinterpret_cast<const sal_Unicode *>(data_), len);
4029 const RubyInfo & aInfo = m_pImpl->GetRubyInfo();
4030 if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt)
4031 {
4032 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4033 PropertyValueVector_t aProps = comphelper::sequenceToContainer< PropertyValueVector_t >(pContext->GetPropertyValues());
4034 OUString sStyle = getOrCreateCharStyle(aProps, /*bAlwaysCreate=*/false);
4035 m_pImpl->SetRubyText(sText,sStyle);
4036 return;
4037 }
4038
4039 if (len == 1)
4040 {
4041 // preload all footnotes in separated footnotes
4042 if (sText[0] == 0x5)
4043 {
4044 if (m_pImpl->IsInFootnote())
4045 {
4046 if (m_pImpl->GetFootnoteCount() > -1)
4047 {
4048 m_pImpl->PopFootOrEndnote();
4049 m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/true);
4050 }
4051 m_pImpl->IncrementFootnoteCount();
4052 }
4053 else
4054 {
4055 if (m_pImpl->GetEndnoteCount() > -1)
4056 {
4057 m_pImpl->PopFootOrEndnote();
4058 m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/false);
4059 }
4060 m_pImpl->IncrementEndnoteCount();
4061 }
4062 }
4063
4064 // If the footnote contains a Footnote Reference Mark, it can't be a custom footnote
4065 // ******
4066 // This code block is wrong, as it should also be in m_pImpl->IsInFootOrEndnote().
4067 // The main problem is that
4068 //
4069 // assert(len != 1 || sText[0] != 0x2)
4070 //
4071 // is triggered by the unit test SwLayoutWriter::testForcepoint75, so all these pseudo
4072 // value handling is broken.
4073 // But this is just a symptom, as I guess it's possible to generate broken DOCX documents,
4074 // which might be problematic, triggering *funny* code paths left and right.
4075 // ******
4076 if (sText[0] == 0x2)
4077 {
4078 m_pImpl->EndCustomFootnote();
4079 return;
4080 }
4081
4082 if (m_pImpl->IsInCustomFootnote())
4083 {
4084 if (sText[0] != 0xd && sText[0] != 0x3)
4085 {
4086 // DOCX can have different labels for the footnote reference and the footnote area.
4087 // This skips the one from the footnote area and just uses the reference one.
4088 if (!m_pImpl->IsInFootOrEndnote())
4089 {
4090 if (PropertyMapPtr pFootnoteContext = m_pImpl->GetFootnoteContext())
4091 {
4092 auto xFootnote = pFootnoteContext->GetFootnote();
4093 xFootnote->setLabel(xFootnote->getLabel() + sText);
4094 }
4095 }
4096 return;
4097 }
4098 else
4099 m_pImpl->SetHasFootnoteStyle(true);
4100 }
4101 }
4102
4103 if (m_pImpl->isSdtEndDeferred())
4104 {
4105 // In case we have a field context, then save the property there, so
4106 // SDT's ending right before a field start are handled as well.
4107 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4108 if (m_pImpl->IsOpenField())
4109 pContext = m_pImpl->GetTopFieldContext()->getProperties();
4110 pContext->Insert(PROP_SDT_END_BEFORE, uno::Any(true), true, CHAR_GRAB_BAG);
4111 m_pImpl->setSdtEndDeferred(false);
4112 }
4113
4114 bool bNewLine = len == 1 && (sText[0] == 0x0d || sText[0] == 0x07);
4115 if (m_pImpl->GetSdtStarts().empty()
4116 && (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::dropDown
4117 || m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::comboBox))
4118 {
4119 // Block, cell or row SDT.
4120 if (bNewLine)
4121 // Dropdown control has single-line texts, so in case of newline, create the control.
4122 m_pImpl->m_pSdtHelper->createDropDownControl();
4123 else
4124 {
4125 m_pImpl->m_pSdtHelper->getSdtTexts().append(sText);
4126 return;
4127 }
4128 }
4129 else if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::datePicker)
4130 {
4131 if (IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
4132 {
4133 m_pImpl->m_pSdtHelper->getDateFormat().truncate();
4134 m_pImpl->m_pSdtHelper->getLocale().truncate();
4135 return;
4136 }
4137 }
4138 else if (m_pImpl->m_pSdtHelper->GetSdtType() != NS_ooxml::LN_CT_SdtRun_sdtContent && m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText)
4139 {
4140 m_pImpl->m_pSdtHelper->getSdtTexts().append(sText);
4141 if (bNewLine)
4142 {
4143 m_pImpl->m_pSdtHelper->createPlainTextControl();
4145 }
4146 return;
4147 }
4148 else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty())
4149 {
4150 // there are unsupported SDT properties in the document
4151 // save them in the paragraph interop grab bag
4152 if (m_pImpl->IsDiscardHeaderFooter())
4153 {
4154 // Unless we're supposed to ignore this header/footer.
4155 m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4156 return;
4157 }
4158 if((m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") ||
4159 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") ||
4160 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") ||
4161 m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") ||
4162 (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") &&
4163 m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph())
4164 {
4165 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER);
4166
4167 if (m_pImpl->IsOpenField())
4168 // We have a field, insert the SDT properties to the field's grab-bag, so they won't be lost.
4169 pContext = m_pImpl->GetTopFieldContext()->getProperties();
4170
4171 uno::Sequence<beans::PropertyValue> aGrabBag = m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4172 if (m_pImpl->GetSdtStarts().empty()
4173 || (m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown
4174 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::comboBox))
4175 {
4176 pContext->Insert(PROP_SDTPR, uno::Any(aGrabBag), true, CHAR_GRAB_BAG);
4177 }
4178 }
4179 else
4180 {
4181 uno::Sequence<beans::PropertyValue> aGrabBag = m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
4182 if (m_pImpl->GetSdtStarts().empty()
4183 || (m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown
4184 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::comboBox
4185 && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::richText))
4186 {
4187 m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR,
4188 uno::Any(aGrabBag), true, PARA_GRAB_BAG);
4189 }
4190 }
4191 }
4192 else if (len == 1 && sText[0] == 0x03)
4193 {
4194 // This is the uFtnEdnSep, remember that the document has a separator.
4195 m_pImpl->m_bHasFtnSep = true;
4196 return;
4197 }
4198 else if (len == 1 && sText[0] == '\r')
4199 {
4200 // Clear "last" one linebreak at end of section
4201 if (m_pImpl->GetIsLastParagraphInSection() && m_pImpl->isBreakDeferred(LINE_BREAK))
4202 m_pImpl->clearDeferredBreak(LINE_BREAK);
4203 // And emit all other linebreaks
4204 while (m_pImpl->isBreakDeferred(LINE_BREAK))
4205 {
4206 m_pImpl->clearDeferredBreak(LINE_BREAK);
4207 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
4208 }
4209 }
4210 else if (len == 1 && sText[0] == '\t' )
4211 {
4212 if ( m_pImpl->m_bCheckFirstFootnoteTab && m_pImpl->IsInFootOrEndnote() )
4213 {
4214 // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent
4215 m_pImpl->m_bCheckFirstFootnoteTab = false;
4216 sal_Int32 nFirstLineIndent = 0;
4217 m_pImpl->GetAnyProperty(PROP_PARA_FIRST_LINE_INDENT, m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)) >>= nFirstLineIndent;
4218 if ( nFirstLineIndent < 0 )
4219 m_pImpl->m_bIgnoreNextTab = true;
4220 }
4221
4222 if ( m_pImpl->m_bIgnoreNextTab )
4223 {
4224 m_pImpl->m_bIgnoreNextTab = false;
4225 return;
4226 }
4227 }
4228 if (!m_pImpl->hasTableManager())
4229 return;
4230
4231 SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
4233 {
4234 m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
4235 return;
4236 }
4237
4238 try
4239 {
4240 while (m_pImpl->isBreakDeferred(LINE_BREAK))
4241 {
4242 m_pImpl->clearDeferredBreak(LINE_BREAK);
4243 m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
4244 }
4245
4246 m_pImpl->getTableManager().utext(data_, len);
4247
4248 if (bNewLine)
4249 {
4250 const bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection();
4251 const bool bSingleParagraphAfterRedline = m_pImpl->GetIsFirstParagraphInSection(/*bAfterRedline=*/true) &&
4252 m_pImpl->GetIsLastParagraphInSection();
4253 PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
4254 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
4255 {
4256 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
4257 {
4258 if (m_pImpl->GetSettingsTable()->GetSplitPgBreakAndParaMark())
4259 {
4260 if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
4261 {
4262 m_pImpl->m_bIsSplitPara = true;
4265 }
4266 else // IsFirstRun
4267 {
4268 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4269 {
4270 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4271 }
4272 }
4273
4274 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
4275 m_pImpl->clearDeferredBreaks();
4276 }
4277 }
4278 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
4279 {
4280 if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
4281 {
4282 mbIsSplitPara = true;
4283 m_pImpl->m_bIsSplitPara = true;
4286 }
4287 else // IsFirstRun
4288 {
4289 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4290 {
4291 pContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4292 }
4293 }
4294
4295 pContext->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
4296 m_pImpl->clearDeferredBreaks();
4297 }
4298 }
4299
4300 // If the paragraph contains only the section properties and it has
4301 // no runs, we should not create a paragraph for it in Writer, unless that would remove the whole section.
4302 // Also do not remove here column breaks: they are treated in a different way and place.
4303 bool bIsColumnBreak = false;
4304 if (pContext->isSet(PROP_BREAK_TYPE))
4305 {
4306 const uno::Any aBreakType = pContext->getProperty(PROP_BREAK_TYPE)->second;
4307 bIsColumnBreak =
4308 aBreakType == style::BreakType_COLUMN_BEFORE ||
4309 aBreakType == style::BreakType_COLUMN_AFTER ||
4310 aBreakType == style::BreakType_COLUMN_BOTH;
4311 }
4312
4313 bool bRemove = (!m_pImpl->GetParaChanged() && m_pImpl->GetRemoveThisPara()) ||
4314 (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr()
4315 && !bSingleParagraphAfterRedline
4316 && !bIsColumnBreak
4317 && !m_pImpl->GetParaHadField()
4318 && (!m_pImpl->GetIsDummyParaAddedForTableInSectionPage())
4319 && !m_pImpl->GetIsPreviousParagraphFramed()
4320 && !m_pImpl->HasTopAnchoredObjects()
4321 && !m_pImpl->IsParaWithInlineObject());
4322
4323 const bool bNoNumbering = bRemove || (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && bSingleParagraph);
4324 PropertyMapPtr xContext = bNoNumbering ? m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) : PropertyMapPtr();
4325 if (xContext)
4326 {
4327 // tdf#97417 delete numbering of the paragraph
4328 // it will be deleted anyway, and the numbering would be copied
4329 // to the next paragraph in sw SplitNode and then be applied to
4330 // every following paragraph
4331 xContext->Erase(PROP_NUMBERING_RULES);
4332 static_cast<ParagraphPropertyMap*>(xContext.get())->props().SetListId(-1);;
4333 xContext->Erase(PROP_NUMBERING_LEVEL);
4334 }
4335 finishParagraph(bRemove, bNoNumbering);
4336 if (bRemove)
4337 m_pImpl->RemoveLastParagraph();
4338
4339 // When the table is closed and the section's initial dummy paragraph has been processed
4340 // then any following sectPr paragraph in the section must be eligible for removal.
4341 if (!bRemove && m_pImpl->GetIsDummyParaAddedForTableInSectionPage() && !IsInTable()
4342 && !m_pImpl->GetFootnoteContext() && !m_pImpl->IsInComments() && !IsInHeaderFooter()
4343 && !IsInShape())
4344 {
4345 m_pImpl->SetIsDummyParaAddedForTableInSectionPage(false);
4346 }
4347
4348 m_pImpl->SetParaSectpr(false);
4349 }
4350 else
4351 {
4352 // GetTopContext() is changed by inserted breaks, but we want to keep the current context
4353 PropertyMapPtr pContext = m_pImpl->GetTopContext();
4354 if (!m_pImpl->GetFootnoteContext() && !m_pImpl->IsInShape() && !m_pImpl->IsInComments())
4355 {
4356 auto pPara = static_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH).get());
4357 if (m_pImpl->isBreakDeferred(PAGE_BREAK))
4358 {
4359 /* If PAGEBREAK appears in first paragraph of the section or
4360 * after first run of any paragraph then need to split paragraph
4361 * to handle it properly.
4362 */
4363 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
4364 {
4365 m_pImpl->m_bIsSplitPara = true;
4368 }
4369 else // IsFirstRun
4370 {
4371 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4372 {
4373 pPara->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)), true);
4374 }
4375 }
4376 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_PAGE_BEFORE));
4377 }
4378 else if (m_pImpl->isBreakDeferred(COLUMN_BREAK))
4379 {
4380 if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() || mbWasShapeInPara)
4381 {
4382 mbIsSplitPara = true;
4383 m_pImpl->m_bIsSplitPara = true;
4386 }
4387 else // IsFirstRun
4388 {
4389 if (GetSettingsTable()->GetWordCompatibilityMode() > 14)
4390 {
4391 pPara->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
4392 }
4393 }
4394 m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::Any(style::BreakType_COLUMN_BEFORE));
4395 }
4396 m_pImpl->clearDeferredBreaks();
4397 }
4398
4399 if (pContext && pContext->GetFootnote().is())
4400 {
4401 pContext->GetFootnote()->setLabel( sText );
4402 // tdf#141548 don't lose footnote/endnote text of the run with uFtnEdnRef
4403 // (i.e. when footnoteRef/endnoteRef is followed by some text in the same run)
4404 m_pImpl->appendTextPortion( sText, pContext );
4405 }
4406 else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields())
4407 {
4408 m_pImpl->AppendFieldCommand(sText);
4409 }
4410 else if( m_pImpl->IsOpenField() && m_pImpl->IsFieldResultAsString())
4411 /*depending on the success of the field insert operation this result will be
4412 set at the field or directly inserted into the text*/
4413 m_pImpl->AppendFieldResult(sText);
4414 else
4415 {
4416 if (pContext == nullptr)
4417 pContext = new PropertyMap();
4418
4419 m_pImpl->appendTextPortion( sText, pContext );
4420 }
4421
4422 }
4423 m_pImpl->SetIsFirstRun(false);
4424 }
4425 catch( const uno::RuntimeException& )
4426 {
4427 }
4428}
4429
4431{
4432 ref->resolve(*this);
4433}
4434
4436{
4437 m_pImpl->SetAnyTableImport(true);
4438 switch(name)
4439 {
4440 case NS_ooxml::LN_FONTTABLE:
4441
4442 // create a font table object that listens to the attributes
4443 // each entry call inserts a new font entry
4444 ref->resolve( *m_pImpl->GetFontTable() );
4445 break;
4446 case NS_ooxml::LN_STYLESHEET:
4447 //same as above to import style sheets
4448 m_pImpl->SetStyleSheetImport( true );
4449 ref->resolve( *m_pImpl->GetStyleSheetTable() );
4450 m_pImpl->GetStyleSheetTable()->ApplyStyleSheets(m_pImpl->GetFontTable());
4451 m_pImpl->SetStyleSheetImport( false );
4452 break;
4453 case NS_ooxml::LN_NUMBERING:
4454 {
4455 m_pImpl->SetNumberingImport(true);
4456 //the same for list tables
4457 ref->resolve( *m_pImpl->GetListTable() );
4458 m_pImpl->GetListTable( )->CreateNumberingRules( );
4459 m_pImpl->SetNumberingImport(false);
4460 }
4461 break;
4462 case NS_ooxml::LN_settings_settings:
4463 ref->resolve ( *m_pImpl->GetSettingsTable() );
4464 m_pImpl->ApplySettingsTable();
4465 break;
4466 default:
4467 OSL_FAIL( "which table is to be filled here?");
4468 }
4469 m_pImpl->SetAnyTableImport(false);
4470}
4471
4473{
4474 m_pImpl->substream(rName, ref);
4475}
4476
4478{
4480 m_pImpl->setGlossaryEntryStart(xTextRange);
4481}
4482
4484{
4485 m_pImpl->appendGlossaryEntry();
4486}
4487
4488void DomainMapper::handleUnderlineType(const Id nId, const ::tools::SvRef<PropertyMap>& rContext)
4489{
4490 sal_Int16 nUnderline = awt::FontUnderline::NONE;
4491
4492 switch (nId)
4493 {
4494 case NS_ooxml::LN_Value_ST_Underline_none:
4495 nUnderline = awt::FontUnderline::NONE;
4496 break;
4497 case NS_ooxml::LN_Value_ST_Underline_words:
4498 rContext->Insert(PROP_CHAR_WORD_MODE, uno::Any(true));
4499 [[fallthrough]];
4500 case NS_ooxml::LN_Value_ST_Underline_single:
4501 nUnderline = awt::FontUnderline::SINGLE;
4502 break;
4503 case NS_ooxml::LN_Value_ST_Underline_double:
4504 nUnderline = awt::FontUnderline::DOUBLE;
4505 break;
4506 case NS_ooxml::LN_Value_ST_Underline_dotted:
4507 nUnderline = awt::FontUnderline::DOTTED;
4508 break;
4509 case NS_ooxml::LN_Value_ST_Underline_dash:
4510 nUnderline = awt::FontUnderline::DASH;
4511 break;
4512 case NS_ooxml::LN_Value_ST_Underline_dotDash:
4513 nUnderline = awt::FontUnderline::DASHDOT;
4514 break;
4515 case NS_ooxml::LN_Value_ST_Underline_dotDotDash:
4516 nUnderline = awt::FontUnderline::DASHDOTDOT;
4517 break;
4518 case NS_ooxml::LN_Value_ST_Underline_thick:
4519 nUnderline = awt::FontUnderline::BOLD;
4520 break;
4521 case NS_ooxml::LN_Value_ST_Underline_wave:
4522 nUnderline = awt::FontUnderline::WAVE;
4523 break;
4524 case NS_ooxml::LN_Value_ST_Underline_dottedHeavy:
4525 nUnderline = awt::FontUnderline::BOLDDOTTED;
4526 break;
4527 case NS_ooxml::LN_Value_ST_Underline_dashedHeavy:
4528 nUnderline = awt::FontUnderline::BOLDDASH;
4529 break;
4530 case NS_ooxml::LN_Value_ST_Underline_dashLong:
4531 nUnderline = awt::FontUnderline::LONGDASH;
4532 break;
4533 case NS_ooxml::LN_Value_ST_Underline_dashLongHeavy:
4534 nUnderline = awt::FontUnderline::BOLDLONGDASH;
4535 break;
4536 case NS_ooxml::LN_Value_ST_Underline_dashDotHeavy:
4537 nUnderline = awt::FontUnderline::BOLDDASHDOT;
4538 break;
4539 case NS_ooxml::LN_Value_ST_Underline_dashDotDotHeavy:
4540 nUnderline = awt::FontUnderline::BOLDDASHDOTDOT;
4541 break;
4542 case NS_ooxml::LN_Value_ST_Underline_wavyHeavy:
4543 nUnderline = awt::FontUnderline::BOLDWAVE;
4544 break;
4545 case NS_ooxml::LN_Value_ST_Underline_wavyDouble:
4546 nUnderline = awt::FontUnderline::DOUBLEWAVE;
4547 break;
4548 }
4549 rContext->Insert(PROP_CHAR_UNDERLINE, uno::Any(nUnderline));
4550}
4551
4552void DomainMapper::handleParaJustification(const sal_Int32 nIntValue, const ::tools::SvRef<PropertyMap>& rContext, const bool bExchangeLeftRight)
4553{
4554 style::ParagraphAdjust nAdjust = style::ParagraphAdjust_LEFT;
4555 style::ParagraphAdjust nLastLineAdjust = style::ParagraphAdjust_LEFT;
4556 OUString aStringValue = "left";
4557 switch(nIntValue)
4558 {
4559 case NS_ooxml::LN_Value_ST_Jc_center:
4560 nAdjust = style::ParagraphAdjust_CENTER;
4561 aStringValue = "center";
4562 break;
4563 case NS_ooxml::LN_Value_ST_Jc_right:
4564 case NS_ooxml::LN_Value_ST_Jc_end:
4565 nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_LEFT : style::ParagraphAdjust_RIGHT;
4566 aStringValue = "right";
4567 break;
4568 case NS_ooxml::LN_Value_ST_Jc_distribute:
4569 nLastLineAdjust = style::ParagraphAdjust_BLOCK;
4570 [[fallthrough]];
4571 case NS_ooxml::LN_Value_ST_Jc_both:
4572 nAdjust = style::ParagraphAdjust_BLOCK;
4573 aStringValue = "both";
4574 break;
4575 case NS_ooxml::LN_Value_ST_Jc_left:
4576 case NS_ooxml::LN_Value_ST_Jc_start:
4577 default:
4578 nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT;
4579 break;
4580 }
4581 rContext->Insert( PROP_PARA_ADJUST, uno::Any( nAdjust ) );
4582 rContext->Insert( PROP_PARA_LAST_LINE_ADJUST, uno::Any( nLastLineAdjust ) );
4583 m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "jc", aStringValue);
4584}
4585
4586bool DomainMapper::getColorFromId(const Id nId, sal_Int32 &nColor)
4587{
4588 nColor = 0;
4589 if ((nId < NS_ooxml::LN_Value_ST_HighlightColor_black) || (nId > NS_ooxml::LN_Value_ST_HighlightColor_none))
4590 return false;
4591
4592 switch (nId)
4593 {
4594 case NS_ooxml::LN_Value_ST_HighlightColor_black: nColor=0x000000; break;
4595 case NS_ooxml::LN_Value_ST_HighlightColor_blue: nColor=0x0000ff; break;
4596 case NS_ooxml::LN_Value_ST_HighlightColor_cyan: nColor=0x00ffff; break;
4597 case NS_ooxml::LN_Value_ST_HighlightColor_green: nColor=0x00ff00; break;
4598 case NS_ooxml::LN_Value_ST_HighlightColor_magenta: nColor=0xff00ff; break;
4599 case NS_ooxml::LN_Value_ST_HighlightColor_red: nColor=0xff0000; break;
4600 case NS_ooxml::LN_Value_ST_HighlightColor_yellow: nColor=0xffff00; break;
4601 case NS_ooxml::LN_Value_ST_HighlightColor_white: nColor=0xffffff; break;
4602 case NS_ooxml::LN_Value_ST_HighlightColor_darkBlue: nColor=0x000080; break;
4603 case NS_ooxml::LN_Value_ST_HighlightColor_darkCyan: nColor=0x008080; break;
4604 case NS_ooxml::LN_Value_ST_HighlightColor_darkGreen: nColor=0x008000; break;
4605 case NS_ooxml::LN_Value_ST_HighlightColor_darkMagenta: nColor=0x800080; break;
4606 case NS_ooxml::LN_Value_ST_HighlightColor_darkRed: nColor=0x800000; break;
4607 case NS_ooxml::LN_Value_ST_HighlightColor_darkYellow: nColor=0x808000; break;
4608 case NS_ooxml::LN_Value_ST_HighlightColor_darkGray: nColor=0x808080; break;
4609 case NS_ooxml::LN_Value_ST_HighlightColor_lightGray: nColor=0xC0C0C0; break;
4610 case NS_ooxml::LN_Value_ST_HighlightColor_none: nColor=0xFFFFFFFF; break; //COL_AUTO
4611 default:
4612 return false;
4613 }
4614 return true;
4615}
4616
4617sal_Int16 DomainMapper::getEmphasisValue(const sal_Int32 nIntValue)
4618{
4619 switch (nIntValue)
4620 {
4621 case NS_ooxml::LN_Value_ST_Em_dot:
4622 return text::FontEmphasis::DOT_ABOVE;
4623 case NS_ooxml::LN_Value_ST_Em_comma:
4624 return text::FontEmphasis::ACCENT_ABOVE;
4625 case NS_ooxml::LN_Value_ST_Em_circle:
4626 return text::FontEmphasis::CIRCLE_ABOVE;
4627 case NS_ooxml::LN_Value_ST_Em_underDot:
4628 return text::FontEmphasis::DOT_BELOW;
4629 default:
4631 }
4632}
4633
4634OUString DomainMapper::getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix)
4635{
4636 switch(nIntValue)
4637 {
4638 case NS_ooxml::LN_Value_ST_CombineBrackets_round:
4639 if (bIsPrefix)
4640 return "(";
4641 return ")";
4642
4643 case NS_ooxml::LN_Value_ST_CombineBrackets_square:
4644 if (bIsPrefix)
4645 return "[";
4646 return "]";
4647
4648 case NS_ooxml::LN_Value_ST_CombineBrackets_angle:
4649 if (bIsPrefix)
4650 return "<";
4651 return ">";
4652
4653 case NS_ooxml::LN_Value_ST_CombineBrackets_curly:
4654 if (bIsPrefix)
4655 return "{";
4656 return "}";
4657
4658 case NS_ooxml::LN_Value_ST_CombineBrackets_none:
4659 default:
4660 return OUString();
4661 }
4662}
4663
4664style::TabAlign DomainMapper::getTabAlignFromValue(const sal_Int32 nIntValue)
4665{
4666 switch (nIntValue)
4667 {
4668 case NS_ooxml::LN_Value_ST_TabJc_start:
4669 case NS_ooxml::LN_Value_ST_TabJc_left:
4670 case NS_ooxml::LN_Value_ST_TabJc_bar: // bar not supported
4671 case NS_ooxml::LN_Value_ST_TabJc_num: // num not supported
4672 return style::TabAlign_LEFT;
4673 case NS_ooxml::LN_Value_ST_TabJc_center:
4674 return style::TabAlign_CENTER;
4675 case NS_ooxml::LN_Value_ST_TabJc_end:
4676 case NS_ooxml::LN_Value_ST_TabJc_right:
4677 return style::TabAlign_RIGHT;
4678 case NS_ooxml::LN_Value_ST_TabJc_decimal:
4679 return style::TabAlign_DECIMAL;
4680 }
4681 return style::TabAlign_LEFT;
4682}
4683
4685{
4686 switch (nIntValue)
4687 {
4688 case NS_ooxml::LN_Value_ST_TabTlc_dot:
4689 return u'.';
4690 case NS_ooxml::LN_Value_ST_TabTlc_hyphen:
4691 return u'-';
4692 case NS_ooxml::LN_Value_ST_TabTlc_underscore:
4693 case NS_ooxml::LN_Value_ST_TabTlc_heavy: // FIXME ???
4694 return u'_';
4695 case NS_ooxml::LN_Value_ST_TabTlc_middleDot: // middleDot
4696 return u'\x00b7';
4697 case NS_ooxml::LN_Value_ST_TabTlc_none:
4698 default:
4699 return u' '; // blank space
4700 }
4701}
4702
4704{
4705 return m_pImpl->IsOOXMLImport();
4706}
4707
4709{
4710 return m_pImpl->IsRTFImport();
4711}
4712
4714{
4715 return m_pImpl->GetTextFactory();
4716}
4717
4719{
4720 if (m_pImpl->HasTopText())
4721 return m_pImpl->GetTopTextAppend()->getEnd();
4722 return m_pImpl->m_xInsertTextRange;
4723}
4724
4725OUString DomainMapper::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate )
4726{
4727 StyleSheetTablePtr pStyleSheets = m_pImpl->GetStyleSheetTable();
4728 return pStyleSheets->getOrCreateCharStyle( rCharProperties, bAlwaysCreate );
4729}
4730
4732{
4733 return m_pImpl->GetStyleSheetTable( );
4734}
4735
4737{
4738 return m_pImpl->GetSettingsTable();
4739}
4740
4742{
4743 if (m_zOrderHelper == nullptr)
4745 return m_zOrderHelper.get();
4746}
4747
4749{
4750 return m_pImpl->PopPendingShape();
4751}
4752
4754{
4755 return m_pImpl->IsInHeaderFooter();
4756}
4757
4758bool DomainMapper::IsInShape() const { return m_pImpl->IsInShape(); }
4759
4761{
4762 return m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell();
4763}
4764
4765OUString DomainMapper::GetListStyleName(sal_Int32 nListId) const
4766{
4767 return m_pImpl->GetListStyleName( nListId );
4768}
4769
4770void DomainMapper::ValidateListLevel(const OUString& sStyleIdentifierD)
4771{
4772 m_pImpl->ValidateListLevel(sStyleIdentifierD);
4773}
4774
4776{
4777 m_pImpl->SetDocDefaultsImport(bSet);
4778}
4779
4781{
4782 return m_pImpl->IsStyleSheetImport();
4783}
4784
4786{
4787 return m_pImpl->IsNumberingImport();
4788}
4789
4790void DomainMapper::enableInteropGrabBag(const OUString& aName)
4791{
4792 m_pImpl->m_aInteropGrabBagName = aName;
4793}
4794
4796{
4797 beans::PropertyValue aRet;
4798 aRet.Name = m_pImpl->m_aInteropGrabBagName;
4799 aRet.Value <<= comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag);
4800
4801 m_pImpl->m_aInteropGrabBag.clear();
4802 m_pImpl->m_aInteropGrabBagName.clear();
4803 return aRet;
4804}
4805
4807{
4808 sal_uInt32 nSprmId = rSprm.getId();
4809
4810 m_pImpl->AddNewRedline( nSprmId );
4811
4812 if (nSprmId == NS_ooxml::LN_CT_PPr_pPrChange)
4813 {
4814 m_pImpl->SetCurrentRedlineToken(XML_ParagraphFormat);
4815 }
4816 else if (nSprmId == NS_ooxml::LN_CT_TrPr_ins)
4817 {
4818 m_pImpl->SetCurrentRedlineToken(XML_tableRowInsert);
4819 }
4820 else if (nSprmId == NS_ooxml::LN_CT_TrPr_del)
4821 {
4822 m_pImpl->SetCurrentRedlineToken(XML_tableRowDelete);
4823 }
4824 else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellIns)
4825 {
4826 m_pImpl->SetCurrentRedlineToken(XML_tableCellInsert);
4827 }
4828 else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellDel)
4829 {
4830 m_pImpl->SetCurrentRedlineToken(XML_tableCellDelete);
4831 }
4832
4833 resolveSprmProps(*this, rSprm );
4834 // now the properties author, date and id should be available
4835 sal_Int32 nToken = m_pImpl->GetCurrentRedlineToken();
4836 switch( nToken & 0xffff )
4837 {
4838 case XML_mod:
4839 case XML_ins:
4840 case XML_del:
4841 case XML_moveTo:
4842 case XML_moveFrom:
4843 case XML_ParagraphFormat:
4844 case XML_tableRowInsert:
4845 case XML_tableRowDelete:
4846 case XML_tableCellInsert:
4847 case XML_tableCellDelete:
4848 break;
4849 default: OSL_FAIL( "redline token other than mod, ins, del, moveTo, moveFrom or table row" ); break;
4850 }
4851 m_pImpl->EndParaMarkerChange( );
4852 m_pImpl->SetCurrentRedlineIsRead();
4853}
4854
4855void DomainMapper::finishParagraph(const bool bRemove, const bool bNoNumbering)
4856{
4857 if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::datePicker)
4858 m_pImpl->m_pSdtHelper->createDateContentControl();
4859 m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), bRemove, bNoNumbering);
4860}
4861
4862void DomainMapper::commentProps(const OUString& sId, const CommentProperties& rProps)
4863{
4864 m_pImpl->commentProps(sId, rProps);
4865}
4866
4867css::uno::Reference<css::container::XNameContainer> const & DomainMapper::GetCharacterStyles()
4868{
4869 return m_pImpl->GetCharacterStyles();
4870}
4871
4873{
4874 return m_pImpl->GetUnusedCharacterStyleName();
4875}
4876
4877} //namespace writerfilter
4878
4879/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::vector< css::beans::PropertyValue > PropertyValueVector_t
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
#define WW_OUTLINE_MAX
PropertiesInfo aProperties
constexpr auto convertTwipToMm100(N n)
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
OUString getLanguage() const
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
LanguageTag & makeFallback()
const OUString & getNumDecimalSep() const
tools::Long getWidth() const
static tools::Long sloppyFitPageDimension(tools::Long nDimension)
tools::Long getHeight() const
static css::uno::Reference< css::embed::XStorage > GetStorageOfFormatFromInputStream(const OUString &aFormat, const css::uno::Reference< css::io::XInputStream > &xStream, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >(), bool bRepairStorage=false)
static css::uno::Reference< css::embed::XStorage > GetTemporaryStorage(const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const
void update(const SequenceAsHashMap &rSource)
void setSchemeColor(ThemeColorType eType)
ThemeColorUsage meThemeColorUsage
void addTransformation(Transformation const &rTransform)
T * get() const
bool is() const
void props(writerfilter::Reference< Properties >::Pointer_t ref) override
Receives properties of the current run of text.
void utext(const sal_uInt8 *data, size_t len) override
Receives 16-bit per character text.
An SPRM: Section, Paragraph and Run Modifier.
virtual sal_uInt32 getId() const =0
Returns id of the SPRM.
virtual writerfilter::Reference< Properties >::Pointer_t getProps()=0
Returns reference to properties contained in the SPRM.
virtual Value::Pointer_t getValue()=0
Returns value of the SPRM.
virtual std::string getName() const =0
Returns name of sprm.
static TagLogger & getInstance()
Definition: TagLogger.cxx:95
void startElement(const std::string &name)
Definition: TagLogger.cxx:140
void chars(const std::string &chars)
Definition: TagLogger.cxx:215
void attribute(const std::string &name, const std::string &value)
Definition: TagLogger.cxx:150
virtual writerfilter::Reference< Properties >::Pointer_t getProperties()=0
Returns properties of this value.
virtual int getInt() const =0
Returns integer representation of the value.
virtual OUString getString() const =0
Returns string representation of the value.
css::uno::Any GetAnyProperty(PropertyIds eId, const PropertyMapPtr &rContext)
virtual void lcl_endTextBoxContent() override
virtual void lcl_endSectionGroup() override
virtual void lcl_props(writerfilter::Reference< Properties >::Pointer_t ref) override
virtual void lcl_startShape(css::uno::Reference< css::drawing::XShape > const &xShape) override
virtual void lcl_endCharacterGroup() override
virtual void lcl_attribute(Id Name, Value &val) override
virtual void lcl_endGlossaryEntry() override
static OUString getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix=true)
GraphicZOrderHelper * graphicZOrderHelper()
virtual void markLastSectionGroup() override
The current section is the last one in this body text.
virtual void lcl_positivePercentage(const OUString &rText) override
css::uno::Reference< css::container::XNameContainer > const & GetCharacterStyles()
void enableInteropGrabBag(const OUString &aName)
Enable storing of seen tokens in a named grab bag.
virtual void lcl_substream(Id name, ::writerfilter::Reference< Stream >::Pointer_t ref) override
virtual void lcl_endShape() override
virtual css::awt::Point getPositionOffset() override
Returns the last set offsets of a shape in HMM.
virtual void markLastParagraphInSection() override
css::uno::Reference< css::text::XTextRange > GetCurrentTextRange()
virtual void lcl_text(const sal_uInt8 *data, size_t len) override
css::uno::Reference< css::drawing::XShape > PopPendingShape()
Return the first from the pending (not inserted to the document) shapes, if there are any.
void PopStyleSheetProperties(bool bAffectTableMngr=false)
virtual void lcl_entry(writerfilter::Reference< Properties >::Pointer_t ref) override
OUString GetListStyleName(sal_Int32 nListId) const
static sal_Int16 getEmphasisValue(const sal_Int32 nIntValue)
virtual void lcl_startCharacterGroup() override
StyleSheetTablePtr const & GetStyleSheetTable()
void ValidateListLevel(const OUString &sStyleIdentifierD)
OUString getOrCreateCharStyle(PropertyValueVector_t &rCharProperties, bool bAlwaysCreate)
virtual void lcl_startGlossaryEntry() override
virtual void lcl_utext(const sal_uInt8 *data, size_t len) override
virtual void lcl_align(const OUString &rText, bool bVertical) override
void sprmWithProps(Sprm &sprm, const PropertyMapPtr &pContext)
std::unique_ptr< DomainMapper_Impl > m_pImpl
virtual void lcl_sprm(Sprm &sprm) override
css::uno::Reference< css::lang::XMultiServiceFactory > const & GetTextFactory() const
void PushStyleSheetProperties(const PropertyMapPtr &pStyleProperties, bool bAffectTableMngr=false)
static css::style::TabAlign getTabAlignFromValue(const sal_Int32 nIntValue)
void PushListProperties(const ::tools::SvRef< PropertyMap > &pListProperties)
static bool getColorFromId(const Id, sal_Int32 &nColor)
static sal_Unicode getFillCharFromValue(const sal_Int32 nIntValue)
std::unique_ptr< GraphicZOrderHelper > m_zOrderHelper
virtual void lcl_checkId(const sal_Int32 nId) override
DomainMapper(const css::uno::Reference< css::uno::XComponentContext > &xContext, css::uno::Reference< css::io::XInputStream > const &xInputStream, css::uno::Reference< css::lang::XComponent > const &xModel, bool bRepairStorage, SourceDocumentType eDocumentType, utl::MediaDescriptor const &rMediaDesc)
virtual void setDocumentReference(writerfilter::ooxml::OOXMLDocument *pDocument) override
virtual void lcl_startTextBoxContent() override
virtual void lcl_positionOffset(const OUString &rText, bool bVertical) override
static void handleUnderlineType(const Id nId, const ::tools::SvRef< PropertyMap > &rContext)
void processDeferredCharacterProperties(const std::map< sal_Int32, css::uno::Any > &rDeferredCharacterProperties, bool bCharContext=true)
css::beans::PropertyValue getInteropGrabBag()
Get the stored tokens and clear the internal storage.
virtual void lcl_startSectionGroup() override
SettingsTablePtr const & GetSettingsTable()
virtual void lcl_endParagraphGroup() override
virtual void data(const sal_uInt8 *buf, size_t len) override
Receives binary data of the object.
virtual void lcl_startParagraphGroup() override
void handleParaJustification(const sal_Int32 nIntValue, const ::tools::SvRef< PropertyMap > &rContext, const bool bExchangeLeftRight)
virtual void lcl_table(Id name, writerfilter::Reference< Table >::Pointer_t ref) override
virtual void commentProps(const OUString &sId, const CommentProperties &rProps) override
void finishParagraph(const bool bRemove=false, const bool bNoNumbering=false)
Handler for sprms that contain a measure and a unit.
void SetWrap(css::text::WrapTextMode nSet)
void CloseSectionGroup(DomainMapper_Impl &rDM_Impl)
void SetGutterMargin(sal_Int32 nGutterMargin)
static model::ThemeColorUsage getThemeColorUsage(sal_Int32 nType)
static model::ThemeColorType getThemeColorTypeIndex(sal_Int32 nType)
static OUString getThemeColorTypeString(sal_Int32 nType)
Class to process all text effects like glow, textOutline, ...
static OUString getOnOffString(sal_Int32 nType)
static sal_uInt8 GetTextFillSolidFillAlpha(const css::beans::PropertyValue &rValue)
static OUString getStringForTheme(const Id id)
ColorTransparency
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
float u
#define DFLT_ESC_SUB
#define DFLT_ESC_SUPER
#define DFLT_ESC_PROP
#define MAX_ESC_POS
#define DFLT_ESC_AUTO_SUB
#define DFLT_ESC_AUTO_SUPER
DocumentType eType
sal_Int16 nValue
OUString sName
const char * name
OUString aName
sal_Int16 nNumType
sal_Int16 nAdjust
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
sal_Int32 getEnumAsINT32(const Any &_rAny)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
model::ComplexColor getFromXComplexColor(uno::Reference< util::XComplexColor > const &rxColor)
uno::Reference< util::XComplexColor > createXComplexColor(model::ComplexColor const &rColor)
OUString ConvertColorOU(const Color &rColor)
sal_Int32 convertEmuToHmm(sal_Int64 nValue)
end
uno::Reference< rdf::XURI > createBaseURI(uno::Reference< uno::XComponentContext > const &i_xContext, uno::Reference< frame::XModel > const &i_xModel, OUString const &i_rPkgURI, std::u16string_view i_rSubDocument)
sal_Int32 convertTwipToMM100WithoutLimit(sal_Int32 _t)
text::RubyAdjust convertRubyAlign(sal_Int32 nIntValue)
sal_Int16 ConvertNumberingType(const sal_Int32 nFmt, const sal_Int16 nDefault)
OUString getPropertyName(PropertyIds eId)
tools::SvRef< PropertyMap > PropertyMapPtr
@ PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING
@ PROP_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING
SkipFootnoteSeparator
Two special footnotes are a separator line, and a continuation line.
static bool ExchangeLeftRight(const PropertyMapPtr &rContext, DomainMapper_Impl &rImpl)
struct writerfilter::dmapper::@0 CT_PageSz
void resolveSprmProps(Properties &rHandler, Sprm &rSprm)
Definition: util.cxx:62
const sal_uInt8 cFieldSep
const sal_uInt8 cFieldStart
const sal_uInt8 cFieldEnd
sal_Int16 nId
PAPER_LETTER
DefTokenId nToken
sal_uInt32 Id
constexpr OUStringLiteral OFOPXML_STORAGE_FORMAT_STRING
bool hasValue()
A container for the extended comment properties linked to the last paragraph of a comment.
Reference< XModel > xModel
unsigned char sal_uInt8
sal_uInt16 sal_Unicode
signed char sal_Int8
OUString sId