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