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