Update git submodules
[LibreOffice.git] / xmloff / source / transform / StyleOASISTContext.cxx
blobfe4274d9389ccd9b0d8ad3cc9fc10cba612ad737
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
21 #include <rtl/ustrbuf.hxx>
22 #include <osl/diagnose.h>
23 #include <sax/tools/converter.hxx>
24 #include <xmloff/namespacemap.hxx>
25 #include <xmloff/xmltoken.hxx>
26 #include <xmloff/xmlnamespace.hxx>
27 #include "PropType.hxx"
28 #include "DeepTContext.hxx"
29 #include "TransformerBase.hxx"
30 #include "TransformerActions.hxx"
31 #include "ActionMapTypesOASIS.hxx"
32 #include "MutableAttrList.hxx"
33 #include "PropertyActionsOASIS.hxx"
34 #include "StyleOASISTContext.hxx"
35 #include <xmloff/xmluconv.hxx>
37 using namespace ::xmloff::token;
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::xml::sax;
41 const sal_uInt16 aAttrActionMaps[XML_PROP_TYPE_END] =
43 PROP_OASIS_GRAPHIC_ATTR_ACTIONS,
44 PROP_OASIS_DRAWING_PAGE_ATTR_ACTIONS, // DRAWING_PAGE
45 PROP_OASIS_PAGE_LAYOUT_ATTR_ACTIONS,
46 PROP_OASIS_HEADER_FOOTER_ATTR_ACTIONS,
47 PROP_OASIS_TEXT_ATTR_ACTIONS,
48 PROP_OASIS_PARAGRAPH_ATTR_ACTIONS,
49 MAX_OASIS_PROP_ACTIONS, // RUBY
50 PROP_OASIS_SECTION_ATTR_ACTIONS,
51 PROP_OASIS_TABLE_ATTR_ACTIONS,
52 PROP_OASIS_TABLE_COLUMN_ATTR_ACTIONS,
53 PROP_OASIS_TABLE_ROW_ATTR_ACTIONS,
54 PROP_OASIS_TABLE_CELL_ATTR_ACTIONS,
55 PROP_OASIS_LIST_LEVEL_ATTR_ACTIONS,
56 PROP_OASIS_CHART_ATTR_ACTIONS
59 class XMLPropertiesTContext_Impl : public XMLPersElemContentTContext
61 rtl::Reference< XMLMutableAttributeList > m_xAttrList;
63 XMLPropType m_ePropType;
64 bool const m_bControlStyle;
66 public:
68 void SetQNameAndPropType( const OUString& rQName,
69 XMLPropType ePropType )
71 m_ePropType = ePropType;
72 XMLTransformerContext::SetQName( rQName );
75 XMLPropertiesTContext_Impl( XMLTransformerBase& rTransformer,
76 const OUString& rQName,
77 XMLPropType eP,
78 bool _bControlStyle );
80 virtual void StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override;
82 virtual void Export() override;
84 static XMLPropType GetPropType( std::u16string_view rLocalName );
86 static OUString const & MergeUnderline( XMLTokenEnum eUnderline,
87 bool bBold, bool bDouble );
88 static OUString const & MergeLineThrough( XMLTokenEnum eLineThrough,
89 bool bBold, bool bDouble,
90 sal_Unicode c );
93 XMLPropertiesTContext_Impl::XMLPropertiesTContext_Impl(
94 XMLTransformerBase& rImp, const OUString& rQName, XMLPropType eP,
95 bool _bControlStyle ) :
96 XMLPersElemContentTContext( rImp, rQName, XML_NAMESPACE_STYLE,
97 XML_PROPERTIES),
98 m_ePropType( eP ),
99 m_bControlStyle( _bControlStyle )
103 void XMLPropertiesTContext_Impl::StartElement(
104 const Reference< XAttributeList >& rAttrList )
106 XMLTransformerActions *pActions = nullptr;
107 sal_uInt16 nActionMap = aAttrActionMaps[m_ePropType];
108 if( nActionMap < MAX_OASIS_PROP_ACTIONS )
110 pActions = GetTransformer().GetUserDefinedActions( nActionMap );
111 OSL_ENSURE( pActions, "go no actions" );
114 if( pActions )
116 if( !m_xAttrList.is() )
117 m_xAttrList = new XMLMutableAttributeList();
118 rtl::Reference<XMLMutableAttributeList> pAttrList = m_xAttrList;
120 XMLTokenEnum eUnderline = XML_TOKEN_END;
121 bool bBoldUnderline = false, bDoubleUnderline = false;
122 XMLTokenEnum eLineThrough = XML_TOKEN_END;
123 bool bBoldLineThrough = false, bDoubleLineThrough = false;
124 sal_Unicode cLineThroughChar = 0;
126 bool bIntervalMinorFound = false;
127 double fIntervalMajor = 0.0;
128 sal_Int32 nIntervalMinorDivisor = 0;
130 // #i25616#
131 OUString aOpacityValueRemember;
132 OUString aImageOpacityValueRemember;
134 sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
135 for( sal_Int16 i=0; i < nAttrCount; i++ )
137 const OUString aAttrName = rAttrList->getNameByIndex( i );
138 const OUString aAttrValue = rAttrList->getValueByIndex( i );
139 OUString aLocalName;
140 sal_uInt16 nPrefix =
141 GetTransformer().GetNamespaceMap().GetKeyByAttrName( aAttrName,
142 &aLocalName );
144 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
145 XMLTransformerActions::const_iterator aIter =
146 pActions->find( aKey );
147 if( aIter != pActions->end() )
149 switch( (*aIter).second.m_nActionType )
151 case XML_ATACTION_REMOVE:
152 break;
153 case XML_ATACTION_COPY:
154 pAttrList->AddAttribute( aAttrName, aAttrValue );
155 break;
156 case XML_ATACTION_RENAME:
158 OUString aNewAttrQName(
159 GetTransformer().GetNamespaceMap().GetQNameByKey(
160 (*aIter).second.GetQNamePrefixFromParam1(),
161 ::xmloff::token::GetXMLToken(
162 (*aIter).second.GetQNameTokenFromParam1()) ) );
163 pAttrList->AddAttribute( aNewAttrQName, aAttrValue );
165 break;
166 case XML_ATACTION_IN2INCH:
168 OUString aAttrValue2( aAttrValue );
169 XMLTransformerBase::ReplaceSingleInWithInch(
170 aAttrValue2 );
171 pAttrList->AddAttribute( aAttrName, aAttrValue2 );
173 break;
174 case XML_ATACTION_INS2INCHS:
176 OUString aAttrValue2( aAttrValue );
177 XMLTransformerBase::ReplaceInWithInch(
178 aAttrValue2 );
179 pAttrList->AddAttribute( aAttrName, aAttrValue2 );
181 break;
182 case XML_ATACTION_DECODE_STYLE_NAME_REF:
184 OUString aAttrValue2( aAttrValue );
185 XMLTransformerBase::DecodeStyleName(aAttrValue2);
186 pAttrList->AddAttribute( aAttrName, aAttrValue2 );
188 break;
189 case XML_ATACTION_RENAME_DECODE_STYLE_NAME_REF:
191 OUString aNewAttrQName(
192 GetTransformer().GetNamespaceMap().GetQNameByKey(
193 (*aIter).second.GetQNamePrefixFromParam1(),
194 ::xmloff::token::GetXMLToken(
195 (*aIter).second.GetQNameTokenFromParam1()) ) );
196 OUString aAttrValue2( aAttrValue );
197 XMLTransformerBase::DecodeStyleName(aAttrValue2);
198 pAttrList->AddAttribute( aNewAttrQName, aAttrValue2 );
200 break;
201 case XML_ATACTION_NEG_PERCENT:
203 OUString aAttrValue2( aAttrValue );
204 XMLTransformerBase::NegPercent(aAttrValue2);
205 pAttrList->AddAttribute( aAttrName, aAttrValue2 );
207 break;
208 case XML_ATACTION_RENAME_NEG_PERCENT:
210 OUString aNewAttrQName(
211 GetTransformer().GetNamespaceMap().GetQNameByKey(
212 (*aIter).second.GetQNamePrefixFromParam1(),
213 ::xmloff::token::GetXMLToken(
214 (*aIter).second.GetQNameTokenFromParam1()) ) );
215 OUString aAttrValue2( aAttrValue );
216 XMLTransformerBase::NegPercent(aAttrValue2);
217 pAttrList->AddAttribute( aNewAttrQName, aAttrValue2 );
219 break;
220 case XML_OPTACTION_LINE_MODE:
222 bool bWordMode =
223 IsXMLToken( aAttrValue, XML_SKIP_WHITE_SPACE );
224 OUString aAttrQName(
225 GetTransformer().GetNamespaceMap().GetQNameByKey(
226 XML_NAMESPACE_FO,
227 GetXMLToken( XML_SCORE_SPACES ) ) );
228 sal_Int16 nIndex =
229 pAttrList->GetIndexByName( aAttrQName );
230 if( -1 != nIndex )
232 if( bWordMode )
234 const OUString aOldValue =
235 pAttrList->getValueByIndex( nIndex );
236 if( !IsXMLToken( aOldValue, XML_TRUE ) )
238 pAttrList->SetValueByIndex( nIndex,
239 GetXMLToken( XML_TRUE ) );
243 else
245 const OUString& aAttrValue2( GetXMLToken( bWordMode
246 ? XML_FALSE
247 : XML_TRUE ) );
248 pAttrList->AddAttribute( aAttrQName, aAttrValue2 );
251 break;
252 case XML_OPTACTION_KEEP_WITH_NEXT:
254 const OUString& aAttrValue2( GetXMLToken(
255 IsXMLToken( aAttrValue, XML_ALWAYS )
256 ? XML_TRUE
257 : XML_FALSE) );
258 pAttrList->AddAttribute( aAttrName, aAttrValue2 );
260 break;
261 case XML_OPTACTION_UNDERLINE_WIDTH:
262 if( IsXMLToken( aAttrValue, XML_BOLD ) )
263 bBoldUnderline = true;
264 break;
265 case XML_OPTACTION_UNDERLINE_TYPE:
266 if( IsXMLToken( aAttrValue, XML_DOUBLE ) )
267 bDoubleUnderline = true;
268 break;
269 case XML_OPTACTION_UNDERLINE_STYLE:
270 eUnderline = GetTransformer().GetToken( aAttrValue );
271 break;
272 case XML_OPTACTION_LINETHROUGH_WIDTH:
273 if( IsXMLToken( aAttrValue, XML_BOLD ) )
274 bBoldLineThrough = true;
275 break;
276 case XML_OPTACTION_LINETHROUGH_TYPE:
277 if( IsXMLToken( aAttrValue, XML_DOUBLE ) )
278 bDoubleLineThrough = true;
279 break;
280 case XML_OPTACTION_LINETHROUGH_STYLE:
281 eLineThrough = GetTransformer().GetToken( aAttrValue );
282 break;
283 case XML_OPTACTION_LINETHROUGH_TEXT:
284 if( !aAttrValue.isEmpty() )
285 cLineThroughChar = aAttrValue[0];
286 break;
287 case XML_OPTACTION_INTERPOLATION:
289 // 0: none (default)
290 sal_Int32 nSplineType = 0;
291 if( IsXMLToken( aAttrValue, XML_CUBIC_SPLINE ))
292 nSplineType = 1;
293 else if( IsXMLToken( aAttrValue, XML_B_SPLINE ))
294 nSplineType = 2;
296 pAttrList->AddAttribute(
297 GetTransformer().GetNamespaceMap().GetQNameByKey(
298 XML_NAMESPACE_CHART,
299 GetXMLToken( XML_SPLINES )),
300 OUString::number( nSplineType ));
302 break;
303 case XML_OPTACTION_INTERVAL_MAJOR:
304 pAttrList->AddAttribute( aAttrName, aAttrValue );
305 ::sax::Converter::convertDouble(fIntervalMajor, aAttrValue);
306 break;
307 case XML_OPTACTION_INTERVAL_MINOR_DIVISOR:
308 ::sax::Converter::convertNumber(nIntervalMinorDivisor, aAttrValue);
309 bIntervalMinorFound = true;
310 break;
311 case XML_OPTACTION_SYMBOL_TYPE:
313 // if symbol_type is "named-symbol" the "symbol"
314 // property is set in the action XML_OPTACTION_SYMBOL_NAME
315 sal_Int32 nSymbolType = 0;
316 if( IsXMLToken( aAttrValue, XML_NONE ))
317 nSymbolType = -3;
318 else if( IsXMLToken( aAttrValue, XML_AUTOMATIC ))
319 nSymbolType = -2;
320 else if( IsXMLToken( aAttrValue, XML_IMAGE ))
321 nSymbolType = -1;
323 if( nSymbolType < 0 )
324 pAttrList->AddAttribute(
325 GetTransformer().GetNamespaceMap().GetQNameByKey(
326 XML_NAMESPACE_CHART,
327 GetXMLToken( XML_SYMBOL )),
328 OUString::number( nSymbolType ));
330 break;
331 case XML_OPTACTION_SYMBOL_NAME:
333 // assume "symbol-type" == "named-symbol"
334 sal_Int32 nSymbolType = -3; // NONE
335 // "square" just has an awkward token-name
336 if( IsXMLToken( aAttrValue, XML_GRADIENTSTYLE_SQUARE ))
337 nSymbolType = 0;
338 else if( IsXMLToken( aAttrValue, XML_DIAMOND ))
339 nSymbolType = 1;
340 else if( IsXMLToken( aAttrValue, XML_ARROW_DOWN ))
341 nSymbolType = 2;
342 else if( IsXMLToken( aAttrValue, XML_ARROW_UP ))
343 nSymbolType = 3;
344 else if( IsXMLToken( aAttrValue, XML_ARROW_RIGHT ))
345 nSymbolType = 4;
346 else if( IsXMLToken( aAttrValue, XML_ARROW_LEFT ))
347 nSymbolType = 5;
348 else if( IsXMLToken( aAttrValue, XML_BOW_TIE ))
349 nSymbolType = 6;
350 else if( IsXMLToken( aAttrValue, XML_HOURGLASS ))
351 nSymbolType = 7;
352 else if( IsXMLToken( aAttrValue, XML_CIRCLE ))
353 nSymbolType = 8;
354 else if( IsXMLToken( aAttrValue, XML_STAR ))
355 nSymbolType = 9;
356 else if( IsXMLToken( aAttrValue, XML_X ))
357 nSymbolType = 10;
358 else if( IsXMLToken( aAttrValue, XML_PLUS ))
359 nSymbolType = 11;
360 else if( IsXMLToken( aAttrValue, XML_ASTERISK ))
361 nSymbolType = 12;
362 else if( IsXMLToken( aAttrValue, XML_HORIZONTAL_BAR ))
363 nSymbolType = 13;
364 else if( IsXMLToken( aAttrValue, XML_VERTICAL_BAR ))
365 nSymbolType = 14;
367 if( nSymbolType >= 0 )
368 pAttrList->AddAttribute(
369 GetTransformer().GetNamespaceMap().GetQNameByKey(
370 XML_NAMESPACE_CHART,
371 GetXMLToken( XML_SYMBOL )),
372 OUString::number( nSymbolType ));
374 break;
375 // #i25616#
376 case XML_OPTACTION_OPACITY:
377 aOpacityValueRemember = aAttrValue;
378 XMLTransformerBase::NegPercent(aOpacityValueRemember);
379 break;
381 // #i25616#
382 case XML_OPTACTION_IMAGE_OPACITY:
383 aImageOpacityValueRemember = aAttrValue;
384 XMLTransformerBase::NegPercent(aImageOpacityValueRemember);
385 break;
387 case XML_OPTACTION_KEEP_TOGETHER:
388 pAttrList->AddAttribute(
389 GetTransformer().GetNamespaceMap().GetQNameByKey(
390 XML_NAMESPACE_STYLE,GetXMLToken(XML_BREAK_INSIDE)),
391 GetXMLToken(
392 IsXMLToken( aAttrValue, XML_ALWAYS )
393 ? XML_COLUMNSPLIT_AVOID
394 : XML_AUTO ) );
395 break;
397 case XML_OPTACTION_CONTROL_TEXT_ALIGN:
398 if ( m_bControlStyle )
400 OUString aNewAttrQName(
401 GetTransformer().GetNamespaceMap().GetQNameByKey(
402 XML_NAMESPACE_STYLE,
403 ::xmloff::token::GetXMLToken(
404 XML_TEXT_ALIGN ) ) );
405 pAttrList->AddAttribute( aNewAttrQName, aAttrValue );
407 else
409 OUString aNewAttrQName(
410 GetTransformer().GetNamespaceMap().GetQNameByKey(
411 XML_NAMESPACE_FO,
412 ::xmloff::token::GetXMLToken(
413 XML_TEXT_ALIGN ) ) );
414 pAttrList->AddAttribute( aNewAttrQName, aAttrValue );
416 break;
418 case XML_ATACTION_CAPTION_ESCAPE_OASIS:
420 OUString aAttrValue2( aAttrValue );
421 if( aAttrValue2.indexOf( '%' ) != -1 )
423 sal_Int32 nValue = 0;
424 ::sax::Converter::convertPercent(nValue, aAttrValue);
425 if( nValue )
427 nValue *= 100;
428 OUStringBuffer aOut;
429 ::sax::Converter::convertPercent(aOut, nValue);
430 aAttrValue2 = aOut.makeStringAndClear();
433 else
435 XMLTransformerBase::ReplaceSingleInWithInch( aAttrValue2 );
438 pAttrList->AddAttribute( aAttrName, aAttrValue2 );
440 break;
442 case XML_ATACTION_DECODE_PROTECT:
444 pAttrList->AddAttribute( aAttrName, aAttrValue );
446 if( aAttrValue.indexOf( GetXMLToken( XML_SIZE ) ) != -1 )
447 pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
448 XML_NAMESPACE_DRAW,
449 GetXMLToken( XML_SIZE_PROTECT )), GetXMLToken( XML_TRUE ) );
451 if( aAttrValue.indexOf( GetXMLToken( XML_POSITION ) ) != -1 )
452 pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
453 XML_NAMESPACE_DRAW,
454 GetXMLToken( XML_MOVE_PROTECT )), GetXMLToken( XML_TRUE ) );
456 break;
458 case XML_ATACTION_DRAW_MIRROR_OASIS: // renames style:mirror to draw:mirror and adapts values
460 // keep original for writer graphic objects
461 // Adapts attribute values (#i49139#)
462 OUStringBuffer aNewAttrValue;
463 SvXMLTokenEnumerator aTokenEnum( aAttrValue );
464 std::u16string_view aToken;
465 while( aTokenEnum.getNextToken( aToken ) )
467 if ( !aNewAttrValue.isEmpty() )
469 aNewAttrValue.append(" ");
472 if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_EVEN ) )
474 aNewAttrValue.append(GetXMLToken( XML_HORIZONTAL_ON_LEFT_PAGES ));
476 else if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_ODD ) )
478 aNewAttrValue.append(GetXMLToken( XML_HORIZONTAL_ON_RIGHT_PAGES ));
480 else
482 aNewAttrValue.append(aToken);
485 pAttrList->AddAttribute( aAttrName, aNewAttrValue.makeStringAndClear() );
487 // create old draw:mirror for drawing graphic objects
488 const OUString& aAttrValue2( GetXMLToken( IsXMLToken( aAttrValue, XML_HORIZONTAL ) ? XML_TRUE : XML_FALSE ) );
489 pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
490 XML_NAMESPACE_DRAW,
491 GetXMLToken( XML_MIRROR )), aAttrValue2 );
493 break;
494 case XML_ATACTION_GAMMA_OASIS: // converts percentage value to double
496 sal_Int32 nValue;
497 ::sax::Converter::convertPercent( nValue, aAttrValue );
498 const double fValue = static_cast<double>(nValue) / 100.0;
499 pAttrList->AddAttribute( aAttrName, OUString::number( fValue ) );
501 break;
502 case XML_ATACTION_OPACITY_FIX:
504 sal_Int32 nValue;
505 if( aAttrValue.indexOf( '%' ) != -1 )
507 ::sax::Converter::convertPercent(nValue, aAttrValue);
509 else
511 nValue = sal_Int32( aAttrValue.toDouble() * 100.0 );
513 nValue = 100 - nValue;
515 OUStringBuffer aOut;
516 ::sax::Converter::convertPercent(aOut, nValue);
517 pAttrList->AddAttribute( aAttrName, aOut.makeStringAndClear() );
519 break;
520 default:
521 OSL_ENSURE( false, "unknown action" );
522 break;
525 else
527 pAttrList->AddAttribute( aAttrName, aAttrValue );
530 if( XML_TOKEN_END != eUnderline )
531 pAttrList->AddAttribute(
532 GetTransformer().GetNamespaceMap().GetQNameByKey(
533 XML_NAMESPACE_STYLE,
534 GetXMLToken( XML_TEXT_UNDERLINE ) ),
535 MergeUnderline( eUnderline, bBoldUnderline,
536 bDoubleUnderline ) );
537 if( XML_TOKEN_END != eLineThrough )
538 pAttrList->AddAttribute(
539 GetTransformer().GetNamespaceMap().GetQNameByKey(
540 XML_NAMESPACE_STYLE,
541 GetXMLToken( XML_TEXT_CROSSING_OUT ) ),
542 MergeLineThrough( eLineThrough, bBoldLineThrough,
543 bDoubleLineThrough, cLineThroughChar ) );
544 if( bIntervalMinorFound )
546 double fIntervalMinor = 0.0;
547 if( nIntervalMinorDivisor != 0)
548 fIntervalMinor = fIntervalMajor / static_cast< double >( nIntervalMinorDivisor );
550 OUStringBuffer aBuf;
551 ::sax::Converter::convertDouble( aBuf, fIntervalMinor );
552 pAttrList->AddAttribute(
553 GetTransformer().GetNamespaceMap().GetQNameByKey(
554 XML_NAMESPACE_CHART,
555 GetXMLToken( XML_INTERVAL_MINOR )),
556 aBuf.makeStringAndClear());
559 // #i25616#
560 if(!aOpacityValueRemember.isEmpty() || !aImageOpacityValueRemember.isEmpty())
562 pAttrList->AddAttribute(
563 GetTransformer().GetNamespaceMap().GetQNameByKey(
564 XML_NAMESPACE_DRAW,
565 GetXMLToken( XML_TRANSPARENCY ) ),
566 !aImageOpacityValueRemember.isEmpty()
567 ? aImageOpacityValueRemember : aOpacityValueRemember );
570 else
572 if( !m_xAttrList.is() )
574 m_xAttrList = new XMLMutableAttributeList( rAttrList, true );
576 else
578 m_xAttrList->AppendAttributeList( rAttrList );
583 void XMLPropertiesTContext_Impl::Export()
585 GetTransformer().GetDocHandler()->startElement( GetExportQName(), m_xAttrList );
586 ExportContent();
587 GetTransformer().GetDocHandler()->endElement( GetExportQName() );
590 XMLPropType XMLPropertiesTContext_Impl::GetPropType( std::u16string_view rLocalName )
592 XMLPropType eProp = XML_PROP_TYPE_END;
593 if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) )
594 eProp = XML_PROP_TYPE_GRAPHIC;
595 else if( IsXMLToken( rLocalName, XML_DRAWING_PAGE_PROPERTIES ) )
596 eProp = XML_PROP_TYPE_DRAWING_PAGE;
597 else if( IsXMLToken( rLocalName, XML_PAGE_LAYOUT_PROPERTIES ) )
598 eProp = XML_PROP_TYPE_PAGE_LAYOUT;
599 else if( IsXMLToken( rLocalName, XML_HEADER_FOOTER_PROPERTIES ) )
600 eProp = XML_PROP_TYPE_HEADER_FOOTER;
601 else if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) )
602 eProp = XML_PROP_TYPE_TEXT;
603 else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) )
604 eProp = XML_PROP_TYPE_PARAGRAPH;
605 else if( IsXMLToken( rLocalName, XML_RUBY_PROPERTIES ) )
606 eProp = XML_PROP_TYPE_RUBY;
607 else if( IsXMLToken( rLocalName, XML_SECTION_PROPERTIES ) )
608 eProp = XML_PROP_TYPE_SECTION;
609 else if( IsXMLToken( rLocalName, XML_TABLE_PROPERTIES ) )
610 eProp = XML_PROP_TYPE_TABLE;
611 else if( IsXMLToken( rLocalName, XML_TABLE_COLUMN_PROPERTIES ) )
612 eProp = XML_PROP_TYPE_TABLE_COLUMN;
613 else if( IsXMLToken( rLocalName, XML_TABLE_ROW_PROPERTIES ) )
614 eProp = XML_PROP_TYPE_TABLE_ROW;
615 else if( IsXMLToken( rLocalName, XML_TABLE_CELL_PROPERTIES ) )
616 eProp = XML_PROP_TYPE_TABLE_CELL;
617 else if( IsXMLToken( rLocalName, XML_LIST_LEVEL_PROPERTIES ) )
618 eProp = XML_PROP_TYPE_LIST_LEVEL;
619 else if( IsXMLToken( rLocalName, XML_CHART_PROPERTIES ) )
620 eProp = XML_PROP_TYPE_CHART;
622 return eProp;
625 OUString const & XMLPropertiesTContext_Impl::MergeUnderline(
626 XMLTokenEnum eUnderline, bool bBold, bool bDouble )
628 if( bDouble )
630 switch( eUnderline )
632 case XML_WAVE:
633 eUnderline = XML_DOUBLE_WAVE;
634 break;
635 default:
636 eUnderline = XML_DOUBLE;
637 break;
640 else if( bBold )
642 switch( eUnderline )
644 case XML_NONE:
645 case XML_SOLID:
646 eUnderline = XML_BOLD;
647 break;
648 case XML_DOTTED:
649 eUnderline = XML_BOLD_DOTTED;
650 break;
651 case XML_DASH:
652 eUnderline = XML_BOLD_DASH;
653 break;
654 case XML_LONG_DASH:
655 eUnderline = XML_BOLD_LONG_DASH;
656 break;
657 case XML_DOT_DASH:
658 eUnderline = XML_BOLD_DOT_DASH;
659 break;
660 case XML_DOT_DOT_DASH:
661 eUnderline = XML_BOLD_DOT_DOT_DASH;
662 break;
663 case XML_WAVE:
664 eUnderline = XML_BOLD_WAVE;
665 break;
666 default:
667 OSL_FAIL( "xmloff::XMLPropertiesTContext_Impl::MergeUnderline(), missing underline case!" );
668 break;
671 else
673 switch( eUnderline )
675 case XML_SOLID:
676 eUnderline = XML_SINGLE;
677 break;
678 case XML_NONE:
679 eUnderline = XML_NONE;
680 break;
681 default:
682 OSL_FAIL( "xmloff::XMLPropertiesTContext_Impl::MergeUnderline(), missing underline case!" );
683 break;
687 return GetXMLToken( eUnderline );
690 OUString const & XMLPropertiesTContext_Impl::MergeLineThrough(
691 XMLTokenEnum eLineThrough, bool bBold, bool bDouble,
692 sal_Unicode c )
694 if( c )
695 eLineThrough = c=='/' ? XML_SLASH : XML_uX;
696 else if( bDouble )
697 eLineThrough = XML_DOUBLE_LINE;
698 else if( bBold )
699 eLineThrough = XML_THICK_LINE;
700 else if( XML_NONE != eLineThrough )
701 eLineThrough = XML_SINGLE_LINE;
703 return GetXMLToken( eLineThrough );
706 XMLStyleOASISTContext::XMLStyleOASISTContext(XMLTransformerBase& rImp,
707 const OUString& rQName, bool bPersistent)
708 : XMLPersElemContentTContext(rImp, rQName)
709 , m_bPersistent(bPersistent)
710 , m_bControlStyle(false)
714 XMLStyleOASISTContext::XMLStyleOASISTContext(
715 XMLTransformerBase& rImp, const OUString& rQName,
716 sal_uInt16 nPrefix, ::xmloff::token::XMLTokenEnum eToken,
717 bool bPersistent)
718 : XMLPersElemContentTContext(rImp, rQName, nPrefix, eToken)
719 , m_bPersistent(bPersistent)
720 , m_bControlStyle(false)
724 XMLStyleOASISTContext::~XMLStyleOASISTContext()
728 rtl::Reference<XMLTransformerContext> XMLStyleOASISTContext::CreateChildContext(
729 sal_uInt16 nPrefix,
730 const OUString& rLocalName,
731 const OUString& rQName,
732 const Reference< XAttributeList >& rAttrList )
734 rtl::Reference<XMLTransformerContext> pContext;
736 if( XML_NAMESPACE_STYLE == nPrefix || XML_NAMESPACE_LO_EXT == nPrefix )
738 XMLPropType ePropType =
739 XMLPropertiesTContext_Impl::GetPropType( rLocalName );
740 if( XML_PROP_TYPE_END != ePropType )
742 // if no properties context exist start a new one.
743 if( !m_xPropContext.is() )
744 m_xPropContext = new XMLPropertiesTContext_Impl(
745 GetTransformer(), rQName, ePropType, m_bControlStyle );
746 else
747 m_xPropContext->SetQNameAndPropType( rQName, ePropType );
748 pContext = m_xPropContext;
751 if( !pContext.is() )
753 // if a properties context exist close it
754 if( m_xPropContext.is() && !m_bPersistent )
756 m_xPropContext->Export();
757 m_xPropContext = nullptr;
760 pContext = m_bPersistent
761 ? XMLPersElemContentTContext::CreateChildContext(
762 nPrefix, rLocalName, rQName, rAttrList )
763 : XMLTransformerContext::CreateChildContext(
764 nPrefix, rLocalName, rQName, rAttrList );
767 return pContext;
770 void XMLStyleOASISTContext::StartElement(
771 const Reference< XAttributeList >& rAttrList )
773 XMLTransformerActions *pActions =
774 GetTransformer().GetUserDefinedActions( OASIS_STYLE_ACTIONS );
775 OSL_ENSURE( pActions, "go no actions" );
777 Reference< XAttributeList > xAttrList( rAttrList );
778 rtl::Reference<XMLMutableAttributeList> pMutableAttrList;
779 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
780 sal_Int16 nFamilyAttr = -1;
781 m_bControlStyle = false;
783 for( sal_Int16 i=0; i < nAttrCount; i++ )
785 const OUString aAttrName = xAttrList->getNameByIndex( i );
786 OUString aLocalName;
787 sal_uInt16 nPrefix =
788 GetTransformer().GetNamespaceMap().GetKeyByAttrName( aAttrName,
789 &aLocalName );
790 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
791 XMLTransformerActions::const_iterator aIter =
792 pActions->find( aKey );
793 if( aIter != pActions->end() )
795 if( !pMutableAttrList )
797 pMutableAttrList =
798 new XMLMutableAttributeList( xAttrList );
799 xAttrList = pMutableAttrList;
801 const OUString aAttrValue = xAttrList->getValueByIndex( i );
802 switch( (*aIter).second.m_nActionType )
804 case XML_ATACTION_STYLE_FAMILY:
805 if( IsXMLToken( aAttrValue, XML_GRAPHIC ) )
807 pMutableAttrList->SetValueByIndex(
808 i, GetXMLToken(XML_GRAPHICS) );
810 else
812 if( IsXMLToken( aAttrValue, XML_PARAGRAPH ) )
813 nFamilyAttr = i;
816 break;
817 case XML_ATACTION_STYLE_DISPLAY_NAME:
818 case XML_ATACTION_REMOVE:
819 pMutableAttrList->RemoveAttributeByIndex( i );
820 --i;
821 --nAttrCount;
822 break;
823 case XML_ATACTION_DECODE_STYLE_NAME:
824 m_bControlStyle = aAttrValue.startsWith( "ctrl" );
825 [[fallthrough]];
826 case XML_ATACTION_DECODE_STYLE_NAME_REF:
828 OUString aAttrValue2( aAttrValue );
829 if( XMLTransformerBase::DecodeStyleName(aAttrValue2) )
830 pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
832 break;
833 case XML_ATACTION_IN2INCH:
835 OUString aAttrValue2( aAttrValue );
836 if( XMLTransformerBase::ReplaceSingleInWithInch(
837 aAttrValue2 ) )
838 pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
840 break;
841 case XML_ATACTION_NEG_PERCENT:
843 OUString aAttrValue2( aAttrValue );
844 if( XMLTransformerBase::NegPercent(aAttrValue2) )
845 pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
847 break;
848 case XML_ATACTION_URI_OASIS:
850 OUString aAttrValue2( aAttrValue );
851 if( GetTransformer().ConvertURIToOOo( aAttrValue2,
852 static_cast< bool >((*aIter).second.m_nParam1)))
853 pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
855 break;
856 default:
857 OSL_ENSURE( false, "unknown action" );
858 break;
863 if( m_bControlStyle && nFamilyAttr != -1 )
864 pMutableAttrList->SetValueByIndex( nFamilyAttr, GetXMLToken( XML_CONTROL ) );
866 if( m_bPersistent )
867 XMLPersElemContentTContext::StartElement( xAttrList );
868 else
869 GetTransformer().GetDocHandler()->startElement( GetExportQName(), xAttrList );
872 void XMLStyleOASISTContext::EndElement()
874 if( m_bPersistent )
876 XMLPersElemContentTContext::EndElement();
878 else
880 // if a properties context exist close it
881 if( m_xPropContext.is() )
883 m_xPropContext->Export();
884 m_xPropContext = nullptr;
886 GetTransformer().GetDocHandler()->endElement( GetExportQName() );
890 void XMLStyleOASISTContext::Characters( const OUString& )
892 // element content only:
895 void XMLStyleOASISTContext::ExportContent()
897 if( m_xPropContext.is() )
898 m_xPropContext->Export();
899 XMLPersElemContentTContext::ExportContent();
902 bool XMLStyleOASISTContext::IsPersistent() const
904 return m_bPersistent;
907 XMLTransformerActions *XMLStyleOASISTContext::CreateTransformerActions(
908 sal_uInt16 nType )
910 XMLTransformerActionInit const *pInit = nullptr;
912 switch( nType )
914 case PROP_OASIS_GRAPHIC_ATTR_ACTIONS:
915 pInit = aGraphicPropertyOASISAttrActionTable;
916 break;
917 case PROP_OASIS_DRAWING_PAGE_ATTR_ACTIONS:
918 pInit = aDrawingPagePropertyOASISAttrActionTable;
919 break;
920 case PROP_OASIS_PAGE_LAYOUT_ATTR_ACTIONS:
921 pInit = aPageLayoutPropertyOASISAttrActionTable;
922 break;
923 case PROP_OASIS_HEADER_FOOTER_ATTR_ACTIONS:
924 pInit = aHeaderFooterPropertyOASISAttrActionTable;
925 break;
926 case PROP_OASIS_TEXT_ATTR_ACTIONS:
927 pInit = aTextPropertyOASISAttrActionTable;
928 break;
929 case PROP_OASIS_PARAGRAPH_ATTR_ACTIONS:
930 pInit = aParagraphPropertyOASISAttrActionTable;
931 break;
932 case PROP_OASIS_SECTION_ATTR_ACTIONS:
933 pInit = aSectionPropertyOASISAttrActionTable;
934 break;
935 case PROP_OASIS_TABLE_ATTR_ACTIONS:
936 pInit = aTablePropertyOASISAttrActionTable;
937 break;
938 case PROP_OASIS_TABLE_COLUMN_ATTR_ACTIONS:
939 pInit = aTableColumnPropertyOASISAttrActionTable;
940 break;
941 case PROP_OASIS_TABLE_ROW_ATTR_ACTIONS:
942 pInit = aTableRowPropertyOASISAttrActionTable;
943 break;
944 case PROP_OASIS_TABLE_CELL_ATTR_ACTIONS:
945 pInit = aTableCellPropertyOASISAttrActionTable;
946 break;
947 case PROP_OASIS_LIST_LEVEL_ATTR_ACTIONS:
948 pInit = aListLevelPropertyOASISAttrActionTable;
949 break;
950 case PROP_OASIS_CHART_ATTR_ACTIONS:
951 pInit = aChartPropertyOASISAttrActionTable;
952 break;
955 XMLTransformerActions *pActions = nullptr;
956 if( pInit )
957 pActions = new XMLTransformerActions( pInit );
959 return pActions;
962 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */