xref: /AOO41X/main/xmloff/source/transform/StyleOASISTContext.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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 
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 
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 
128 XMLPropertiesTContext_Impl::~XMLPropertiesTContext_Impl()
129 {
130 }
131 
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 
390                         if( nSymbolType >= 0 )
391                             pAttrList->AddAttribute(
392                                 GetTransformer().GetNamespaceMap().GetQNameByKey(
393                                     XML_NAMESPACE_CHART,
394                                     GetXMLToken( XML_SYMBOL )),
395                                 OUString::valueOf( nSymbolType ));
396                     }
397                     break;
398                 // #i25616#
399                 case XML_OPTACTION_OPACITY:
400                     aOpacityValueRemember = rAttrValue;
401                     GetTransformer().NegPercent(aOpacityValueRemember);
402                     break;
403 
404                 // #i25616#
405                 case XML_OPTACTION_IMAGE_OPACITY:
406                     aImageOpacityValueRemember = rAttrValue;
407                     GetTransformer().NegPercent(aImageOpacityValueRemember);
408                     break;
409 
410                 case XML_OPTACTION_KEEP_TOGETHER:
411                     pAttrList->AddAttribute(
412                         GetTransformer().GetNamespaceMap().GetQNameByKey(
413                             XML_NAMESPACE_STYLE,GetXMLToken(XML_BREAK_INSIDE)),
414                         GetXMLToken(
415                             IsXMLToken( rAttrValue, XML_ALWAYS )
416                             ? XML_COLUMNSPLIT_AVOID
417                             : XML_COLUMNSPLIT_AUTO ) );
418                     break;
419 
420                 case XML_OPTACTION_CONTROL_TEXT_ALIGN:
421                     if ( m_bControlStyle )
422                     {
423                         OUString aNewAttrQName(
424                             GetTransformer().GetNamespaceMap().GetQNameByKey(
425                                 XML_NAMESPACE_STYLE,
426                                 ::xmloff::token::GetXMLToken(
427                                 XML_TEXT_ALIGN ) ) );
428                         pAttrList->AddAttribute( aNewAttrQName, rAttrValue );
429                     }
430                     else
431                     {
432                         OUString aNewAttrQName(
433                             GetTransformer().GetNamespaceMap().GetQNameByKey(
434                                 XML_NAMESPACE_FO,
435                                 ::xmloff::token::GetXMLToken(
436                                 XML_TEXT_ALIGN ) ) );
437                         pAttrList->AddAttribute( aNewAttrQName, rAttrValue );
438                     }
439                     break;
440 
441                 case XML_OPTACTION_DRAW_WRITING_MODE:
442                     if( IsXMLToken( m_aStyleFamily, XML_GRAPHICS ) )
443                     {
444                         pAttrList->AddAttribute(
445                             GetTransformer().GetNamespaceMap().GetQNameByKey(
446                                     XML_NAMESPACE_DRAW,
447                                     GetXMLToken( XML_WRITING_MODE ) ), rAttrValue );
448                     }
449                     pAttrList->AddAttribute( rAttrName, rAttrValue );
450                     break;
451 
452                 case XML_ATACTION_CAPTION_ESCAPE_OASIS:
453                     {
454                         OUString aAttrValue( rAttrValue );
455                         if( aAttrValue.indexOf( sal_Unicode('%') ) != -1 )
456                         {
457                             sal_Int32 nValue = 0;
458                             SvXMLUnitConverter::convertPercent( nValue, rAttrValue );
459                             if( nValue )
460                             {
461                                 nValue *= 100;
462                                 rtl::OUStringBuffer aOut;
463                                 SvXMLUnitConverter::convertPercent( aOut, nValue );
464                                 aAttrValue = aOut.makeStringAndClear();
465                             }
466                         }
467                         else
468                         {
469                             XMLTransformerBase::ReplaceSingleInWithInch( aAttrValue );
470                         }
471 
472                         pAttrList->AddAttribute( rAttrName, aAttrValue );
473                     }
474                     break;
475 
476                 case XML_ATACTION_DECODE_PROTECT:
477                     {
478                         pAttrList->AddAttribute( rAttrName, rAttrValue );
479 
480                         if( rAttrValue.indexOf( GetXMLToken( XML_SIZE ) ) != -1 )
481                             pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
482                                     XML_NAMESPACE_DRAW,
483                                     GetXMLToken( XML_SIZE_PROTECT )), GetXMLToken( XML_TRUE ) );
484 
485                         if( rAttrValue.indexOf( GetXMLToken( XML_POSITION ) ) != -1 )
486                             pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
487                                     XML_NAMESPACE_DRAW,
488                                     GetXMLToken( XML_MOVE_PROTECT )), GetXMLToken( XML_TRUE ) );
489                     }
490                     break;
491 
492                 case XML_ATACTION_DRAW_MIRROR_OASIS: // renames style:mirror to draw:mirror and adapts values
493                     {
494                         // keep original for writer graphic objects
495                         // --> OD 2005-05-12 #i49139# - adapts attribute values,
496                         OUString aNewAttrValue;
497                         SvXMLTokenEnumerator aTokenEnum( rAttrValue );
498                         OUString aToken;
499                         while( aTokenEnum.getNextToken( aToken ) )
500                         {
501                             if ( aNewAttrValue.getLength() > 0 )
502                             {
503                                 aNewAttrValue += rtl::OUString::createFromAscii( " " );
504                             }
505 
506                             if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_EVEN ) )
507                             {
508                                 aNewAttrValue += GetXMLToken( XML_HORIZONTAL_ON_LEFT_PAGES );
509                             }
510                             else if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_ODD ) )
511                             {
512                                 aNewAttrValue += GetXMLToken( XML_HORIZONTAL_ON_RIGHT_PAGES );
513                             }
514                             else
515                             {
516                                 aNewAttrValue += aToken;
517                             }
518                         }
519                         pAttrList->AddAttribute( rAttrName, aNewAttrValue );
520                         // <--
521 
522                         // create old draw:mirror for drawing graphic objects
523                         OUString aAttrValue( GetXMLToken( IsXMLToken( rAttrValue, XML_HORIZONTAL ) ? XML_TRUE : XML_FALSE ) );
524                         pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
525                                     XML_NAMESPACE_DRAW,
526                                     GetXMLToken( XML_MIRROR )), aAttrValue );
527                     }
528                     break;
529                 case XML_ATACTION_GAMMA_OASIS:       // converts percentage value to double
530                     {
531                         sal_Int32 nValue;
532                         SvXMLUnitConverter::convertPercent( nValue, rAttrValue );
533                         const double fValue = ((double)nValue) / 100.0;
534                         pAttrList->AddAttribute( rAttrName, OUString::valueOf( fValue ) );
535                     }
536                     break;
537                 case XML_ATACTION_OPACITY_FIX:
538                     {
539                         sal_Int32 nValue;
540                         if( rAttrValue.indexOf( sal_Unicode('%') ) != -1 )
541                         {
542                             SvXMLUnitConverter::convertPercent( nValue, rAttrValue );
543                         }
544                         else
545                         {
546                             nValue = sal_Int32( rAttrValue.toDouble() * 100.0 );
547                         }
548                         nValue = 100 - nValue;
549 
550                         rtl::OUStringBuffer aOut;
551                         SvXMLUnitConverter::convertPercent( aOut, nValue );
552                         pAttrList->AddAttribute( rAttrName, aOut.makeStringAndClear() );
553                     }
554                     break;
555                 default:
556                     OSL_ENSURE( !this, "unknown action" );
557                     break;
558                 }
559             }
560             else
561             {
562                 pAttrList->AddAttribute( rAttrName, rAttrValue );
563             }
564         }
565         if( XML_TOKEN_END != eUnderline )
566             pAttrList->AddAttribute(
567                     GetTransformer().GetNamespaceMap().GetQNameByKey(
568                         XML_NAMESPACE_STYLE,
569                         GetXMLToken( XML_TEXT_UNDERLINE ) ),
570                     MergeUnderline( eUnderline, bBoldUnderline,
571                                     bDoubleUnderline ) );
572         if( XML_TOKEN_END != eLineThrough )
573             pAttrList->AddAttribute(
574                     GetTransformer().GetNamespaceMap().GetQNameByKey(
575                         XML_NAMESPACE_STYLE,
576                         GetXMLToken( XML_TEXT_CROSSING_OUT ) ),
577                     MergeLineThrough( eLineThrough, bBoldLineThrough,
578                                     bDoubleLineThrough, cLineThroughChar ) );
579         if( bIntervalMinorFound )
580         {
581             double fIntervalMinor = 0.0;
582             if( nIntervalMinorDivisor != 0)
583                 fIntervalMinor = fIntervalMajor / static_cast< double >( nIntervalMinorDivisor );
584 
585             ::rtl::OUStringBuffer aBuf;
586             SvXMLUnitConverter::convertDouble( aBuf, fIntervalMinor );
587             pAttrList->AddAttribute(
588                 GetTransformer().GetNamespaceMap().GetQNameByKey(
589                     XML_NAMESPACE_CHART,
590                     GetXMLToken( XML_INTERVAL_MINOR )),
591                 aBuf.makeStringAndClear());
592         }
593 
594         // #i25616#
595         if(aOpacityValueRemember.getLength() || aImageOpacityValueRemember.getLength())
596         {
597             pAttrList->AddAttribute(
598                     GetTransformer().GetNamespaceMap().GetQNameByKey(
599                         XML_NAMESPACE_DRAW,
600                         GetXMLToken( XML_TRANSPARENCY ) ),
601                     aImageOpacityValueRemember.getLength()
602                     ? aImageOpacityValueRemember : aOpacityValueRemember );
603         }
604     }
605     else
606     {
607         if( !m_xAttrList.is() )
608         {
609             m_xAttrList = new XMLMutableAttributeList( rAttrList, sal_True );
610         }
611         else
612         {
613             static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
614                 ->AppendAttributeList( rAttrList );
615         }
616     }
617 }
618 
619 void XMLPropertiesTContext_Impl::Export()
620 {
621     OUString aNewQName( GetTransformer().GetNamespaceMap().GetQNameByKey(
622                 XML_NAMESPACE_STYLE,
623                 ::xmloff::token::GetXMLToken( XML_PROPERTIES ) ) );
624     GetTransformer().GetDocHandler()->startElement( GetExportQName(),
625                                                     m_xAttrList );
626     ExportContent();
627     GetTransformer().GetDocHandler()->endElement( GetExportQName() );
628 }
629 
630 XMLPropType XMLPropertiesTContext_Impl::GetPropType( const OUString& rLocalName )
631 {
632     XMLPropType eProp = XML_PROP_TYPE_END;
633     if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES )  )
634         eProp = XML_PROP_TYPE_GRAPHIC;
635     else if( IsXMLToken( rLocalName, XML_DRAWING_PAGE_PROPERTIES ) )
636         eProp = XML_PROP_TYPE_DRAWING_PAGE;
637     else if( IsXMLToken( rLocalName, XML_PAGE_LAYOUT_PROPERTIES ) )
638         eProp = XML_PROP_TYPE_PAGE_LAYOUT;
639     else if( IsXMLToken( rLocalName, XML_HEADER_FOOTER_PROPERTIES ) )
640         eProp = XML_PROP_TYPE_HEADER_FOOTER;
641     else if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) )
642         eProp = XML_PROP_TYPE_TEXT;
643     else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) )
644         eProp = XML_PROP_TYPE_PARAGRAPH;
645     else if( IsXMLToken( rLocalName, XML_RUBY_PROPERTIES ) )
646         eProp = XML_PROP_TYPE_RUBY;
647     else if( IsXMLToken( rLocalName, XML_SECTION_PROPERTIES ) )
648         eProp = XML_PROP_TYPE_SECTION;
649     else if( IsXMLToken( rLocalName, XML_TABLE_PROPERTIES ) )
650         eProp = XML_PROP_TYPE_TABLE;
651     else if( IsXMLToken( rLocalName, XML_TABLE_COLUMN_PROPERTIES ) )
652         eProp = XML_PROP_TYPE_TABLE_COLUMN;
653     else if( IsXMLToken( rLocalName, XML_TABLE_ROW_PROPERTIES ) )
654         eProp = XML_PROP_TYPE_TABLE_ROW;
655     else if( IsXMLToken( rLocalName, XML_TABLE_CELL_PROPERTIES ) )
656         eProp = XML_PROP_TYPE_TABLE_CELL;
657     else if( IsXMLToken( rLocalName, XML_LIST_LEVEL_PROPERTIES ) )
658         eProp = XML_PROP_TYPE_LIST_LEVEL;
659     else if( IsXMLToken( rLocalName, XML_CHART_PROPERTIES ) )
660         eProp = XML_PROP_TYPE_CHART;
661 
662     return eProp;
663 }
664 
665 OUString XMLPropertiesTContext_Impl::MergeUnderline(
666             XMLTokenEnum eUnderline, sal_Bool bBold, sal_Bool bDouble )
667 {
668     if( bDouble )
669     {
670         switch( eUnderline )
671         {
672         case XML_WAVE:
673             eUnderline = XML_DOUBLE_WAVE;
674             break;
675         default:
676             eUnderline = XML_DOUBLE;
677             break;
678         }
679     }
680     else if( bBold )
681     {
682         switch( eUnderline )
683         {
684         case XML_NONE:
685         case XML_SOLID:
686             eUnderline = XML_BOLD;
687             break;
688         case XML_DOTTED:
689             eUnderline = XML_BOLD_DOTTED;
690             break;
691         case XML_DASH:
692             eUnderline = XML_BOLD_DASH;
693             break;
694         case XML_LONG_DASH:
695             eUnderline = XML_BOLD_LONG_DASH;
696             break;
697         case XML_DOT_DASH:
698             eUnderline = XML_BOLD_DOT_DASH;
699             break;
700         case XML_DOT_DOT_DASH:
701             eUnderline = XML_BOLD_DOT_DOT_DASH;
702             break;
703         case XML_WAVE:
704             eUnderline = XML_BOLD_WAVE;
705             break;
706         default:
707             OSL_ENSURE( false, "xmloff::XMLPropertiesTContext_Impl::MergeUnderline(), missing underline case!" );
708             break;
709         }
710     }
711     else
712     {
713         switch( eUnderline )
714         {
715         case XML_SOLID:
716             eUnderline = XML_SINGLE;
717             break;
718         case XML_NONE:
719             eUnderline = XML_NONE;
720             break;
721         default:
722             OSL_ENSURE( false, "xmloff::XMLPropertiesTContext_Impl::MergeUnderline(), missing underline case!" );
723             break;
724         }
725     }
726 
727     return GetXMLToken( eUnderline );
728 }
729 
730 OUString XMLPropertiesTContext_Impl::MergeLineThrough(
731             XMLTokenEnum eLineThrough, sal_Bool bBold, sal_Bool bDouble,
732             sal_Unicode c )
733 {
734     if( c )
735         eLineThrough = c=='/' ? XML_SLASH : XML_uX;
736     else if( bDouble )
737         eLineThrough = XML_DOUBLE_LINE;
738     else if( bBold )
739         eLineThrough = XML_THICK_LINE;
740     else if( XML_NONE != eLineThrough )
741         eLineThrough = XML_SINGLE_LINE;
742 
743     return GetXMLToken( eLineThrough );
744 }
745 
746 //------------------------------------------------------------------------------
747 
748 TYPEINIT1( XMLStyleOASISTContext, XMLPersElemContentTContext );
749 
750 XMLStyleOASISTContext::XMLStyleOASISTContext( XMLTransformerBase& rImp,
751                                               const OUString& rQName,
752                                               sal_Bool bPersistent ) :
753     XMLPersElemContentTContext ( rImp, rQName ),
754     m_bPersistent( bPersistent ),
755     m_bControlStyle( false )
756 {
757 }
758 
759 XMLStyleOASISTContext::XMLStyleOASISTContext(
760         XMLTransformerBase& rImp,
761         const OUString& rQName,
762         sal_uInt16 nPrefix,
763         ::xmloff::token::XMLTokenEnum eToken,
764         sal_Bool bPersistent ) :
765     XMLPersElemContentTContext( rImp, rQName, nPrefix, eToken ),
766     m_bPersistent( bPersistent )
767 {
768 }
769 
770 XMLStyleOASISTContext::~XMLStyleOASISTContext()
771 {
772 }
773 
774 XMLTransformerContext *XMLStyleOASISTContext::CreateChildContext(
775             sal_uInt16 nPrefix,
776             const OUString& rLocalName,
777             const OUString& rQName,
778             const Reference< XAttributeList >& rAttrList )
779 {
780     XMLTransformerContext *pContext = 0;
781 
782     if( XML_NAMESPACE_STYLE == nPrefix )
783     {
784         XMLPropType ePropType =
785             XMLPropertiesTContext_Impl::GetPropType( rLocalName );
786         if( XML_PROP_TYPE_END != ePropType )
787         {
788             // if no properties context exist start a new one.
789             if( !m_xPropContext.is() )
790                 m_xPropContext = new XMLPropertiesTContext_Impl(
791                     GetTransformer(), rQName, ePropType, m_aStyleFamily, m_bControlStyle );
792             else
793                 m_xPropContext->SetQNameAndPropType( rQName, ePropType );
794             pContext = m_xPropContext.get();
795         }
796     }
797     if( !pContext )
798     {
799         // if a properties context exist close it
800         if( m_xPropContext.is() && !m_bPersistent )
801         {
802             m_xPropContext->Export();
803             m_xPropContext = 0;
804         }
805 
806         pContext = m_bPersistent
807                         ? XMLPersElemContentTContext::CreateChildContext(
808                                 nPrefix, rLocalName, rQName, rAttrList )
809                         : XMLTransformerContext::CreateChildContext(
810                                 nPrefix, rLocalName, rQName, rAttrList );
811     }
812 
813     return pContext;
814 }
815 
816 void XMLStyleOASISTContext::StartElement(
817         const Reference< XAttributeList >& rAttrList )
818 {
819     XMLTransformerActions *pActions =
820         GetTransformer().GetUserDefinedActions( OASIS_STYLE_ACTIONS );
821     OSL_ENSURE( pActions, "go no actions" );
822 
823     Reference< XAttributeList > xAttrList( rAttrList );
824     XMLMutableAttributeList *pMutableAttrList = 0;
825     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
826     sal_Int16 nFamilyAttr = -1;
827     m_bControlStyle = sal_False;
828 
829     for( sal_Int16 i=0; i < nAttrCount; i++ )
830     {
831         const OUString& rAttrName = xAttrList->getNameByIndex( i );
832         OUString aLocalName;
833         sal_uInt16 nPrefix =
834             GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
835                                                                  &aLocalName );
836         XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
837         XMLTransformerActions::const_iterator aIter =
838             pActions->find( aKey );
839         if( !(aIter == pActions->end() ) )
840         {
841             if( !pMutableAttrList )
842             {
843                 pMutableAttrList =
844                         new XMLMutableAttributeList( xAttrList );
845                 xAttrList = pMutableAttrList;
846             }
847             const OUString& rAttrValue = xAttrList->getValueByIndex( i );
848             switch( (*aIter).second.m_nActionType )
849             {
850             case XML_ATACTION_STYLE_FAMILY:
851                 if( IsXMLToken( rAttrValue, XML_GRAPHIC ) )
852                 {
853                     m_aStyleFamily = GetXMLToken( XML_GRAPHICS ) ;
854                     pMutableAttrList->SetValueByIndex( i, m_aStyleFamily );
855                 }
856                 else
857                 {
858                     m_aStyleFamily = rAttrValue;
859 
860                     if( IsXMLToken( rAttrValue, XML_PARAGRAPH ) )
861                         nFamilyAttr = i;
862                 }
863 
864                 break;
865             case XML_ATACTION_STYLE_DISPLAY_NAME:
866             case XML_ATACTION_REMOVE:
867                 pMutableAttrList->RemoveAttributeByIndex( i );
868                 --i;
869                 --nAttrCount;
870                 break;
871             case XML_ATACTION_DECODE_STYLE_NAME:
872                 m_bControlStyle = 0 == rAttrValue.compareToAscii( "ctrl", 4 );
873             case XML_ATACTION_DECODE_STYLE_NAME_REF:
874                 {
875                     OUString aAttrValue( rAttrValue );
876                     if( GetTransformer().DecodeStyleName(aAttrValue) )
877                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
878                 }
879                 break;
880             case XML_ATACTION_IN2INCH:
881                 {
882                     OUString aAttrValue( rAttrValue );
883                     if( XMLTransformerBase::ReplaceSingleInWithInch(
884                                 aAttrValue ) )
885                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
886                 }
887                 break;
888             case XML_ATACTION_NEG_PERCENT:
889                 {
890                     OUString aAttrValue( rAttrValue );
891                     if( GetTransformer().NegPercent(aAttrValue) )
892                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
893                 }
894                 break;
895             case XML_ATACTION_URI_OASIS:
896                 {
897                     OUString aAttrValue( rAttrValue );
898                     if( GetTransformer().ConvertURIToOOo( aAttrValue,
899                             static_cast< sal_Bool >((*aIter).second.m_nParam1)))
900                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
901                 }
902                 break;
903             default:
904                 OSL_ENSURE( !this, "unknown action" );
905                 break;
906             }
907         }
908     }
909 
910     if( m_bControlStyle && nFamilyAttr != -1 )
911         pMutableAttrList->SetValueByIndex( nFamilyAttr, GetXMLToken( XML_CONTROL ) );
912 
913 
914     if( m_bPersistent )
915         XMLPersElemContentTContext::StartElement( xAttrList );
916     else
917         GetTransformer().GetDocHandler()->startElement( GetExportQName(),
918                                                         xAttrList );
919 }
920 
921 void XMLStyleOASISTContext::EndElement()
922 {
923     if( m_bPersistent )
924     {
925         XMLPersElemContentTContext::EndElement();
926     }
927     else
928     {
929         // if a properties context exist close it
930         if( m_xPropContext.is() )
931         {
932             m_xPropContext->Export();
933             m_xPropContext = 0;
934         }
935         GetTransformer().GetDocHandler()->endElement( GetExportQName() );
936     }
937 }
938 
939 void XMLStyleOASISTContext::Characters( const OUString& )
940 {
941     // element content only:
942 }
943 
944 void XMLStyleOASISTContext::ExportContent()
945 {
946     if( m_xPropContext.is() )
947         m_xPropContext->Export();
948     XMLPersElemContentTContext::ExportContent();
949 }
950 
951 sal_Bool XMLStyleOASISTContext::IsPersistent() const
952 {
953     return m_bPersistent;
954 }
955 
956 XMLTransformerActions *XMLStyleOASISTContext::CreateTransformerActions(
957         sal_uInt16 nType )
958 {
959     XMLTransformerActionInit *pInit = 0;
960 
961     switch( nType )
962     {
963     case PROP_OASIS_GRAPHIC_ATTR_ACTIONS:
964         pInit = aGraphicPropertyOASISAttrActionTable;
965         break;
966     case PROP_OASIS_DRAWING_PAGE_ATTR_ACTIONS:
967         pInit = aDrawingPagePropertyOASISAttrActionTable;
968         break;
969     case PROP_OASIS_PAGE_LAYOUT_ATTR_ACTIONS:
970         pInit = aPageLayoutPropertyOASISAttrActionTable;
971         break;
972     case PROP_OASIS_HEADER_FOOTER_ATTR_ACTIONS:
973         pInit = aHeaderFooterPropertyOASISAttrActionTable;
974         break;
975     case PROP_OASIS_TEXT_ATTR_ACTIONS:
976         pInit = aTextPropertyOASISAttrActionTable;
977         break;
978     case PROP_OASIS_PARAGRAPH_ATTR_ACTIONS:
979         pInit = aParagraphPropertyOASISAttrActionTable;
980         break;
981     case PROP_OASIS_SECTION_ATTR_ACTIONS:
982         pInit = aSectionPropertyOASISAttrActionTable;
983         break;
984     case PROP_OASIS_TABLE_ATTR_ACTIONS:
985         pInit = aTablePropertyOASISAttrActionTable;
986         break;
987     case PROP_OASIS_TABLE_COLUMN_ATTR_ACTIONS:
988         pInit = aTableColumnPropertyOASISAttrActionTable;
989         break;
990     case PROP_OASIS_TABLE_ROW_ATTR_ACTIONS:
991         pInit = aTableRowPropertyOASISAttrActionTable;
992         break;
993     case PROP_OASIS_TABLE_CELL_ATTR_ACTIONS:
994         pInit = aTableCellPropertyOASISAttrActionTable;
995         break;
996     case PROP_OASIS_LIST_LEVEL_ATTR_ACTIONS:
997         pInit = aListLevelPropertyOASISAttrActionTable;
998         break;
999     case PROP_OASIS_CHART_ATTR_ACTIONS:
1000         pInit = aChartPropertyOASISAttrActionTable;
1001         break;
1002     }
1003 
1004     XMLTransformerActions *pActions = 0;
1005     if( pInit )
1006         pActions = new XMLTransformerActions( pInit );
1007 
1008     return pActions;
1009 }
1010