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 <xmloff/nmspmap.hxx>
31 #include <xmloff/xmltoken.hxx>
32 #include "xmloff/xmlnmspe.hxx"
33 #include "PropType.hxx"
34 #include "DeepTContext.hxx"
35 #include "RenameElemTContext.hxx"
36 #include "ProcAttrTContext.hxx"
37 #include "ActionMapTypesOOo.hxx"
38 #include "MutableAttrList.hxx"
39 #include "TransformerActions.hxx"
40 #include "PropertyActionsOOo.hxx"
41 #ifndef _XMLOFF_TRANSFORMERBASE_HXX
42 #include "TransformerBase.hxx"
43 #endif
44 
45 #ifndef _XMLOFF_STYLEOASISTCONTEXT_HXX
46 #include "StyleOOoTContext.hxx"
47 #endif
48 #include <xmloff/xmluconv.hxx>
49 #include <rtl/ustrbuf.hxx>
50 #include <rtl/math.hxx>
51 
52 using ::rtl::OUString;
53 using namespace ::xmloff::token;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::xml::sax;
56 
57 const sal_uInt16 MAX_PROP_TYPES = 4;
58 #define ENTRY4(a,b,c,d) \
59 	{ XML_PROP_TYPE_##a, XML_PROP_TYPE_##b, \
60 		XML_PROP_TYPE_##c, XML_PROP_TYPE_##d  }
61 #define ENTRY3(a,b,c) \
62 	{ XML_PROP_TYPE_##a, XML_PROP_TYPE_##b,  \
63 		XML_PROP_TYPE_##c, XML_PROP_TYPE_END }
64 #define ENTRY2(a,b) \
65 	{ XML_PROP_TYPE_##a, XML_PROP_TYPE_##b, \
66 		XML_PROP_TYPE_END, XML_PROP_TYPE_END }
67 #define ENTRY1(a) \
68 	{ XML_PROP_TYPE_##a, XML_PROP_TYPE_##END, \
69 		XML_PROP_TYPE_END, XML_PROP_TYPE_END }
70 
71 static XMLPropType aPropTypes[XML_FAMILY_TYPE_END][MAX_PROP_TYPES] =
72 {
73 	ENTRY3( GRAPHIC, PARAGRAPH, TEXT ),			// XML_FAMILY_TYPE_GRAPHIC,
74 	ENTRY3( GRAPHIC, PARAGRAPH, TEXT ),			// XML_FAMILY_TYPE_PRESENTATION,
75 	ENTRY1( DRAWING_PAGE ),						// XML_FAMILY_TYPE_DRAWING_PAGE,
76 	ENTRY1( END ),								// XML_FAMILY_TYPE_MASTER_PAGE
77 	ENTRY1( PAGE_LAYOUT ),						// XML_FAMILY_TYPE_PAGE_LAYOUT,
78 	ENTRY1( HEADER_FOOTER ),					// XML_FAMILY_TYPE_HEADER_FOOTER
79 	ENTRY1( TEXT ),								// XML_FAMILY_TYPE_TEXT,
80 	ENTRY2( PARAGRAPH, TEXT ),					// XML_FAMILY_TYPE_PARAGRAPH,
81 	ENTRY1( RUBY ),								//XML_FAMILY_TYPE_RUBY,
82 	ENTRY1( SECTION ),							// XML_FAMILY_TYPE_SECTION,
83 	ENTRY1( TABLE ),							// XML_FAMILY_TYPE_TABLE,
84 	ENTRY1( TABLE_COLUMN ),						// XML_FAMILY_TYPE_TABLE_COLUMN,
85 	ENTRY1( TABLE_ROW ),						// XML_FAMILY_TYPE_TABLE_ROW,
86 	ENTRY3( TABLE_CELL, PARAGRAPH, TEXT ),		// XML_FAMILY_TYPE_TABLE_CELL,
87 	ENTRY1( LIST_LEVEL ),						// XML_FAMILY_TYPE_LIST,
88 	ENTRY4( CHART, GRAPHIC, PARAGRAPH, TEXT ),	// XML_FAMILY_TYPE_CHART,
89 	ENTRY1( TEXT ),								// XML_FAMILY_TYPE_DATA,
90 	ENTRY1( END ),								// XML_FAMILY_TYPE_GRADIENT,
91 	ENTRY1( END ),								// XML_FAMILY_TYPE_HATCH,
92 	ENTRY1( END ),								// XML_FAMILY_TYPE_FILL_IMAGE,
93 	ENTRY1( END ),								// XML_FAMILY_TYPE_STROKE_DASH,
94 	ENTRY1( END ),								// XML_FAMILY_TYPE_MARKER,
95 	ENTRY1( END )								// XML_FAMILY_TYPE_PRESENTATION_PAGE_LAYOUT,
96 };
97 
98 static XMLTokenEnum aPropTokens[XML_PROP_TYPE_END] =
99 {
100 	XML_GRAPHIC_PROPERTIES,
101 	XML_DRAWING_PAGE_PROPERTIES,
102 	XML_PAGE_LAYOUT_PROPERTIES,
103 	XML_HEADER_FOOTER_PROPERTIES,
104 	XML_TEXT_PROPERTIES,
105 	XML_PARAGRAPH_PROPERTIES,
106 	XML_RUBY_PROPERTIES,
107 	XML_SECTION_PROPERTIES,
108 	XML_TABLE_PROPERTIES,
109 	XML_TABLE_COLUMN_PROPERTIES,
110 	XML_TABLE_ROW_PROPERTIES,
111 	XML_TABLE_CELL_PROPERTIES,
112 	XML_LIST_LEVEL_PROPERTIES,
113 	XML_CHART_PROPERTIES
114 };
115 
116 static sal_uInt16 aAttrActionMaps[XML_PROP_TYPE_END] =
117 {
118 	PROP_OOO_GRAPHIC_ATTR_ACTIONS,
119 	PROP_OOO_DRAWING_PAGE_ATTR_ACTIONS,		// DRAWING_PAGE
120 	PROP_OOO_PAGE_LAYOUT_ATTR_ACTIONS,
121 	PROP_OOO_HEADER_FOOTER_ATTR_ACTIONS,
122 	PROP_OOO_TEXT_ATTR_ACTIONS,
123 	PROP_OOO_PARAGRAPH_ATTR_ACTIONS,
124 	MAX_OOO_PROP_ACTIONS,		// RUBY
125 	PROP_OOO_SECTION_ATTR_ACTIONS,
126 	PROP_OOO_TABLE_ATTR_ACTIONS,
127 	PROP_OOO_TABLE_COLUMN_ATTR_ACTIONS,
128 	PROP_OOO_TABLE_ROW_ATTR_ACTIONS,
129 	PROP_OOO_TABLE_CELL_ATTR_ACTIONS,
130 	PROP_OOO_LIST_LEVEL_ATTR_ACTIONS,
131 	PROP_OOO_CHART_ATTR_ACTIONS
132 };
133 
134 static sal_uInt16 aElemActionMaps[XML_PROP_TYPE_END] =
135 {
136 	PROP_OOO_GRAPHIC_ELEM_ACTIONS,
137 	MAX_OOO_PROP_ACTIONS,
138 	MAX_OOO_PROP_ACTIONS,
139 	MAX_OOO_PROP_ACTIONS,
140 	PROP_OOO_TEXT_ELEM_ACTIONS,
141 	PROP_OOO_PARAGRAPH_ELEM_ACTIONS,
142 	MAX_OOO_PROP_ACTIONS,
143 	MAX_OOO_PROP_ACTIONS,
144 	MAX_OOO_PROP_ACTIONS,
145 	MAX_OOO_PROP_ACTIONS,
146 	MAX_OOO_PROP_ACTIONS,
147 	PROP_OOO_TABLE_CELL_ELEM_ACTIONS,
148 	MAX_OOO_PROP_ACTIONS,
149 	PROP_OOO_CHART_ELEM_ACTIONS
150 };
151 
152 
153 //------------------------------------------------------------------------------
154 
155 class XMLTypedPropertiesOOoTContext_Impl : public XMLPersElemContentTContext
156 {
157 	::com::sun::star::uno::Reference<
158 		::com::sun::star::xml::sax::XAttributeList > m_xAttrList;
159 
160 public:
161 
162 	TYPEINFO();
163 
164 	XMLTypedPropertiesOOoTContext_Impl( XMLTransformerBase& rTransformer,
165 						   const ::rtl::OUString& rQName );
166 
167 	virtual ~XMLTypedPropertiesOOoTContext_Impl();
168 
169     using XMLPersAttrListTContext::AddAttribute;
170 	void AddAttribute( const ::rtl::OUString &sName ,
171 					   const ::rtl::OUString &sValue );
172 	void AddAttribute( sal_uInt16 nPrefix, XMLTokenEnum eToken,
173 					   const ::rtl::OUString &sValue );
174 
175 	virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& rAttrList );
176 
177 	virtual void Export();
178 };
179 
180 TYPEINIT1( XMLTypedPropertiesOOoTContext_Impl, XMLPersElemContentTContext );
181 
182 XMLTypedPropertiesOOoTContext_Impl::XMLTypedPropertiesOOoTContext_Impl(
183 	XMLTransformerBase& rImp,
184 	const OUString& rQName ) :
185 	XMLPersElemContentTContext( rImp, rQName ),
186 	m_xAttrList( new XMLMutableAttributeList() )
187 {
188 }
189 
190 XMLTypedPropertiesOOoTContext_Impl::~XMLTypedPropertiesOOoTContext_Impl()
191 {
192 }
193 
194 void XMLTypedPropertiesOOoTContext_Impl::AddAttribute(
195 	const ::rtl::OUString &sName ,
196 	const ::rtl::OUString &sValue )
197 {
198 	static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
199 			->AddAttribute( sName, sValue );
200 }
201 
202 void XMLTypedPropertiesOOoTContext_Impl::AddAttribute(
203 	sal_uInt16 nPrefix, XMLTokenEnum eToken,
204 	const ::rtl::OUString &sValue )
205 {
206 	OUString sName(
207 			GetTransformer().GetNamespaceMap().GetQNameByKey(
208 						nPrefix, ::xmloff::token::GetXMLToken( eToken ) ) );
209 	static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
210 			->AddAttribute( sName, sValue );
211 }
212 
213 void XMLTypedPropertiesOOoTContext_Impl::StartElement(
214 		const Reference< XAttributeList >& )
215 {
216 	// empty, ignore even the attribute list
217 }
218 
219 void XMLTypedPropertiesOOoTContext_Impl::Export()
220 {
221 	if( m_xAttrList->getLength() || HasElementContent() )
222 	{
223 		GetTransformer().GetDocHandler()->startElement( GetQName(), m_xAttrList );
224 		ExportContent();
225 		GetTransformer().GetDocHandler()->endElement( GetQName() );
226 	}
227 }
228 
229 //------------------------------------------------------------------------------
230 
231 class XMLPropertiesOOoTContext_Impl : public XMLTransformerContext
232 {
233 	::rtl::Reference < XMLTypedPropertiesOOoTContext_Impl >
234 		m_aPropContexts[MAX_PROP_TYPES];
235 
236 	typedef XMLPropType XMLPropTypes[MAX_PROP_TYPES];
237 
238 	XMLPropTypes m_aPropTypes;
239 
240 	sal_Bool m_bPersistent;
241 
242 	XMLTypedPropertiesOOoTContext_Impl *GetPropContextAndAction(
243 			TransformerAction_Impl& rAction,
244 			sal_uInt16 nPrefix, const OUString& rLocalName,
245 		    sal_Bool bElem );
246 
247 	XMLTypedPropertiesOOoTContext_Impl *GetPropContext(
248 			XMLPropType eType );
249 
250 
251 public:
252 
253 	TYPEINFO();
254 
255 	XMLPropertiesOOoTContext_Impl( XMLTransformerBase& rTransformer,
256 						   const ::rtl::OUString& rQName,
257 		   					XMLPropTypes& rTypes,
258 		   					sal_Bool bPersistent );
259 
260 	virtual ~XMLPropertiesOOoTContext_Impl();
261 
262 	XMLTransformerContext *CreateChildContext(
263 			sal_uInt16 nPrefix,
264 			const OUString& rLocalName,
265 			const OUString& rQName,
266 			const Reference< XAttributeList >& rAttrList );
267 
268 	virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& rAttrList );
269 
270 	virtual void EndElement();
271 
272 	virtual void Characters( const ::rtl::OUString& rChars );
273 
274 	virtual void Export();
275 
276 	virtual sal_Bool IsPersistent() const;
277 };
278 
279 TYPEINIT1( XMLPropertiesOOoTContext_Impl, XMLTransformerContext );
280 
281 XMLTypedPropertiesOOoTContext_Impl
282 	*XMLPropertiesOOoTContext_Impl::GetPropContext(
283 			XMLPropType eType )
284 {
285 	sal_uInt16 nIndex = MAX_PROP_TYPES;
286 	for( sal_uInt16 i=0; i< MAX_PROP_TYPES; i++ )
287 	{
288 		if( m_aPropTypes[i] == eType )
289 		{
290 			nIndex = i;
291 			break;
292 		}
293 	}
294 	if( MAX_PROP_TYPES == nIndex )
295 		return 0;
296 
297 	if( !m_aPropContexts[nIndex].is() )
298 	{
299 		m_aPropContexts[nIndex] =
300 			new XMLTypedPropertiesOOoTContext_Impl(
301 					GetTransformer(),
302 					GetTransformer().GetNamespaceMap().GetQNameByKey(
303 						XML_NAMESPACE_STYLE,
304 						::xmloff::token::GetXMLToken(
305 							aPropTokens[m_aPropTypes[nIndex]] ) ));
306 	}
307 
308 	return m_aPropContexts[nIndex].get();
309 }
310 
311 
312 XMLTypedPropertiesOOoTContext_Impl
313 	*XMLPropertiesOOoTContext_Impl::GetPropContextAndAction(
314 			TransformerAction_Impl& rAction,
315 			sal_uInt16 nPrefix, const OUString& rLocalName,
316 		    sal_Bool bElem )
317 {
318 	rAction.m_nActionType = XML_ATACTION_COPY;
319 	sal_uInt16 nIndex = 0;
320 
321 	XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
322 	sal_uInt16 i=0;
323 	while( i < MAX_PROP_TYPES && XML_PROP_TYPE_END!=m_aPropTypes[i])
324 	{
325 		sal_uInt16 nActionMap =
326 			(bElem ? aElemActionMaps : aAttrActionMaps)[m_aPropTypes[i]];
327 		if( nActionMap < MAX_OOO_PROP_ACTIONS )
328 		{
329 			XMLTransformerActions *pActions =
330 				GetTransformer().GetUserDefinedActions( nActionMap );
331 			OSL_ENSURE( pActions, "go no actions" );
332 			if( pActions )
333 			{
334 				XMLTransformerActions::const_iterator aIter =
335 					pActions->find( aKey );
336 
337 				if( !(aIter == pActions->end()) )
338 				{
339 					rAction = (*aIter).second;
340 					nIndex = i;
341 					break;
342 				}
343 			}
344 		}
345 		++i;
346 	}
347 
348 #ifdef DBG_UTIL
349 	if( !( XML_NAMESPACE_NONE == nPrefix ||
350 				(XML_NAMESPACE_UNKNOWN_FLAG & nPrefix) ||
351 				XML_PROP_TYPE_END==m_aPropTypes[1] ||
352 				(i<MAX_PROP_TYPES && XML_PROP_TYPE_END!=m_aPropTypes[i]) ) )
353 	{
354 		::rtl::OString aTmp("Didnt't find property: ");
355 		const ::rtl::OUString& rPrefix =
356 			GetTransformer().GetNamespaceMap().GetPrefixByKey( nPrefix );
357 		aTmp +=	::rtl::OString( rPrefix.getStr(), rPrefix.getLength(),
358 								RTL_TEXTENCODING_ASCII_US );
359 		aTmp += ::rtl::OString::valueOf( ':' );
360 		aTmp +=	::rtl::OString( rLocalName.getStr(), rLocalName.getLength(),
361 								RTL_TEXTENCODING_ASCII_US );
362 		aTmp += ::rtl::OString(", assuming <style:");
363 		const ::rtl::OUString& rName =
364 			::xmloff::token::GetXMLToken( aPropTokens[m_aPropTypes[0]] );
365 		aTmp +=	::rtl::OString( rName.getStr(), rName.getLength(),
366 								RTL_TEXTENCODING_ASCII_US );
367 		aTmp += ::rtl::OString::valueOf( '>' );
368 
369 		OSL_ENSURE( !this, aTmp );
370 	}
371 #endif
372 
373 	if( !m_aPropContexts[nIndex].is() )
374 	{
375 		m_aPropContexts[nIndex] =
376 			new XMLTypedPropertiesOOoTContext_Impl(
377 					GetTransformer(),
378 					GetTransformer().GetNamespaceMap().GetQNameByKey(
379 						XML_NAMESPACE_STYLE,
380 						::xmloff::token::GetXMLToken(
381 							aPropTokens[m_aPropTypes[nIndex]] ) ));
382 	}
383 
384 	return m_aPropContexts[nIndex].get();
385 }
386 
387 XMLPropertiesOOoTContext_Impl::XMLPropertiesOOoTContext_Impl(
388 	XMLTransformerBase& rImp,
389 	const OUString& rQName,
390 	XMLPropTypes& rTypes,
391 	sal_Bool bPersistent	) :
392 	XMLTransformerContext( rImp, rQName ),
393 	m_bPersistent( bPersistent )
394 {
395 	for( sal_uInt16 i=0; i < MAX_PROP_TYPES; ++i )
396 	{
397 		// remember the types that belong to the attribute and element lists
398 		m_aPropTypes[i] = rTypes[i];
399 	}
400 }
401 
402 XMLPropertiesOOoTContext_Impl::~XMLPropertiesOOoTContext_Impl()
403 {
404 }
405 
406 XMLTransformerContext *XMLPropertiesOOoTContext_Impl::CreateChildContext(
407 			sal_uInt16 nPrefix,
408 			const OUString& rLocalName,
409 			const OUString& rQName,
410 			const Reference< XAttributeList >& rAttrList )
411 {
412 	TransformerAction_Impl aAction;
413 	return GetPropContextAndAction( aAction, nPrefix, rLocalName, sal_True )
414 				->CreateChildContext( nPrefix, rLocalName, rQName, rAttrList );
415 }
416 
417 
418 void XMLPropertiesOOoTContext_Impl::StartElement(
419 		const Reference< XAttributeList >& rAttrList )
420 {
421 	Reference< XAttributeList > xAttrList( rAttrList );
422 
423     XMLTypedPropertiesOOoTContext_Impl * pIntervalMinorDivisorContext = 0;
424     double fIntervalMajor = 0.0;
425     double fIntervalMinor = 0.0;
426 	sal_Bool bMoveProtect = sal_False;
427 	sal_Bool bSizeProtect = sal_False;
428 	OUString aProtectAttrValue;
429 	XMLTypedPropertiesOOoTContext_Impl * pProtectContext = 0;
430 
431     // --> OD 2005-05-13 #i49139# - attribute <style:mirror> has to be priority
432     // over attribute <style:draw>. The filter from OpenDocument file format
433     // to OpenOffice.org file format produces styles with both attributes.
434     sal_Bool bExistStyleMirror( sal_False );
435     OUString aStyleMirrorAttrValue;
436     sal_Bool bExistDrawMirror( sal_False );
437     OUString aDrawMirrorAttrValue;
438     XMLTypedPropertiesOOoTContext_Impl* pMirrorContext( 0L );
439     // <--
440 
441 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
442 	for( sal_Int16 i=0; i < nAttrCount; i++ )
443 	{
444 		const OUString sAttrName = xAttrList->getNameByIndex( i );
445 		const OUString sAttrValue = xAttrList->getValueByIndex( i );
446 		OUString aLocalName;
447 		sal_uInt16 nPrefix =
448 			GetTransformer().GetNamespaceMap().GetKeyByAttrName( sAttrName,
449 																 &aLocalName );
450 		TransformerAction_Impl aAction;
451 		XMLTypedPropertiesOOoTContext_Impl *pContext =
452 			GetPropContextAndAction( aAction, nPrefix, aLocalName, sal_False );
453 		switch( aAction.m_nActionType )
454 		{
455 		case XML_ATACTION_REMOVE:
456 			break;
457 		case XML_ATACTION_COPY:
458 			pContext->AddAttribute( sAttrName, sAttrValue );
459 			break;
460 		case XML_ATACTION_COPY_DUPLICATE:
461             {
462 			    pContext->AddAttribute( sAttrName, sAttrValue );
463 				XMLTypedPropertiesOOoTContext_Impl *pContext2 =
464 					GetPropContext( (XMLPropType)aAction.m_nParam1 );
465 				if( pContext2 )
466 					pContext2->AddAttribute( sAttrName, sAttrValue );
467             }
468 			break;
469 		case XML_ATACTION_RENAME:
470 			{
471 				pContext->AddAttribute( aAction.GetQNamePrefixFromParam1(),
472 										aAction.GetQNameTokenFromParam1(),
473 										sAttrValue );
474 			}
475 			break;
476 		case XML_ATACTION_ENCODE_STYLE_NAME_REF:
477 			{
478 				OUString aAttrValue( sAttrValue );
479 				GetTransformer().EncodeStyleName(aAttrValue);
480 				pContext->AddAttribute( sAttrName, aAttrValue );
481 			}
482 			break;
483 		case XML_ATACTION_RENAME_ENCODE_STYLE_NAME_REF:
484 			{
485 				OUString aAttrValue( sAttrValue );
486 				GetTransformer().EncodeStyleName(aAttrValue);
487 				pContext->AddAttribute( aAction.GetQNamePrefixFromParam1(),
488 										aAction.GetQNameTokenFromParam1(),
489 										aAttrValue );
490 			}
491 			break;
492 		case XML_ATACTION_NEG_PERCENT:
493 			{
494 				OUString aAttrValue( sAttrValue );
495 				GetTransformer().NegPercent(aAttrValue);
496 				pContext->AddAttribute( sAttrName, aAttrValue );
497 			}
498 			break;
499 		case XML_ATACTION_RENAME_NEG_PERCENT:
500 			{
501 				OUString aAttrValue( sAttrValue );
502 				GetTransformer().NegPercent(aAttrValue);
503 				pContext->AddAttribute( aAction.GetQNamePrefixFromParam1(),
504 										aAction.GetQNameTokenFromParam1(),
505 										aAttrValue );
506 			}
507 			break;
508 		case XML_ATACTION_INCH2IN:
509 			{
510 				OUString aAttrValue( sAttrValue );
511 				XMLTransformerBase::ReplaceSingleInchWithIn( aAttrValue );
512 				pContext->AddAttribute( sAttrName, aAttrValue );
513 			}
514 			break;
515 		case XML_ATACTION_INCH2IN_DUPLICATE:
516 			{
517 				OUString aAttrValue( sAttrValue );
518 				XMLTransformerBase::ReplaceSingleInchWithIn( aAttrValue );
519 				pContext->AddAttribute( sAttrName, aAttrValue );
520 				XMLTypedPropertiesOOoTContext_Impl *pContext2 =
521 					GetPropContext( (XMLPropType)aAction.m_nParam1 );
522 				if( pContext2 )
523 					pContext2->AddAttribute( sAttrName, aAttrValue );
524 			}
525 			break;
526 		case XML_ATACTION_INCHS2INS:
527 			{
528 				OUString aAttrValue( sAttrValue );
529 				XMLTransformerBase::ReplaceInchWithIn( aAttrValue );
530 				pContext->AddAttribute( sAttrName, aAttrValue );
531 			}
532 			break;
533 		case XML_PTACTION_LINE_MODE:
534 			{
535 				OUString aAttrValue( GetXMLToken(
536 										IsXMLToken( sAttrValue, XML_TRUE )
537 											? XML_CONTINUOUS
538 											: XML_SKIP_WHITE_SPACE) );
539 				OUString aAttrQName(
540 						GetTransformer().GetNamespaceMap().GetQNameByKey(
541 							XML_NAMESPACE_STYLE,
542 							GetXMLToken( XML_TEXT_UNDERLINE_MODE ) ) );
543 				pContext->AddAttribute( aAttrQName, aAttrValue );
544 
545 				aAttrQName =
546 						GetTransformer().GetNamespaceMap().GetQNameByKey(
547 							XML_NAMESPACE_STYLE,
548 							GetXMLToken( XML_TEXT_LINE_THROUGH_MODE ) );
549 				pContext->AddAttribute( aAttrQName, aAttrValue );
550 			}
551 			break;
552 		case XML_PTACTION_KEEP_WITH_NEXT:
553 			{
554 				OUString aAttrValue( GetXMLToken(
555 										IsXMLToken( sAttrValue, XML_TRUE )
556 											? XML_ALWAYS
557 											: XML_AUTO) );
558 				pContext->AddAttribute( sAttrName, aAttrValue );
559 			}
560 			break;
561 		case XML_PTACTION_UNDERLINE:
562 			{
563 				XMLTokenEnum eToken = GetTransformer().GetToken( sAttrValue );
564 				sal_Bool bBold = sal_False, bDouble = sal_False;
565 				switch( eToken )
566 				{
567 				case XML_SINGLE:
568 					eToken = XML_SOLID;
569 					break;
570 				case XML_DOUBLE:
571 					eToken = XML_SOLID;
572 					bDouble = sal_True;
573 					break;
574 				case XML_BOLD:
575 					eToken = XML_SOLID;
576 					bBold = sal_True;
577 					break;
578 				case XML_BOLD_DOTTED:
579 					eToken = XML_DOTTED;
580 					bBold = sal_True;
581 					break;
582 				case XML_BOLD_DASH:
583 					eToken = XML_DASH;
584 					bBold = sal_True;
585 					break;
586 				case XML_BOLD_LONG_DASH:
587 					eToken = XML_LONG_DASH;
588 					bBold = sal_True;
589 					break;
590 				case XML_BOLD_DOT_DASH:
591 					eToken = XML_DOT_DASH;
592 					bBold = sal_True;
593 					break;
594 				case XML_BOLD_DOT_DOT_DASH:
595 					eToken = XML_DOT_DOT_DASH;
596 					bBold = sal_True;
597 					break;
598 				case XML_BOLD_WAVE:
599 					eToken = XML_WAVE;
600 					bBold = sal_True;
601 					break;
602 				case XML_DOUBLE_WAVE:
603 					eToken = XML_WAVE;
604 					bDouble = sal_True;
605 					break;
606 				case XML_NONE:
607 					eToken = XML_NONE;
608 					bDouble = sal_False;
609 					break;
610 				default:
611 					OSL_ENSURE( false, "xmloff::XMLPropertiesOOoTContext_Impl::StartElement(), unknown underline token!" );
612 					break;
613 				}
614 				pContext->AddAttribute(
615 						GetTransformer().GetNamespaceMap().GetQNameByKey(
616 							XML_NAMESPACE_STYLE,
617 							GetXMLToken( XML_TEXT_UNDERLINE_STYLE ) ),
618 						eToken != XML_TOKEN_END ? GetXMLToken( eToken )
619 					   							: sAttrValue	);
620 				if( bDouble )
621 					pContext->AddAttribute(
622 							GetTransformer().GetNamespaceMap().GetQNameByKey(
623 								XML_NAMESPACE_STYLE,
624 								GetXMLToken( XML_TEXT_UNDERLINE_TYPE ) ),
625 							GetXMLToken( XML_DOUBLE ) );
626 				if( bBold )
627 					pContext->AddAttribute(
628 							GetTransformer().GetNamespaceMap().GetQNameByKey(
629 								XML_NAMESPACE_STYLE,
630 								GetXMLToken( XML_TEXT_UNDERLINE_WIDTH ) ),
631 							GetXMLToken( XML_BOLD ) );
632 			}
633 			break;
634 		case XML_PTACTION_LINETHROUGH:
635 			{
636 				XMLTokenEnum eToken = GetTransformer().GetToken( sAttrValue );
637 				sal_Bool bBold = sal_False, bDouble = sal_False;
638 				sal_Unicode c = 0;
639 				switch( eToken )
640 				{
641 				case XML_SINGLE_LINE:
642 					eToken = XML_SOLID;
643 					break;
644 				case XML_DOUBLE_LINE:
645 					eToken = XML_SOLID;
646 					bDouble = sal_True;
647 					break;
648 				case XML_THICK_LINE:
649 					eToken = XML_SOLID;
650 					bBold = sal_True;
651 					break;
652 				case XML_SLASH:
653 					eToken = XML_SOLID;
654 					c = '/';
655 					break;
656 				case XML_uX:
657 					eToken = XML_SOLID;
658 					c = 'X';
659 					break;
660 				default:
661 					break;
662 				}
663 				pContext->AddAttribute(
664 						GetTransformer().GetNamespaceMap().GetQNameByKey(
665 							XML_NAMESPACE_STYLE,
666 							GetXMLToken( XML_TEXT_LINE_THROUGH_STYLE ) ),
667 						eToken != XML_TOKEN_END ? GetXMLToken( eToken )
668 					   							: sAttrValue	);
669 				if( bDouble )
670 					pContext->AddAttribute(
671 							GetTransformer().GetNamespaceMap().GetQNameByKey(
672 								XML_NAMESPACE_STYLE,
673 								GetXMLToken( XML_TEXT_LINE_THROUGH_TYPE ) ),
674 							GetXMLToken( XML_DOUBLE ) );
675 				if( bBold )
676 					pContext->AddAttribute(
677 							GetTransformer().GetNamespaceMap().GetQNameByKey(
678 								XML_NAMESPACE_STYLE,
679 								GetXMLToken( XML_TEXT_LINE_THROUGH_WIDTH ) ),
680 							GetXMLToken( XML_BOLD ) );
681 				if( c )
682 					pContext->AddAttribute(
683 							GetTransformer().GetNamespaceMap().GetQNameByKey(
684 								XML_NAMESPACE_STYLE,
685 								GetXMLToken( XML_TEXT_LINE_THROUGH_TEXT ) ),
686 							OUString::valueOf( c ) );
687 			}
688 			break;
689 		case XML_PTACTION_SPLINES:
690             {
691                 sal_Int32 nSplineType = sAttrValue.toInt32();
692                 OUString aNewAttrName = GetTransformer().GetNamespaceMap().GetQNameByKey(
693                     XML_NAMESPACE_CHART, GetXMLToken( XML_INTERPOLATION ) );
694 
695                 switch( nSplineType )
696                 {
697                     // straight lines
698                     case 0:
699                         pContext->AddAttribute(
700                             aNewAttrName, GetXMLToken( XML_NONE ));
701                         break;
702                     // cubic spline
703                     case 1:
704                         pContext->AddAttribute(
705                             aNewAttrName, GetXMLToken( XML_CUBIC_SPLINE ));
706                         break;
707                     // B-spline
708                     case 2:
709                         pContext->AddAttribute(
710                             aNewAttrName, GetXMLToken( XML_B_SPLINE ));
711                         break;
712 
713                     default:
714                         OSL_ENSURE( false, "invalid spline type" );
715                         pContext->AddAttribute(
716                             aNewAttrName, GetXMLToken( XML_NONE ));
717                         break;
718                 }
719             }
720             break;
721         case XML_PTACTION_INTERVAL_MAJOR:
722             pContext->AddAttribute( sAttrName, sAttrValue );
723             SvXMLUnitConverter::convertDouble( fIntervalMajor, sAttrValue );
724             break;
725         case XML_PTACTION_INTERVAL_MINOR:
726             SvXMLUnitConverter::convertDouble( fIntervalMinor, sAttrValue );
727             pIntervalMinorDivisorContext = pContext;
728             break;
729         case XML_PTACTION_SYMBOL:
730             {
731                 sal_Int32 nSymbolType = sAttrValue.toInt32();
732                 OUString aNewAttrName = GetTransformer().GetNamespaceMap().GetQNameByKey(
733                     XML_NAMESPACE_CHART, GetXMLToken( XML_SYMBOL_TYPE ) );
734 
735                 if( nSymbolType >= 0 )
736                 {
737                     pContext->AddAttribute( aNewAttrName, GetXMLToken( XML_NAMED_SYMBOL ));
738                     enum XMLTokenEnum eToken = XML_TOKEN_INVALID;
739                     switch( nSymbolType )
740                     {
741                         // SYMBOL0
742                         case 0:
743                             // "square" has an awkward token name
744                             eToken = XML_GRADIENTSTYLE_SQUARE;
745                             break;
746                         // SYMBOL1
747                         case 1:
748                             eToken = XML_DIAMOND;
749                             break;
750                         // SYMBOL2
751                         case 2:
752                             eToken = XML_ARROW_DOWN;
753                             break;
754                         // SYMBOL3
755                         case 3:
756                             eToken = XML_ARROW_UP;
757                             break;
758                         // SYMBOL4
759                         case 4:
760                             eToken = XML_ARROW_RIGHT;
761                             break;
762                         // SYMBOL5
763                         case 5:
764                             eToken = XML_ARROW_LEFT;
765                             break;
766                         // SYMBOL6
767                         case 6:
768                             eToken = XML_BOW_TIE;
769                             break;
770                         // SYMBOL7
771                         case 7:
772                             eToken = XML_HOURGLASS;
773                             break;
774                         case 8:
775                             eToken = XML_CIRCLE;
776                             break;
777                         case 9:
778                             eToken = XML_STAR;
779                             break;
780                         case 10:
781                             eToken = XML_X;
782                             break;
783                         case 11:
784                             eToken = XML_PLUS;
785                             break;
786                         case 12:
787                             eToken = XML_ASTERISK;
788                             break;
789                         case 13:
790                             eToken = XML_HORIZONTAL_BAR;
791                             break;
792                         case 14:
793                             eToken = XML_VERTICAL_BAR;
794                             break;
795                         default:
796                             OSL_ENSURE( false, "invalid named symbol" );
797                             break;
798                     }
799 
800                     if( eToken != XML_TOKEN_INVALID )
801                     {
802                         pContext->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
803                                                     XML_NAMESPACE_CHART, GetXMLToken( XML_SYMBOL_NAME )),
804                                                 GetXMLToken( eToken ));
805                     }
806                 }
807                 else
808                 {
809                     switch( nSymbolType )
810                     {
811                         // NONE
812                         case -3:
813                             pContext->AddAttribute(
814                                 aNewAttrName, GetXMLToken( XML_NONE ));
815                             break;
816                             // AUTO
817                         case -2:
818                             pContext->AddAttribute(
819                                 aNewAttrName, GetXMLToken( XML_AUTOMATIC ));
820                             break;
821                             // BITMAPURL
822                         case -1:
823                             pContext->AddAttribute(
824                                 aNewAttrName, GetXMLToken( XML_IMAGE ));
825                             break;
826                         default:
827                             OSL_ENSURE( false, "invalid symbol type" );
828                             pContext->AddAttribute(
829                                 aNewAttrName, GetXMLToken( XML_NONE ));
830                             break;
831                     }
832                 }
833             }
834             break;
835         case XML_PTACTION_SYMBOL_IMAGE_NAME:
836             {
837                 // create an xlink:href element for URI attribute
838                 XMLPersAttrListTContext *pSymbolImageContext = new XMLPersAttrListTContext(
839                     GetTransformer(), GetTransformer().GetNamespaceMap().GetQNameByKey(
840                         XML_NAMESPACE_CHART, GetXMLToken( XML_SYMBOL_IMAGE )));
841 
842                 OUString aAttrValue( sAttrValue );
843                 if( GetTransformer().ConvertURIToOASIS( aAttrValue, sal_True ))
844                 {
845                     pSymbolImageContext->AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aAttrValue );
846                     pContext->AddContent( pSymbolImageContext );
847                 }
848             }
849             break;
850 
851 		// #i25616#
852 		case XML_PTACTION_TRANSPARENCY :
853 			{
854 				OUString aAttrValue( sAttrValue );
855 				GetTransformer().NegPercent(aAttrValue);
856 				pContext->AddAttribute( XML_NAMESPACE_DRAW,
857 										XML_OPACITY,
858 										aAttrValue );
859 				pContext->AddAttribute( XML_NAMESPACE_DRAW,
860 										XML_IMAGE_OPACITY,
861 										aAttrValue );
862 			}
863 			break;
864 
865         case XML_PTACTION_BREAK_INSIDE:
866             {
867                 pContext->AddAttribute(
868                     XML_NAMESPACE_FO, XML_KEEP_TOGETHER,
869                     GetXMLToken(
870                         IsXMLToken( sAttrValue, XML_COLUMNSPLIT_AVOID )
871                         ? XML_ALWAYS
872                         : XML_AUTO ) );
873             }
874             break;
875 		case XML_ATACTION_CAPTION_ESCAPE_OOO:
876 			{
877                 OUString aAttrValue( sAttrValue );
878 				if( aAttrValue.indexOf( sal_Unicode('%') ) != -1 )
879 				{
880 					sal_Int32 nValue = 0;
881                     SvXMLUnitConverter::convertPercent( nValue, sAttrValue );
882 					if( nValue )
883 					{
884 						nValue /= 100;
885 						rtl::OUStringBuffer aOut;
886 					 	SvXMLUnitConverter::convertPercent( aOut, nValue );
887 						aAttrValue = aOut.makeStringAndClear();
888 					}
889 				}
890 				else
891 				{
892 					XMLTransformerBase::ReplaceSingleInchWithIn( aAttrValue );
893 				}
894 
895                 pContext->AddAttribute( sAttrName, aAttrValue );
896 			}
897 			break;
898 		case XML_ATACTION_MOVE_PROTECT:
899             bMoveProtect = IsXMLToken( sAttrValue, XML_TRUE );
900 			pProtectContext = pContext;
901 			break;
902 		case XML_ATACTION_SIZE_PROTECT:
903             bSizeProtect = IsXMLToken( sAttrValue, XML_TRUE );
904 			pProtectContext = pContext;
905 			break;
906 		case XML_ATACTION_PROTECT:
907             aProtectAttrValue = sAttrValue;
908 			pProtectContext = pContext;
909 			break;
910 		case XML_ATACTION_DRAW_MIRROR_OOO:	 // renames draw:mirror to style:mirror and adapts values
911 			{
912                 // --> OD 2005-05-13 #i49139#
913                 aDrawMirrorAttrValue =
914                                 GetXMLToken( IsXMLToken( sAttrValue, XML_TRUE )
915                                              ? XML_HORIZONTAL : XML_NONE );
916                 bExistDrawMirror = sal_True;
917                 pMirrorContext = pContext;
918                 // <--
919 			}
920 			break;
921         // --> OD 2005-05-12 #i49139#
922         case XML_ATACTION_STYLE_MIRROR_OOO:   // adapts style:mirror values
923             {
924                 SvXMLTokenEnumerator aTokenEnum( sAttrValue );
925                 OUString aToken;
926                 while( aTokenEnum.getNextToken( aToken ) )
927                 {
928                     if ( aStyleMirrorAttrValue.getLength() > 0 )
929                     {
930                         aStyleMirrorAttrValue += rtl::OUString::createFromAscii( " " );
931                     }
932 
933                     if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_LEFT_PAGES ) )
934                     {
935                         aStyleMirrorAttrValue += GetXMLToken( XML_HORIZONTAL_ON_EVEN );
936                     }
937                     else if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_RIGHT_PAGES ) )
938                     {
939                         aStyleMirrorAttrValue += GetXMLToken( XML_HORIZONTAL_ON_ODD );
940                     }
941                     else
942                     {
943                         aStyleMirrorAttrValue += aToken;
944                     }
945                 }
946                 bExistStyleMirror = sal_True;
947                 pMirrorContext = pContext;
948             }
949             break;
950         // <--
951 		case XML_ATACTION_GAMMA_OOO:		// converts double value to percentage
952 			{
953                 double fValue = sAttrValue.toDouble();
954 				sal_Int32 nValue = (sal_Int32)((fValue * 100.0) + ( fValue > 0 ? 0.5 : - 0.5 ) );
955 
956 				rtl::OUStringBuffer aOut;
957 				SvXMLUnitConverter::convertPercent( aOut, nValue );
958 				OUString aAttrValue( aOut.makeStringAndClear() );
959                 pContext->AddAttribute( sAttrName, aAttrValue );
960 			}
961 			break;
962 		case XML_ATACTION_OPACITY_FIX:
963 			{
964 				sal_Int32 nValue;
965 				if( sAttrValue.indexOf( sal_Unicode('%') ) != -1 )
966 				{
967 					SvXMLUnitConverter::convertPercent( nValue, sAttrValue );
968 				}
969 				else
970 				{
971 					nValue = sal_Int32( sAttrValue.toDouble() * 100.0 );
972 				}
973 				nValue = 100 - nValue;
974 
975 				rtl::OUStringBuffer aOut;
976 				SvXMLUnitConverter::convertPercent( aOut, nValue );
977 				pContext->AddAttribute( sAttrName, aOut.makeStringAndClear() );
978 			}
979 			break;
980 		default:
981 			OSL_ENSURE( !this, "unknown action" );
982 			break;
983 		}
984 	}
985 
986     // --> OD 2005-05-13 #i49139#
987     if ( bExistStyleMirror )
988     {
989         pMirrorContext->AddAttribute(
990                         GetTransformer().GetNamespaceMap().GetQNameByKey(
991                                 XML_NAMESPACE_STYLE, GetXMLToken( XML_MIRROR ) ),
992                         aStyleMirrorAttrValue);
993     }
994     else if ( bExistDrawMirror )
995     {
996         pMirrorContext->AddAttribute(
997                         GetTransformer().GetNamespaceMap().GetQNameByKey(
998                                 XML_NAMESPACE_STYLE, GetXMLToken( XML_MIRROR ) ),
999                         aDrawMirrorAttrValue);
1000     }
1001     // <--
1002 
1003 	if( bMoveProtect || bSizeProtect || aProtectAttrValue.getLength() )
1004 	{
1005 		if( (bMoveProtect ||bSizeProtect) && IsXMLToken( aProtectAttrValue, XML_NONE ) )
1006 			aProtectAttrValue = OUString();
1007 
1008 		const OUString& rPosition = GetXMLToken( XML_POSITION );
1009 		if( bMoveProtect && -1 == aProtectAttrValue.indexOf( rPosition ) )
1010 		{
1011 			if( aProtectAttrValue.getLength() )
1012 				aProtectAttrValue += OUString::valueOf( sal_Unicode( ' ' ) );
1013 			aProtectAttrValue += rPosition;
1014 		}
1015 
1016 		const OUString& rSize = GetXMLToken( XML_SIZE );
1017 		if( bSizeProtect && -1 == aProtectAttrValue.indexOf( rSize ) )
1018 		{
1019 			if( aProtectAttrValue.getLength() )
1020 				aProtectAttrValue += OUString::valueOf( sal_Unicode( ' ' ) );
1021 			aProtectAttrValue += rSize;
1022 		}
1023 
1024 		pProtectContext->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_STYLE, GetXMLToken( XML_PROTECT ) ), aProtectAttrValue );
1025 	}
1026 
1027     if( pIntervalMinorDivisorContext )
1028     {
1029         if( fIntervalMinor != 0.0 )
1030         {
1031             sal_Int32 nIntervalMinorDivisor = static_cast< sal_Int32 >(
1032                 ::rtl::math::round( fIntervalMajor / fIntervalMinor ));
1033 
1034             ::rtl::OUStringBuffer aBuf;
1035             SvXMLUnitConverter::convertNumber( aBuf, nIntervalMinorDivisor );
1036             pIntervalMinorDivisorContext->AddAttribute(
1037                 GetTransformer().GetNamespaceMap().GetQNameByKey(
1038                     XML_NAMESPACE_CHART,
1039                     GetXMLToken( XML_INTERVAL_MINOR_DIVISOR )),
1040                 aBuf.makeStringAndClear());
1041         }
1042     }
1043 }
1044 
1045 void XMLPropertiesOOoTContext_Impl::EndElement()
1046 {
1047 	if( !m_bPersistent )
1048 		Export();
1049 }
1050 
1051 void XMLPropertiesOOoTContext_Impl::Characters( const OUString& )
1052 {
1053 	// ignore them
1054 }
1055 
1056 void XMLPropertiesOOoTContext_Impl::Export()
1057 {
1058 
1059 	for( sal_uInt16 i=0; i < MAX_PROP_TYPES; i++ )
1060 	{
1061 		if( m_aPropContexts[i].is() )
1062 			m_aPropContexts[i]->Export();
1063 	}
1064 }
1065 
1066 sal_Bool XMLPropertiesOOoTContext_Impl::IsPersistent() const
1067 {
1068 	return m_bPersistent;
1069 }
1070 
1071 
1072 //------------------------------------------------------------------------------
1073 
1074 TYPEINIT1( XMLStyleOOoTContext, XMLPersElemContentTContext );
1075 
1076 XMLStyleOOoTContext::XMLStyleOOoTContext( XMLTransformerBase& rImp,
1077 							  			  const OUString& rQName,
1078 		   				   				  XMLFamilyType eT,
1079 	   									  sal_Bool bPersistent ) :
1080 	XMLPersElemContentTContext( rImp, rQName ),
1081 	m_eFamily( eT ),
1082 	m_bPersistent( bPersistent )
1083 {
1084 }
1085 
1086 XMLStyleOOoTContext::XMLStyleOOoTContext(
1087 		XMLTransformerBase& rImp,
1088 	  	const OUString& rQName,
1089 	    XMLFamilyType eT,
1090 	    sal_uInt16 nPrefix,
1091 		::xmloff::token::XMLTokenEnum eToken,
1092 	   	sal_Bool bPersistent ) :
1093 	XMLPersElemContentTContext( rImp, rQName, nPrefix, eToken ),
1094 	m_eFamily( eT ),
1095 	m_bPersistent( bPersistent )
1096 {
1097 }
1098 
1099 XMLStyleOOoTContext::~XMLStyleOOoTContext()
1100 {
1101 }
1102 
1103 XMLTransformerContext *XMLStyleOOoTContext::CreateChildContext(
1104 			sal_uInt16 nPrefix,
1105 			const OUString& rLocalName,
1106 			const OUString& rQName,
1107 			const Reference< XAttributeList >& rAttrList )
1108 {
1109 	XMLTransformerContext *pContext = 0;
1110 
1111 	if( XML_NAMESPACE_STYLE == nPrefix &&
1112 		IsXMLToken( rLocalName, XML_PROPERTIES ) )
1113 	{
1114 		if( aPropTypes[m_eFamily][0] == XML_PROP_TYPE_END )
1115 		{
1116 			OSL_ENSURE( !this, "unexpected properties element" );
1117 			pContext = m_bPersistent
1118 							? XMLPersElemContentTContext::CreateChildContext(
1119 									nPrefix, rLocalName, rQName, rAttrList )
1120 							: XMLTransformerContext::CreateChildContext(
1121 									nPrefix, rLocalName, rQName, rAttrList );
1122 		}
1123 		else if( aPropTypes[m_eFamily][1] == XML_PROP_TYPE_END )
1124 		{
1125 			sal_uInt16 nActionMap =
1126 				aAttrActionMaps[aPropTypes[m_eFamily][0]];
1127 			if( nActionMap < MAX_OOO_PROP_ACTIONS )
1128 			{
1129 				pContext = new XMLPropertiesOOoTContext_Impl(
1130 									GetTransformer(), rQName,
1131 									aPropTypes[m_eFamily], m_bPersistent );
1132 			}
1133 			else
1134 			{
1135 				if( m_bPersistent )
1136 					pContext = new XMLPersElemContentTContext(
1137 									GetTransformer(), rQName,
1138 									XML_NAMESPACE_STYLE,
1139 									aPropTokens[aPropTypes[m_eFamily][0]] );
1140 				else
1141 					pContext = new XMLRenameElemTransformerContext(
1142 									GetTransformer(), rQName,
1143 									XML_NAMESPACE_STYLE,
1144 									aPropTokens[aPropTypes[m_eFamily][0]] );
1145 			}
1146 		}
1147 		else
1148 		{
1149 			pContext = new XMLPropertiesOOoTContext_Impl(
1150 								GetTransformer(), rQName,
1151 								aPropTypes[m_eFamily], m_bPersistent);
1152 		}
1153 
1154 		if( m_bPersistent )
1155 			AddContent( pContext );
1156 	}
1157 	else
1158 	{
1159 		pContext = m_bPersistent
1160 						? XMLPersElemContentTContext::CreateChildContext(
1161 								nPrefix, rLocalName, rQName, rAttrList )
1162 						: XMLTransformerContext::CreateChildContext(
1163 								nPrefix, rLocalName, rQName, rAttrList );
1164 	}
1165 
1166 	return pContext;
1167 }
1168 
1169 void XMLStyleOOoTContext::StartElement(
1170 		const Reference< XAttributeList >& rAttrList )
1171 {
1172 	XMLTransformerActions *pActions =
1173 		GetTransformer().GetUserDefinedActions( OOO_STYLE_ACTIONS );
1174 	OSL_ENSURE( pActions, "go no actions" );
1175 
1176 	Reference< XAttributeList > xAttrList( rAttrList );
1177 	XMLMutableAttributeList *pMutableAttrList = 0;
1178 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1179 	for( sal_Int16 i=0; i < nAttrCount; i++ )
1180 	{
1181 		const OUString sAttrName = xAttrList->getNameByIndex( i );
1182 		OUString aLocalName;
1183 		sal_uInt16 nPrefix =
1184 			GetTransformer().GetNamespaceMap().GetKeyByAttrName( sAttrName,
1185 																 &aLocalName );
1186 		XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
1187 		XMLTransformerActions::const_iterator aIter =
1188 			pActions->find( aKey );
1189 		if( !(aIter == pActions->end() ) )
1190 		{
1191 			if( !pMutableAttrList )
1192 			{
1193 				pMutableAttrList =
1194 					new XMLMutableAttributeList( xAttrList );
1195 				xAttrList = pMutableAttrList;
1196 			}
1197 			const OUString sAttrValue = xAttrList->getValueByIndex( i );
1198 			switch( (*aIter).second.m_nActionType )
1199 			{
1200 			case XML_ATACTION_STYLE_FAMILY:
1201 				{
1202 					sal_Bool bControl = sal_False;
1203 					if( XML_FAMILY_TYPE_END == m_eFamily )
1204 					{
1205 						if( IsXMLToken( sAttrValue, XML_GRAPHICS ) )
1206 							m_eFamily = XML_FAMILY_TYPE_GRAPHIC;
1207 						else if( IsXMLToken( sAttrValue, XML_PRESENTATION ) )
1208 							m_eFamily = XML_FAMILY_TYPE_PRESENTATION;
1209 						else if( IsXMLToken( sAttrValue, XML_DRAWING_PAGE ) )
1210 							m_eFamily = XML_FAMILY_TYPE_DRAWING_PAGE;
1211 						else if( IsXMLToken( sAttrValue, XML_TEXT) )
1212 							m_eFamily = XML_FAMILY_TYPE_TEXT;
1213 						else if( IsXMLToken( sAttrValue, XML_PARAGRAPH) )
1214 							m_eFamily = XML_FAMILY_TYPE_PARAGRAPH;
1215 						else if( IsXMLToken( sAttrValue, XML_RUBY) )
1216 							m_eFamily = XML_FAMILY_TYPE_RUBY;
1217 						else if( IsXMLToken( sAttrValue, XML_SECTION) )
1218 							m_eFamily = XML_FAMILY_TYPE_SECTION;
1219 						else if( IsXMLToken( sAttrValue, XML_TABLE) )
1220 							m_eFamily = XML_FAMILY_TYPE_TABLE;
1221 						else if( IsXMLToken( sAttrValue, XML_TABLE_COLUMN) )
1222 							m_eFamily = XML_FAMILY_TYPE_TABLE_COLUMN;
1223 						else if( IsXMLToken( sAttrValue, XML_TABLE_ROW) )
1224 							m_eFamily = XML_FAMILY_TYPE_TABLE_ROW;
1225 						else if( IsXMLToken( sAttrValue, XML_TABLE_CELL) )
1226 							m_eFamily = XML_FAMILY_TYPE_TABLE_CELL;
1227 						else if( IsXMLToken( sAttrValue, XML_CHART) )
1228 							m_eFamily = XML_FAMILY_TYPE_CHART;
1229 						else if( IsXMLToken( sAttrValue, XML_CONTROL) )
1230 						{
1231 							m_eFamily = XML_FAMILY_TYPE_PARAGRAPH;
1232 							bControl = sal_True;
1233 						}
1234 					}
1235 					if( XML_FAMILY_TYPE_GRAPHIC == m_eFamily )
1236 					{
1237 						pMutableAttrList->SetValueByIndex( i,
1238 												GetXMLToken( XML_GRAPHIC ) );
1239 					}
1240 					else if( bControl )
1241 					{
1242 						pMutableAttrList->SetValueByIndex( i,
1243 												GetXMLToken( XML_PARAGRAPH ) );
1244 					}
1245 				}
1246 				break;
1247 			case XML_ATACTION_INCH2IN:
1248 				{
1249 					OUString aAttrValue( sAttrValue );
1250 					if( XMLTransformerBase::ReplaceSingleInchWithIn(
1251 								aAttrValue ) )
1252 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1253 				}
1254 				break;
1255 			case XML_ATACTION_ENCODE_STYLE_NAME:
1256 				{
1257 					OUString aAttrValue( sAttrValue );
1258 					if( GetTransformer().EncodeStyleName(aAttrValue) )
1259 					{
1260 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1261 						OUString aNewAttrQName(
1262 							GetTransformer().GetNamespaceMap().
1263 								GetQNameByKey(
1264 									nPrefix, ::xmloff::token::GetXMLToken(
1265 										XML_DISPLAY_NAME ) ) );
1266 						pMutableAttrList->AddAttribute( aNewAttrQName,
1267 														sAttrValue );
1268 					}
1269 				}
1270 				break;
1271 			case XML_ATACTION_ENCODE_STYLE_NAME_REF:
1272 				{
1273 					OUString aAttrValue( sAttrValue );
1274 					if( GetTransformer().EncodeStyleName(aAttrValue) )
1275 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1276 				}
1277 				break;
1278 			case XML_ATACTION_NEG_PERCENT:
1279 				{
1280 					OUString aAttrValue( sAttrValue );
1281 					if( GetTransformer().NegPercent(aAttrValue) )
1282 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1283 				}
1284 				break;
1285 			case XML_ATACTION_URI_OOO:
1286 				{
1287 					OUString aAttrValue( sAttrValue );
1288 					if( GetTransformer().ConvertURIToOASIS( aAttrValue,
1289 							static_cast< sal_Bool >((*aIter).second.m_nParam1)))
1290 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1291 				}
1292 				break;
1293 			default:
1294 				OSL_ENSURE( !this, "unknown action" );
1295 				break;
1296 			}
1297 		}
1298 	}
1299 	if( XML_FAMILY_TYPE_END == m_eFamily )
1300 		m_eFamily = XML_FAMILY_TYPE_TEXT;
1301 	if( m_bPersistent )
1302 		XMLPersElemContentTContext::StartElement( xAttrList );
1303 	else
1304 		GetTransformer().GetDocHandler()->startElement( GetExportQName(),
1305 														xAttrList );
1306 }
1307 
1308 void XMLStyleOOoTContext::EndElement()
1309 {
1310 	if( m_bPersistent )
1311 		XMLPersElemContentTContext::EndElement();
1312 	else
1313 		GetTransformer().GetDocHandler()->endElement( GetExportQName() );
1314 }
1315 
1316 void XMLStyleOOoTContext::Characters( const OUString& )
1317 {
1318 	// element content only:
1319 }
1320 
1321 sal_Bool XMLStyleOOoTContext::IsPersistent() const
1322 {
1323 	return m_bPersistent;
1324 }
1325 
1326 XMLTransformerActions *XMLStyleOOoTContext::CreateTransformerActions(
1327 		sal_uInt16 nType )
1328 {
1329 	XMLTransformerActionInit *pInit = 0;
1330 
1331 	switch( nType )
1332 	{
1333 	case PROP_OOO_GRAPHIC_ATTR_ACTIONS:
1334 		pInit = aGraphicPropertyOOoAttrActionTable;
1335 		break;
1336 	case PROP_OOO_GRAPHIC_ELEM_ACTIONS:
1337 		pInit = aGraphicPropertyOOoElemActionTable;
1338 		break;
1339 	case PROP_OOO_DRAWING_PAGE_ATTR_ACTIONS:
1340 		pInit = aDrawingPagePropertyOOoAttrActionTable;
1341 		break;
1342 	case PROP_OOO_PAGE_LAYOUT_ATTR_ACTIONS:
1343 		pInit = aPageLayoutPropertyOOoAttrActionTable;
1344 		break;
1345 	case PROP_OOO_HEADER_FOOTER_ATTR_ACTIONS:
1346 		pInit = aHeaderFooterPropertyOOoAttrActionTable;
1347 		break;
1348 	case PROP_OOO_TEXT_ATTR_ACTIONS:
1349 		pInit = aTextPropertyOOoAttrActionTable;
1350 		break;
1351 	case PROP_OOO_TEXT_ELEM_ACTIONS:
1352 		pInit = aTextPropertyOOoElemActionTable;
1353 		break;
1354 	case PROP_OOO_PARAGRAPH_ATTR_ACTIONS:
1355 		pInit = aParagraphPropertyOOoAttrActionTable;
1356 		break;
1357     case PROP_OOO_PARAGRAPH_ELEM_ACTIONS:
1358 		pInit = aParagraphPropertyOOoElemActionTable;
1359 		break;
1360 	case PROP_OOO_SECTION_ATTR_ACTIONS:
1361 		pInit = aSectionPropertyOOoAttrActionTable;
1362 		break;
1363 	case PROP_OOO_TABLE_ATTR_ACTIONS:
1364 		pInit = aTablePropertyOOoAttrActionTable;
1365 		break;
1366 	case PROP_OOO_TABLE_COLUMN_ATTR_ACTIONS:
1367 		pInit = aTableColumnPropertyOOoAttrActionTable;
1368 		break;
1369 	case PROP_OOO_TABLE_ROW_ATTR_ACTIONS:
1370 		pInit = aTableRowPropertyOOoAttrActionTable;
1371 		break;
1372 	case PROP_OOO_TABLE_CELL_ATTR_ACTIONS:
1373 		pInit = aTableCellPropertyOOoAttrActionTable;
1374 		break;
1375 	case PROP_OOO_TABLE_CELL_ELEM_ACTIONS:
1376 		pInit = aTableCellPropertyOOoElemActionTable;
1377 		break;
1378 	case PROP_OOO_LIST_LEVEL_ATTR_ACTIONS:
1379 		pInit = aListLevelPropertyOOoAttrActionTable;
1380 		break;
1381 	case PROP_OOO_CHART_ATTR_ACTIONS:
1382 		pInit = aChartPropertyOOoAttrActionTable;
1383 		break;
1384 	case PROP_OOO_CHART_ELEM_ACTIONS:
1385 		pInit = aChartPropertyOOoElemActionTable;
1386 		break;
1387 	}
1388 
1389 	XMLTransformerActions *pActions = 0;
1390 	if( pInit )
1391 		pActions = new XMLTransformerActions( pInit );
1392 
1393 	return pActions;
1394 }
1395