1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include <com/sun/star/xml/sax/SAXParseException.hpp>
27 #include <com/sun/star/xml/sax/SAXException.hpp>
28 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
29 #include <com/sun/star/xml/sax/XAttributeList.hpp>
30 #include <rtl/ustrbuf.hxx>
31 #include <xmloff/nmspmap.hxx>
32 #include <xmloff/xmltoken.hxx>
33 #include "xmloff/xmlnmspe.hxx"
34 #include "PropType.hxx"
35 #include "DeepTContext.hxx"
36 #include "ProcAttrTContext.hxx"
37 #ifndef _XMLOFF_TRANSFOERMERBASE_HXX
38 #include "TransformerBase.hxx"
39 #endif
40 #include "TransformerActions.hxx"
41 #include "ActionMapTypesOASIS.hxx"
42 #include "MutableAttrList.hxx"
43 #include "PropertyActionsOASIS.hxx"
44 #include "StyleOASISTContext.hxx"
45 #include <xmloff/xmluconv.hxx>
46 #include <rtl/ustrbuf.hxx>
47
48 using ::rtl::OUString;
49 using namespace ::xmloff::token;
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star::xml::sax;
52 //------------------------------------------------------------------------------
53
54 static sal_uInt16 aAttrActionMaps[XML_PROP_TYPE_END] =
55 {
56 PROP_OASIS_GRAPHIC_ATTR_ACTIONS,
57 PROP_OASIS_DRAWING_PAGE_ATTR_ACTIONS, // DRAWING_PAGE
58 PROP_OASIS_PAGE_LAYOUT_ATTR_ACTIONS,
59 PROP_OASIS_HEADER_FOOTER_ATTR_ACTIONS,
60 PROP_OASIS_TEXT_ATTR_ACTIONS,
61 PROP_OASIS_PARAGRAPH_ATTR_ACTIONS,
62 MAX_OASIS_PROP_ACTIONS, // RUBY
63 PROP_OASIS_SECTION_ATTR_ACTIONS,
64 PROP_OASIS_TABLE_ATTR_ACTIONS,
65 PROP_OASIS_TABLE_COLUMN_ATTR_ACTIONS,
66 PROP_OASIS_TABLE_ROW_ATTR_ACTIONS,
67 PROP_OASIS_TABLE_CELL_ATTR_ACTIONS,
68 PROP_OASIS_LIST_LEVEL_ATTR_ACTIONS,
69 PROP_OASIS_CHART_ATTR_ACTIONS
70 };
71
72 //------------------------------------------------------------------------------
73
74 class XMLPropertiesTContext_Impl : public XMLPersElemContentTContext
75 {
76 ::com::sun::star::uno::Reference<
77 ::com::sun::star::xml::sax::XAttributeList > m_xAttrList;
78
79 XMLPropType m_ePropType;
80 sal_Bool m_bControlStyle;
81 ::rtl::OUString m_aStyleFamily;
82
83 public:
84
SetQNameAndPropType(const::rtl::OUString & rQName,XMLPropType ePropType)85 void SetQNameAndPropType( const ::rtl::OUString& rQName,
86 XMLPropType ePropType )
87 {
88 m_ePropType = ePropType;
89 XMLTransformerContext::SetQName( rQName );
90 };
91
92 TYPEINFO();
93
94 XMLPropertiesTContext_Impl( XMLTransformerBase& rTransformer,
95 const ::rtl::OUString& rQName,
96 XMLPropType eP,
97 const ::rtl::OUString& rStyleFamily,
98 sal_Bool _bControlStyle = sal_False );
99
100 virtual ~XMLPropertiesTContext_Impl();
101
102 virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
103
104 virtual void Export();
105
106 static XMLPropType GetPropType( const OUString& rLocalName );
107
108 static OUString MergeUnderline( XMLTokenEnum eUnderline,
109 sal_Bool bBold, sal_Bool bDouble );
110 static OUString MergeLineThrough( XMLTokenEnum eLineThrough,
111 sal_Bool bBold, sal_Bool bDouble,
112 sal_Unicode c );
113 };
114
115 TYPEINIT1( XMLPropertiesTContext_Impl, XMLPersElemContentTContext );
116
XMLPropertiesTContext_Impl(XMLTransformerBase & rImp,const OUString & rQName,XMLPropType eP,const::rtl::OUString & rStyleFamily,sal_Bool _bControlStyle)117 XMLPropertiesTContext_Impl::XMLPropertiesTContext_Impl(
118 XMLTransformerBase& rImp, const OUString& rQName, XMLPropType eP,
119 const ::rtl::OUString& rStyleFamily, sal_Bool _bControlStyle ) :
120 XMLPersElemContentTContext( rImp, rQName, XML_NAMESPACE_STYLE,
121 XML_PROPERTIES),
122 m_ePropType( eP ),
123 m_bControlStyle( _bControlStyle ),
124 m_aStyleFamily( rStyleFamily )
125 {
126 }
127
~XMLPropertiesTContext_Impl()128 XMLPropertiesTContext_Impl::~XMLPropertiesTContext_Impl()
129 {
130 }
131
StartElement(const Reference<XAttributeList> & rAttrList)132 void XMLPropertiesTContext_Impl::StartElement(
133 const Reference< XAttributeList >& rAttrList )
134 {
135 XMLTransformerActions *pActions = 0;
136 sal_uInt16 nActionMap = aAttrActionMaps[m_ePropType];
137 if( nActionMap < MAX_OASIS_PROP_ACTIONS )
138 {
139 pActions = GetTransformer().GetUserDefinedActions( nActionMap );
140 OSL_ENSURE( pActions, "go no actions" );
141 }
142
143 if( pActions )
144 {
145 XMLMutableAttributeList *pAttrList = 0;
146 if( !m_xAttrList.is() )
147 {
148 pAttrList = new XMLMutableAttributeList();
149 m_xAttrList = pAttrList;
150 }
151 else
152 {
153 pAttrList =
154 static_cast< XMLMutableAttributeList * >( m_xAttrList.get() );
155 }
156
157 XMLTokenEnum eUnderline = XML_TOKEN_END;
158 sal_Bool bBoldUnderline = sal_False, bDoubleUnderline = sal_False;
159 XMLTokenEnum eLineThrough = XML_TOKEN_END;
160 sal_Bool bBoldLineThrough = sal_False, bDoubleLineThrough = sal_False;
161 sal_Unicode cLineThroughChar = 0;
162
163 bool bIntervalMinorFound = false;
164 double fIntervalMajor = 0.0;
165 sal_Int32 nIntervalMinorDivisor = 0;
166
167 // #i25616#
168 OUString aOpacityValueRemember;
169 OUString aImageOpacityValueRemember;
170
171 sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
172 for( sal_Int16 i=0; i < nAttrCount; i++ )
173 {
174 const OUString& rAttrName = rAttrList->getNameByIndex( i );
175 const OUString& rAttrValue = rAttrList->getValueByIndex( i );
176 OUString aLocalName;
177 sal_uInt16 nPrefix =
178 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
179 &aLocalName );
180
181 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
182 XMLTransformerActions::const_iterator aIter =
183 pActions->find( aKey );
184 if( !(aIter == pActions->end() ) )
185 {
186 switch( (*aIter).second.m_nActionType )
187 {
188 case XML_ATACTION_REMOVE:
189 break;
190 case XML_ATACTION_COPY:
191 pAttrList->AddAttribute( rAttrName, rAttrValue );
192 break;
193 case XML_ATACTION_RENAME:
194 {
195 OUString aNewAttrQName(
196 GetTransformer().GetNamespaceMap().GetQNameByKey(
197 (*aIter).second.GetQNamePrefixFromParam1(),
198 ::xmloff::token::GetXMLToken(
199 (*aIter).second.GetQNameTokenFromParam1()) ) );
200 pAttrList->AddAttribute( aNewAttrQName, rAttrValue );
201 }
202 break;
203 case XML_ATACTION_IN2INCH:
204 {
205 OUString aAttrValue( rAttrValue );
206 XMLTransformerBase::ReplaceSingleInWithInch(
207 aAttrValue );
208 pAttrList->AddAttribute( rAttrName, aAttrValue );
209 }
210 break;
211 case XML_ATACTION_INS2INCHS:
212 {
213 OUString aAttrValue( rAttrValue );
214 XMLTransformerBase::ReplaceInWithInch(
215 aAttrValue );
216 pAttrList->AddAttribute( rAttrName, aAttrValue );
217 }
218 break;
219 case XML_ATACTION_DECODE_STYLE_NAME_REF:
220 {
221 OUString aAttrValue( rAttrValue );
222 GetTransformer().DecodeStyleName(aAttrValue);
223 pAttrList->AddAttribute( rAttrName, aAttrValue );
224 }
225 break;
226 case XML_ATACTION_RENAME_DECODE_STYLE_NAME_REF:
227 {
228 OUString aNewAttrQName(
229 GetTransformer().GetNamespaceMap().GetQNameByKey(
230 (*aIter).second.GetQNamePrefixFromParam1(),
231 ::xmloff::token::GetXMLToken(
232 (*aIter).second.GetQNameTokenFromParam1()) ) );
233 OUString aAttrValue( rAttrValue );
234 GetTransformer().DecodeStyleName(aAttrValue);
235 pAttrList->AddAttribute( aNewAttrQName, aAttrValue );
236 }
237 break;
238 case XML_ATACTION_NEG_PERCENT:
239 {
240 OUString aAttrValue( rAttrValue );
241 GetTransformer().NegPercent(aAttrValue);
242 pAttrList->AddAttribute( rAttrName, aAttrValue );
243 }
244 break;
245 case XML_ATACTION_RENAME_NEG_PERCENT:
246 {
247 OUString aNewAttrQName(
248 GetTransformer().GetNamespaceMap().GetQNameByKey(
249 (*aIter).second.GetQNamePrefixFromParam1(),
250 ::xmloff::token::GetXMLToken(
251 (*aIter).second.GetQNameTokenFromParam1()) ) );
252 OUString aAttrValue( rAttrValue );
253 GetTransformer().NegPercent(aAttrValue);
254 pAttrList->AddAttribute( aNewAttrQName, aAttrValue );
255 }
256 break;
257 case XML_OPTACTION_LINE_MODE:
258 {
259 sal_Bool bWordMode =
260 IsXMLToken( rAttrValue, XML_SKIP_WHITE_SPACE );
261 OUString aAttrQName(
262 GetTransformer().GetNamespaceMap().GetQNameByKey(
263 XML_NAMESPACE_FO,
264 GetXMLToken( XML_SCORE_SPACES ) ) );
265 sal_Int16 nIndex =
266 pAttrList->GetIndexByName( aAttrQName );
267 if( -1 != nIndex )
268 {
269 if( bWordMode )
270 {
271 const OUString& rOldValue =
272 pAttrList->getValueByIndex( nIndex );
273 if( !IsXMLToken( rOldValue, XML_TRUE ) )
274 {
275 pAttrList->SetValueByIndex( nIndex,
276 GetXMLToken( XML_TRUE ) );
277 }
278 }
279 }
280 else
281 {
282 OUString aAttrValue( GetXMLToken( bWordMode
283 ? XML_FALSE
284 : XML_TRUE ) );
285 pAttrList->AddAttribute( aAttrQName, aAttrValue );
286 }
287 }
288 break;
289 case XML_OPTACTION_KEEP_WITH_NEXT:
290 {
291 OUString aAttrValue( GetXMLToken(
292 IsXMLToken( rAttrValue, XML_ALWAYS )
293 ? XML_TRUE
294 : XML_FALSE) );
295 pAttrList->AddAttribute( rAttrName, aAttrValue );
296 }
297 break;
298 case XML_OPTACTION_UNDERLINE_WIDTH:
299 if( IsXMLToken( rAttrValue, XML_BOLD ) )
300 bBoldUnderline = sal_True;
301 break;
302 case XML_OPTACTION_UNDERLINE_TYPE:
303 if( IsXMLToken( rAttrValue, XML_DOUBLE ) )
304 bDoubleUnderline = sal_True;
305 break;
306 case XML_OPTACTION_UNDERLINE_STYLE:
307 eUnderline = GetTransformer().GetToken( rAttrValue );
308 break;
309 case XML_OPTACTION_LINETHROUGH_WIDTH:
310 if( IsXMLToken( rAttrValue, XML_BOLD ) )
311 bBoldLineThrough = sal_True;
312 break;
313 case XML_OPTACTION_LINETHROUGH_TYPE:
314 if( IsXMLToken( rAttrValue, XML_DOUBLE ) )
315 bDoubleLineThrough = sal_True;
316 break;
317 case XML_OPTACTION_LINETHROUGH_STYLE:
318 eLineThrough = GetTransformer().GetToken( rAttrValue );
319 break;
320 case XML_OPTACTION_LINETHROUGH_TEXT:
321 if( rAttrValue.getLength() )
322 cLineThroughChar = rAttrValue[0];
323 break;
324 case XML_OPTACTION_INTERPOLATION:
325 {
326 // 0: none
327 sal_Int32 nSplineType = 0;
328 if( IsXMLToken( rAttrValue, XML_CUBIC_SPLINE ))
329 nSplineType = 1;
330 else if( IsXMLToken( rAttrValue, XML_B_SPLINE ))
331 nSplineType = 2;
332
333 pAttrList->AddAttribute(
334 GetTransformer().GetNamespaceMap().GetQNameByKey(
335 XML_NAMESPACE_CHART,
336 GetXMLToken( XML_SPLINES )),
337 OUString::valueOf( nSplineType ));
338 }
339 break;
340 case XML_OPTACTION_INTERVAL_MAJOR:
341 pAttrList->AddAttribute( rAttrName, rAttrValue );
342 SvXMLUnitConverter::convertDouble( fIntervalMajor, rAttrValue );
343 break;
344 case XML_OPTACTION_INTERVAL_MINOR_DIVISOR:
345 SvXMLUnitConverter::convertNumber( nIntervalMinorDivisor, rAttrValue );
346 bIntervalMinorFound = true;
347 break;
348 case XML_OPTACTION_SYMBOL_TYPE:
349 {
350 // if symbol_type is "named-symbol" the "symbol"
351 // property is set in the action XML_OPTACTION_SYMBOL_NAME
352 sal_Int32 nSymbolType = 0;
353 if( IsXMLToken( rAttrValue, XML_NONE ))
354 nSymbolType = -3;
355 else if( IsXMLToken( rAttrValue, XML_AUTOMATIC ))
356 nSymbolType = -2;
357 else if( IsXMLToken( rAttrValue, XML_IMAGE ))
358 nSymbolType = -1;
359
360 if( nSymbolType < 0 )
361 pAttrList->AddAttribute(
362 GetTransformer().GetNamespaceMap().GetQNameByKey(
363 XML_NAMESPACE_CHART,
364 GetXMLToken( XML_SYMBOL )),
365 OUString::valueOf( nSymbolType ));
366 }
367 break;
368 case XML_OPTACTION_SYMBOL_NAME:
369 {
370 // assume "symbol-type" == "named-symbol"
371 sal_Int32 nSymbolType = -3; // NONE
372 // "square" just has an awkward token-name
373 if( IsXMLToken( rAttrValue, XML_GRADIENTSTYLE_SQUARE ))
374 nSymbolType = 0;
375 else if( IsXMLToken( rAttrValue, XML_DIAMOND ))
376 nSymbolType = 1;
377 else if( IsXMLToken( rAttrValue, XML_ARROW_DOWN ))
378 nSymbolType = 2;
379 else if( IsXMLToken( rAttrValue, XML_ARROW_UP ))
380 nSymbolType = 3;
381 else if( IsXMLToken( rAttrValue, XML_ARROW_RIGHT ))
382 nSymbolType = 4;
383 else if( IsXMLToken( rAttrValue, XML_ARROW_LEFT ))
384 nSymbolType = 5;
385 else if( IsXMLToken( rAttrValue, XML_BOW_TIE ))
386 nSymbolType = 6;
387 else if( IsXMLToken( rAttrValue, XML_HOURGLASS ))
388 nSymbolType = 7;
389 else if( IsXMLToken( rAttrValue, XML_CIRCLE ))
390 nSymbolType = 8;
391 else if( IsXMLToken( rAttrValue, XML_STAR ))
392 nSymbolType = 9;
393 else if( IsXMLToken( rAttrValue, XML_X ))
394 nSymbolType = 10;
395 else if( IsXMLToken( rAttrValue, XML_PLUS ))
396 nSymbolType = 11;
397 else if( IsXMLToken( rAttrValue, XML_ASTERISK ))
398 nSymbolType = 12;
399 else if( IsXMLToken( rAttrValue, XML_HORIZONTAL_BAR ))
400 nSymbolType = 13;
401 else if( IsXMLToken( rAttrValue, XML_VERTICAL_BAR ))
402 nSymbolType = 14;
403
404 if( nSymbolType >= 0 )
405 pAttrList->AddAttribute(
406 GetTransformer().GetNamespaceMap().GetQNameByKey(
407 XML_NAMESPACE_CHART,
408 GetXMLToken( XML_SYMBOL )),
409 OUString::valueOf( nSymbolType ));
410 }
411 break;
412 // #i25616#
413 case XML_OPTACTION_OPACITY:
414 aOpacityValueRemember = rAttrValue;
415 GetTransformer().NegPercent(aOpacityValueRemember);
416 break;
417
418 // #i25616#
419 case XML_OPTACTION_IMAGE_OPACITY:
420 aImageOpacityValueRemember = rAttrValue;
421 GetTransformer().NegPercent(aImageOpacityValueRemember);
422 break;
423
424 case XML_OPTACTION_KEEP_TOGETHER:
425 pAttrList->AddAttribute(
426 GetTransformer().GetNamespaceMap().GetQNameByKey(
427 XML_NAMESPACE_STYLE,GetXMLToken(XML_BREAK_INSIDE)),
428 GetXMLToken(
429 IsXMLToken( rAttrValue, XML_ALWAYS )
430 ? XML_COLUMNSPLIT_AVOID
431 : XML_COLUMNSPLIT_AUTO ) );
432 break;
433
434 case XML_OPTACTION_CONTROL_TEXT_ALIGN:
435 if ( m_bControlStyle )
436 {
437 OUString aNewAttrQName(
438 GetTransformer().GetNamespaceMap().GetQNameByKey(
439 XML_NAMESPACE_STYLE,
440 ::xmloff::token::GetXMLToken(
441 XML_TEXT_ALIGN ) ) );
442 pAttrList->AddAttribute( aNewAttrQName, rAttrValue );
443 }
444 else
445 {
446 OUString aNewAttrQName(
447 GetTransformer().GetNamespaceMap().GetQNameByKey(
448 XML_NAMESPACE_FO,
449 ::xmloff::token::GetXMLToken(
450 XML_TEXT_ALIGN ) ) );
451 pAttrList->AddAttribute( aNewAttrQName, rAttrValue );
452 }
453 break;
454
455 case XML_OPTACTION_DRAW_WRITING_MODE:
456 if( IsXMLToken( m_aStyleFamily, XML_GRAPHICS ) )
457 {
458 pAttrList->AddAttribute(
459 GetTransformer().GetNamespaceMap().GetQNameByKey(
460 XML_NAMESPACE_DRAW,
461 GetXMLToken( XML_WRITING_MODE ) ), rAttrValue );
462 }
463 pAttrList->AddAttribute( rAttrName, rAttrValue );
464 break;
465
466 case XML_ATACTION_CAPTION_ESCAPE_OASIS:
467 {
468 OUString aAttrValue( rAttrValue );
469 if( aAttrValue.indexOf( sal_Unicode('%') ) != -1 )
470 {
471 sal_Int32 nValue = 0;
472 SvXMLUnitConverter::convertPercent( nValue, rAttrValue );
473 if( nValue )
474 {
475 nValue *= 100;
476 rtl::OUStringBuffer aOut;
477 SvXMLUnitConverter::convertPercent( aOut, nValue );
478 aAttrValue = aOut.makeStringAndClear();
479 }
480 }
481 else
482 {
483 XMLTransformerBase::ReplaceSingleInWithInch( aAttrValue );
484 }
485
486 pAttrList->AddAttribute( rAttrName, aAttrValue );
487 }
488 break;
489
490 case XML_ATACTION_DECODE_PROTECT:
491 {
492 pAttrList->AddAttribute( rAttrName, rAttrValue );
493
494 if( rAttrValue.indexOf( GetXMLToken( XML_SIZE ) ) != -1 )
495 pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
496 XML_NAMESPACE_DRAW,
497 GetXMLToken( XML_SIZE_PROTECT )), GetXMLToken( XML_TRUE ) );
498
499 if( rAttrValue.indexOf( GetXMLToken( XML_POSITION ) ) != -1 )
500 pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
501 XML_NAMESPACE_DRAW,
502 GetXMLToken( XML_MOVE_PROTECT )), GetXMLToken( XML_TRUE ) );
503 }
504 break;
505
506 case XML_ATACTION_DRAW_MIRROR_OASIS: // renames style:mirror to draw:mirror and adapts values
507 {
508 // keep original for writer graphic objects
509 // --> OD 2005-05-12 #i49139# - adapts attribute values,
510 OUString aNewAttrValue;
511 SvXMLTokenEnumerator aTokenEnum( rAttrValue );
512 OUString aToken;
513 while( aTokenEnum.getNextToken( aToken ) )
514 {
515 if ( aNewAttrValue.getLength() > 0 )
516 {
517 aNewAttrValue += rtl::OUString::createFromAscii( " " );
518 }
519
520 if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_EVEN ) )
521 {
522 aNewAttrValue += GetXMLToken( XML_HORIZONTAL_ON_LEFT_PAGES );
523 }
524 else if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_ODD ) )
525 {
526 aNewAttrValue += GetXMLToken( XML_HORIZONTAL_ON_RIGHT_PAGES );
527 }
528 else
529 {
530 aNewAttrValue += aToken;
531 }
532 }
533 pAttrList->AddAttribute( rAttrName, aNewAttrValue );
534 // <--
535
536 // create old draw:mirror for drawing graphic objects
537 OUString aAttrValue( GetXMLToken( IsXMLToken( rAttrValue, XML_HORIZONTAL ) ? XML_TRUE : XML_FALSE ) );
538 pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
539 XML_NAMESPACE_DRAW,
540 GetXMLToken( XML_MIRROR )), aAttrValue );
541 }
542 break;
543 case XML_ATACTION_GAMMA_OASIS: // converts percentage value to double
544 {
545 sal_Int32 nValue;
546 SvXMLUnitConverter::convertPercent( nValue, rAttrValue );
547 const double fValue = ((double)nValue) / 100.0;
548 pAttrList->AddAttribute( rAttrName, OUString::valueOf( fValue ) );
549 }
550 break;
551 case XML_ATACTION_OPACITY_FIX:
552 {
553 sal_Int32 nValue;
554 if( rAttrValue.indexOf( sal_Unicode('%') ) != -1 )
555 {
556 SvXMLUnitConverter::convertPercent( nValue, rAttrValue );
557 }
558 else
559 {
560 nValue = sal_Int32( rAttrValue.toDouble() * 100.0 );
561 }
562 nValue = 100 - nValue;
563
564 rtl::OUStringBuffer aOut;
565 SvXMLUnitConverter::convertPercent( aOut, nValue );
566 pAttrList->AddAttribute( rAttrName, aOut.makeStringAndClear() );
567 }
568 break;
569 default:
570 OSL_ENSURE( !this, "unknown action" );
571 break;
572 }
573 }
574 else
575 {
576 pAttrList->AddAttribute( rAttrName, rAttrValue );
577 }
578 }
579 if( XML_TOKEN_END != eUnderline )
580 pAttrList->AddAttribute(
581 GetTransformer().GetNamespaceMap().GetQNameByKey(
582 XML_NAMESPACE_STYLE,
583 GetXMLToken( XML_TEXT_UNDERLINE ) ),
584 MergeUnderline( eUnderline, bBoldUnderline,
585 bDoubleUnderline ) );
586 if( XML_TOKEN_END != eLineThrough )
587 pAttrList->AddAttribute(
588 GetTransformer().GetNamespaceMap().GetQNameByKey(
589 XML_NAMESPACE_STYLE,
590 GetXMLToken( XML_TEXT_CROSSING_OUT ) ),
591 MergeLineThrough( eLineThrough, bBoldLineThrough,
592 bDoubleLineThrough, cLineThroughChar ) );
593 if( bIntervalMinorFound )
594 {
595 double fIntervalMinor = 0.0;
596 if( nIntervalMinorDivisor != 0)
597 fIntervalMinor = fIntervalMajor / static_cast< double >( nIntervalMinorDivisor );
598
599 ::rtl::OUStringBuffer aBuf;
600 SvXMLUnitConverter::convertDouble( aBuf, fIntervalMinor );
601 pAttrList->AddAttribute(
602 GetTransformer().GetNamespaceMap().GetQNameByKey(
603 XML_NAMESPACE_CHART,
604 GetXMLToken( XML_INTERVAL_MINOR )),
605 aBuf.makeStringAndClear());
606 }
607
608 // #i25616#
609 if(aOpacityValueRemember.getLength() || aImageOpacityValueRemember.getLength())
610 {
611 pAttrList->AddAttribute(
612 GetTransformer().GetNamespaceMap().GetQNameByKey(
613 XML_NAMESPACE_DRAW,
614 GetXMLToken( XML_TRANSPARENCY ) ),
615 aImageOpacityValueRemember.getLength()
616 ? aImageOpacityValueRemember : aOpacityValueRemember );
617 }
618 }
619 else
620 {
621 if( !m_xAttrList.is() )
622 {
623 m_xAttrList = new XMLMutableAttributeList( rAttrList, sal_True );
624 }
625 else
626 {
627 static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
628 ->AppendAttributeList( rAttrList );
629 }
630 }
631 }
632
Export()633 void XMLPropertiesTContext_Impl::Export()
634 {
635 OUString aNewQName( GetTransformer().GetNamespaceMap().GetQNameByKey(
636 XML_NAMESPACE_STYLE,
637 ::xmloff::token::GetXMLToken( XML_PROPERTIES ) ) );
638 GetTransformer().GetDocHandler()->startElement( GetExportQName(),
639 m_xAttrList );
640 ExportContent();
641 GetTransformer().GetDocHandler()->endElement( GetExportQName() );
642 }
643
GetPropType(const OUString & rLocalName)644 XMLPropType XMLPropertiesTContext_Impl::GetPropType( const OUString& rLocalName )
645 {
646 XMLPropType eProp = XML_PROP_TYPE_END;
647 if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) )
648 eProp = XML_PROP_TYPE_GRAPHIC;
649 else if( IsXMLToken( rLocalName, XML_DRAWING_PAGE_PROPERTIES ) )
650 eProp = XML_PROP_TYPE_DRAWING_PAGE;
651 else if( IsXMLToken( rLocalName, XML_PAGE_LAYOUT_PROPERTIES ) )
652 eProp = XML_PROP_TYPE_PAGE_LAYOUT;
653 else if( IsXMLToken( rLocalName, XML_HEADER_FOOTER_PROPERTIES ) )
654 eProp = XML_PROP_TYPE_HEADER_FOOTER;
655 else if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) )
656 eProp = XML_PROP_TYPE_TEXT;
657 else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) )
658 eProp = XML_PROP_TYPE_PARAGRAPH;
659 else if( IsXMLToken( rLocalName, XML_RUBY_PROPERTIES ) )
660 eProp = XML_PROP_TYPE_RUBY;
661 else if( IsXMLToken( rLocalName, XML_SECTION_PROPERTIES ) )
662 eProp = XML_PROP_TYPE_SECTION;
663 else if( IsXMLToken( rLocalName, XML_TABLE_PROPERTIES ) )
664 eProp = XML_PROP_TYPE_TABLE;
665 else if( IsXMLToken( rLocalName, XML_TABLE_COLUMN_PROPERTIES ) )
666 eProp = XML_PROP_TYPE_TABLE_COLUMN;
667 else if( IsXMLToken( rLocalName, XML_TABLE_ROW_PROPERTIES ) )
668 eProp = XML_PROP_TYPE_TABLE_ROW;
669 else if( IsXMLToken( rLocalName, XML_TABLE_CELL_PROPERTIES ) )
670 eProp = XML_PROP_TYPE_TABLE_CELL;
671 else if( IsXMLToken( rLocalName, XML_LIST_LEVEL_PROPERTIES ) )
672 eProp = XML_PROP_TYPE_LIST_LEVEL;
673 else if( IsXMLToken( rLocalName, XML_CHART_PROPERTIES ) )
674 eProp = XML_PROP_TYPE_CHART;
675
676 return eProp;
677 }
678
MergeUnderline(XMLTokenEnum eUnderline,sal_Bool bBold,sal_Bool bDouble)679 OUString XMLPropertiesTContext_Impl::MergeUnderline(
680 XMLTokenEnum eUnderline, sal_Bool bBold, sal_Bool bDouble )
681 {
682 if( bDouble )
683 {
684 switch( eUnderline )
685 {
686 case XML_WAVE:
687 eUnderline = XML_DOUBLE_WAVE;
688 break;
689 default:
690 eUnderline = XML_DOUBLE;
691 break;
692 }
693 }
694 else if( bBold )
695 {
696 switch( eUnderline )
697 {
698 case XML_NONE:
699 case XML_SOLID:
700 eUnderline = XML_BOLD;
701 break;
702 case XML_DOTTED:
703 eUnderline = XML_BOLD_DOTTED;
704 break;
705 case XML_DASH:
706 eUnderline = XML_BOLD_DASH;
707 break;
708 case XML_LONG_DASH:
709 eUnderline = XML_BOLD_LONG_DASH;
710 break;
711 case XML_DOT_DASH:
712 eUnderline = XML_BOLD_DOT_DASH;
713 break;
714 case XML_DOT_DOT_DASH:
715 eUnderline = XML_BOLD_DOT_DOT_DASH;
716 break;
717 case XML_WAVE:
718 eUnderline = XML_BOLD_WAVE;
719 break;
720 default:
721 OSL_ENSURE( false, "xmloff::XMLPropertiesTContext_Impl::MergeUnderline(), missing underline case!" );
722 break;
723 }
724 }
725 else
726 {
727 switch( eUnderline )
728 {
729 case XML_SOLID:
730 eUnderline = XML_SINGLE;
731 break;
732 case XML_NONE:
733 eUnderline = XML_NONE;
734 break;
735 default:
736 OSL_ENSURE( false, "xmloff::XMLPropertiesTContext_Impl::MergeUnderline(), missing underline case!" );
737 break;
738 }
739 }
740
741 return GetXMLToken( eUnderline );
742 }
743
MergeLineThrough(XMLTokenEnum eLineThrough,sal_Bool bBold,sal_Bool bDouble,sal_Unicode c)744 OUString XMLPropertiesTContext_Impl::MergeLineThrough(
745 XMLTokenEnum eLineThrough, sal_Bool bBold, sal_Bool bDouble,
746 sal_Unicode c )
747 {
748 if( c )
749 eLineThrough = c=='/' ? XML_SLASH : XML_uX;
750 else if( bDouble )
751 eLineThrough = XML_DOUBLE_LINE;
752 else if( bBold )
753 eLineThrough = XML_THICK_LINE;
754 else if( XML_NONE != eLineThrough )
755 eLineThrough = XML_SINGLE_LINE;
756
757 return GetXMLToken( eLineThrough );
758 }
759
760 //------------------------------------------------------------------------------
761
762 TYPEINIT1( XMLStyleOASISTContext, XMLPersElemContentTContext );
763
XMLStyleOASISTContext(XMLTransformerBase & rImp,const OUString & rQName,sal_Bool bPersistent)764 XMLStyleOASISTContext::XMLStyleOASISTContext( XMLTransformerBase& rImp,
765 const OUString& rQName,
766 sal_Bool bPersistent ) :
767 XMLPersElemContentTContext ( rImp, rQName ),
768 m_bPersistent( bPersistent ),
769 m_bControlStyle( false )
770 {
771 }
772
XMLStyleOASISTContext(XMLTransformerBase & rImp,const OUString & rQName,sal_uInt16 nPrefix,::xmloff::token::XMLTokenEnum eToken,sal_Bool bPersistent)773 XMLStyleOASISTContext::XMLStyleOASISTContext(
774 XMLTransformerBase& rImp,
775 const OUString& rQName,
776 sal_uInt16 nPrefix,
777 ::xmloff::token::XMLTokenEnum eToken,
778 sal_Bool bPersistent ) :
779 XMLPersElemContentTContext( rImp, rQName, nPrefix, eToken ),
780 m_bPersistent( bPersistent )
781 {
782 }
783
~XMLStyleOASISTContext()784 XMLStyleOASISTContext::~XMLStyleOASISTContext()
785 {
786 }
787
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const OUString & rQName,const Reference<XAttributeList> & rAttrList)788 XMLTransformerContext *XMLStyleOASISTContext::CreateChildContext(
789 sal_uInt16 nPrefix,
790 const OUString& rLocalName,
791 const OUString& rQName,
792 const Reference< XAttributeList >& rAttrList )
793 {
794 XMLTransformerContext *pContext = 0;
795
796 if( XML_NAMESPACE_STYLE == nPrefix )
797 {
798 XMLPropType ePropType =
799 XMLPropertiesTContext_Impl::GetPropType( rLocalName );
800 if( XML_PROP_TYPE_END != ePropType )
801 {
802 // if no properties context exist start a new one.
803 if( !m_xPropContext.is() )
804 m_xPropContext = new XMLPropertiesTContext_Impl(
805 GetTransformer(), rQName, ePropType, m_aStyleFamily, m_bControlStyle );
806 else
807 m_xPropContext->SetQNameAndPropType( rQName, ePropType );
808 pContext = m_xPropContext.get();
809 }
810 }
811 if( !pContext )
812 {
813 // if a properties context exist close it
814 if( m_xPropContext.is() && !m_bPersistent )
815 {
816 m_xPropContext->Export();
817 m_xPropContext = 0;
818 }
819
820 pContext = m_bPersistent
821 ? XMLPersElemContentTContext::CreateChildContext(
822 nPrefix, rLocalName, rQName, rAttrList )
823 : XMLTransformerContext::CreateChildContext(
824 nPrefix, rLocalName, rQName, rAttrList );
825 }
826
827 return pContext;
828 }
829
StartElement(const Reference<XAttributeList> & rAttrList)830 void XMLStyleOASISTContext::StartElement(
831 const Reference< XAttributeList >& rAttrList )
832 {
833 XMLTransformerActions *pActions =
834 GetTransformer().GetUserDefinedActions( OASIS_STYLE_ACTIONS );
835 OSL_ENSURE( pActions, "go no actions" );
836
837 Reference< XAttributeList > xAttrList( rAttrList );
838 XMLMutableAttributeList *pMutableAttrList = 0;
839 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
840 sal_Int16 nFamilyAttr = -1;
841 m_bControlStyle = sal_False;
842
843 for( sal_Int16 i=0; i < nAttrCount; i++ )
844 {
845 const OUString& rAttrName = xAttrList->getNameByIndex( i );
846 OUString aLocalName;
847 sal_uInt16 nPrefix =
848 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
849 &aLocalName );
850 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
851 XMLTransformerActions::const_iterator aIter =
852 pActions->find( aKey );
853 if( !(aIter == pActions->end() ) )
854 {
855 if( !pMutableAttrList )
856 {
857 pMutableAttrList =
858 new XMLMutableAttributeList( xAttrList );
859 xAttrList = pMutableAttrList;
860 }
861 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
862 switch( (*aIter).second.m_nActionType )
863 {
864 case XML_ATACTION_STYLE_FAMILY:
865 if( IsXMLToken( rAttrValue, XML_GRAPHIC ) )
866 {
867 m_aStyleFamily = GetXMLToken( XML_GRAPHICS ) ;
868 pMutableAttrList->SetValueByIndex( i, m_aStyleFamily );
869 }
870 else
871 {
872 m_aStyleFamily = rAttrValue;
873
874 if( IsXMLToken( rAttrValue, XML_PARAGRAPH ) )
875 nFamilyAttr = i;
876 }
877
878 break;
879 case XML_ATACTION_STYLE_DISPLAY_NAME:
880 case XML_ATACTION_REMOVE:
881 pMutableAttrList->RemoveAttributeByIndex( i );
882 --i;
883 --nAttrCount;
884 break;
885 case XML_ATACTION_DECODE_STYLE_NAME:
886 m_bControlStyle = 0 == rAttrValue.compareToAscii( "ctrl", 4 );
887 case XML_ATACTION_DECODE_STYLE_NAME_REF:
888 {
889 OUString aAttrValue( rAttrValue );
890 if( GetTransformer().DecodeStyleName(aAttrValue) )
891 pMutableAttrList->SetValueByIndex( i, aAttrValue );
892 }
893 break;
894 case XML_ATACTION_IN2INCH:
895 {
896 OUString aAttrValue( rAttrValue );
897 if( XMLTransformerBase::ReplaceSingleInWithInch(
898 aAttrValue ) )
899 pMutableAttrList->SetValueByIndex( i, aAttrValue );
900 }
901 break;
902 case XML_ATACTION_NEG_PERCENT:
903 {
904 OUString aAttrValue( rAttrValue );
905 if( GetTransformer().NegPercent(aAttrValue) )
906 pMutableAttrList->SetValueByIndex( i, aAttrValue );
907 }
908 break;
909 case XML_ATACTION_URI_OASIS:
910 {
911 OUString aAttrValue( rAttrValue );
912 if( GetTransformer().ConvertURIToOOo( aAttrValue,
913 static_cast< sal_Bool >((*aIter).second.m_nParam1)))
914 pMutableAttrList->SetValueByIndex( i, aAttrValue );
915 }
916 break;
917 default:
918 OSL_ENSURE( !this, "unknown action" );
919 break;
920 }
921 }
922 }
923
924 if( m_bControlStyle && nFamilyAttr != -1 )
925 pMutableAttrList->SetValueByIndex( nFamilyAttr, GetXMLToken( XML_CONTROL ) );
926
927
928 if( m_bPersistent )
929 XMLPersElemContentTContext::StartElement( xAttrList );
930 else
931 GetTransformer().GetDocHandler()->startElement( GetExportQName(),
932 xAttrList );
933 }
934
EndElement()935 void XMLStyleOASISTContext::EndElement()
936 {
937 if( m_bPersistent )
938 {
939 XMLPersElemContentTContext::EndElement();
940 }
941 else
942 {
943 // if a properties context exist close it
944 if( m_xPropContext.is() )
945 {
946 m_xPropContext->Export();
947 m_xPropContext = 0;
948 }
949 GetTransformer().GetDocHandler()->endElement( GetExportQName() );
950 }
951 }
952
Characters(const OUString &)953 void XMLStyleOASISTContext::Characters( const OUString& )
954 {
955 // element content only:
956 }
957
ExportContent()958 void XMLStyleOASISTContext::ExportContent()
959 {
960 if( m_xPropContext.is() )
961 m_xPropContext->Export();
962 XMLPersElemContentTContext::ExportContent();
963 }
964
IsPersistent() const965 sal_Bool XMLStyleOASISTContext::IsPersistent() const
966 {
967 return m_bPersistent;
968 }
969
CreateTransformerActions(sal_uInt16 nType)970 XMLTransformerActions *XMLStyleOASISTContext::CreateTransformerActions(
971 sal_uInt16 nType )
972 {
973 XMLTransformerActionInit *pInit = 0;
974
975 switch( nType )
976 {
977 case PROP_OASIS_GRAPHIC_ATTR_ACTIONS:
978 pInit = aGraphicPropertyOASISAttrActionTable;
979 break;
980 case PROP_OASIS_DRAWING_PAGE_ATTR_ACTIONS:
981 pInit = aDrawingPagePropertyOASISAttrActionTable;
982 break;
983 case PROP_OASIS_PAGE_LAYOUT_ATTR_ACTIONS:
984 pInit = aPageLayoutPropertyOASISAttrActionTable;
985 break;
986 case PROP_OASIS_HEADER_FOOTER_ATTR_ACTIONS:
987 pInit = aHeaderFooterPropertyOASISAttrActionTable;
988 break;
989 case PROP_OASIS_TEXT_ATTR_ACTIONS:
990 pInit = aTextPropertyOASISAttrActionTable;
991 break;
992 case PROP_OASIS_PARAGRAPH_ATTR_ACTIONS:
993 pInit = aParagraphPropertyOASISAttrActionTable;
994 break;
995 case PROP_OASIS_SECTION_ATTR_ACTIONS:
996 pInit = aSectionPropertyOASISAttrActionTable;
997 break;
998 case PROP_OASIS_TABLE_ATTR_ACTIONS:
999 pInit = aTablePropertyOASISAttrActionTable;
1000 break;
1001 case PROP_OASIS_TABLE_COLUMN_ATTR_ACTIONS:
1002 pInit = aTableColumnPropertyOASISAttrActionTable;
1003 break;
1004 case PROP_OASIS_TABLE_ROW_ATTR_ACTIONS:
1005 pInit = aTableRowPropertyOASISAttrActionTable;
1006 break;
1007 case PROP_OASIS_TABLE_CELL_ATTR_ACTIONS:
1008 pInit = aTableCellPropertyOASISAttrActionTable;
1009 break;
1010 case PROP_OASIS_LIST_LEVEL_ATTR_ACTIONS:
1011 pInit = aListLevelPropertyOASISAttrActionTable;
1012 break;
1013 case PROP_OASIS_CHART_ATTR_ACTIONS:
1014 pInit = aChartPropertyOASISAttrActionTable;
1015 break;
1016 }
1017
1018 XMLTransformerActions *pActions = 0;
1019 if( pInit )
1020 pActions = new XMLTransformerActions( pInit );
1021
1022 return pActions;
1023 }
1024