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                         default:
775                             OSL_ENSURE( false, "invalid named symbol" );
776                             break;
777                     }
778 
779                     if( eToken != XML_TOKEN_INVALID )
780                     {
781                         pContext->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
782                                                     XML_NAMESPACE_CHART, GetXMLToken( XML_SYMBOL_NAME )),
783                                                 GetXMLToken( eToken ));
784                     }
785                 }
786                 else
787                 {
788                     switch( nSymbolType )
789                     {
790                         // NONE
791                         case -3:
792                             pContext->AddAttribute(
793                                 aNewAttrName, GetXMLToken( XML_NONE ));
794                             break;
795                             // AUTO
796                         case -2:
797                             pContext->AddAttribute(
798                                 aNewAttrName, GetXMLToken( XML_AUTOMATIC ));
799                             break;
800                             // BITMAPURL
801                         case -1:
802                             pContext->AddAttribute(
803                                 aNewAttrName, GetXMLToken( XML_IMAGE ));
804                             break;
805                         default:
806                             OSL_ENSURE( false, "invalid symbol type" );
807                             pContext->AddAttribute(
808                                 aNewAttrName, GetXMLToken( XML_NONE ));
809                             break;
810                     }
811                 }
812             }
813             break;
814         case XML_PTACTION_SYMBOL_IMAGE_NAME:
815             {
816                 // create an xlink:href element for URI attribute
817                 XMLPersAttrListTContext *pSymbolImageContext = new XMLPersAttrListTContext(
818                     GetTransformer(), GetTransformer().GetNamespaceMap().GetQNameByKey(
819                         XML_NAMESPACE_CHART, GetXMLToken( XML_SYMBOL_IMAGE )));
820 
821                 OUString aAttrValue( sAttrValue );
822                 if( GetTransformer().ConvertURIToOASIS( aAttrValue, sal_True ))
823                 {
824                     pSymbolImageContext->AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aAttrValue );
825                     pContext->AddContent( pSymbolImageContext );
826                 }
827             }
828             break;
829 
830 		// #i25616#
831 		case XML_PTACTION_TRANSPARENCY :
832 			{
833 				OUString aAttrValue( sAttrValue );
834 				GetTransformer().NegPercent(aAttrValue);
835 				pContext->AddAttribute( XML_NAMESPACE_DRAW,
836 										XML_OPACITY,
837 										aAttrValue );
838 				pContext->AddAttribute( XML_NAMESPACE_DRAW,
839 										XML_IMAGE_OPACITY,
840 										aAttrValue );
841 			}
842 			break;
843 
844         case XML_PTACTION_BREAK_INSIDE:
845             {
846                 pContext->AddAttribute(
847                     XML_NAMESPACE_FO, XML_KEEP_TOGETHER,
848                     GetXMLToken(
849                         IsXMLToken( sAttrValue, XML_COLUMNSPLIT_AVOID )
850                         ? XML_ALWAYS
851                         : XML_AUTO ) );
852             }
853             break;
854 		case XML_ATACTION_CAPTION_ESCAPE_OOO:
855 			{
856                 OUString aAttrValue( sAttrValue );
857 				if( aAttrValue.indexOf( sal_Unicode('%') ) != -1 )
858 				{
859 					sal_Int32 nValue = 0;
860                     SvXMLUnitConverter::convertPercent( nValue, sAttrValue );
861 					if( nValue )
862 					{
863 						nValue /= 100;
864 						rtl::OUStringBuffer aOut;
865 					 	SvXMLUnitConverter::convertPercent( aOut, nValue );
866 						aAttrValue = aOut.makeStringAndClear();
867 					}
868 				}
869 				else
870 				{
871 					XMLTransformerBase::ReplaceSingleInchWithIn( aAttrValue );
872 				}
873 
874                 pContext->AddAttribute( sAttrName, aAttrValue );
875 			}
876 			break;
877 		case XML_ATACTION_MOVE_PROTECT:
878             bMoveProtect = IsXMLToken( sAttrValue, XML_TRUE );
879 			pProtectContext = pContext;
880 			break;
881 		case XML_ATACTION_SIZE_PROTECT:
882             bSizeProtect = IsXMLToken( sAttrValue, XML_TRUE );
883 			pProtectContext = pContext;
884 			break;
885 		case XML_ATACTION_PROTECT:
886             aProtectAttrValue = sAttrValue;
887 			pProtectContext = pContext;
888 			break;
889 		case XML_ATACTION_DRAW_MIRROR_OOO:	 // renames draw:mirror to style:mirror and adapts values
890 			{
891                 // --> OD 2005-05-13 #i49139#
892                 aDrawMirrorAttrValue =
893                                 GetXMLToken( IsXMLToken( sAttrValue, XML_TRUE )
894                                              ? XML_HORIZONTAL : XML_NONE );
895                 bExistDrawMirror = sal_True;
896                 pMirrorContext = pContext;
897                 // <--
898 			}
899 			break;
900         // --> OD 2005-05-12 #i49139#
901         case XML_ATACTION_STYLE_MIRROR_OOO:   // adapts style:mirror values
902             {
903                 SvXMLTokenEnumerator aTokenEnum( sAttrValue );
904                 OUString aToken;
905                 while( aTokenEnum.getNextToken( aToken ) )
906                 {
907                     if ( aStyleMirrorAttrValue.getLength() > 0 )
908                     {
909                         aStyleMirrorAttrValue += rtl::OUString::createFromAscii( " " );
910                     }
911 
912                     if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_LEFT_PAGES ) )
913                     {
914                         aStyleMirrorAttrValue += GetXMLToken( XML_HORIZONTAL_ON_EVEN );
915                     }
916                     else if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_RIGHT_PAGES ) )
917                     {
918                         aStyleMirrorAttrValue += GetXMLToken( XML_HORIZONTAL_ON_ODD );
919                     }
920                     else
921                     {
922                         aStyleMirrorAttrValue += aToken;
923                     }
924                 }
925                 bExistStyleMirror = sal_True;
926                 pMirrorContext = pContext;
927             }
928             break;
929         // <--
930 		case XML_ATACTION_GAMMA_OOO:		// converts double value to percentage
931 			{
932                 double fValue = sAttrValue.toDouble();
933 				sal_Int32 nValue = (sal_Int32)((fValue * 100.0) + ( fValue > 0 ? 0.5 : - 0.5 ) );
934 
935 				rtl::OUStringBuffer aOut;
936 				SvXMLUnitConverter::convertPercent( aOut, nValue );
937 				OUString aAttrValue( aOut.makeStringAndClear() );
938                 pContext->AddAttribute( sAttrName, aAttrValue );
939 			}
940 			break;
941 		case XML_ATACTION_OPACITY_FIX:
942 			{
943 				sal_Int32 nValue;
944 				if( sAttrValue.indexOf( sal_Unicode('%') ) != -1 )
945 				{
946 					SvXMLUnitConverter::convertPercent( nValue, sAttrValue );
947 				}
948 				else
949 				{
950 					nValue = sal_Int32( sAttrValue.toDouble() * 100.0 );
951 				}
952 				nValue = 100 - nValue;
953 
954 				rtl::OUStringBuffer aOut;
955 				SvXMLUnitConverter::convertPercent( aOut, nValue );
956 				pContext->AddAttribute( sAttrName, aOut.makeStringAndClear() );
957 			}
958 			break;
959 		default:
960 			OSL_ENSURE( !this, "unknown action" );
961 			break;
962 		}
963 	}
964 
965     // --> OD 2005-05-13 #i49139#
966     if ( bExistStyleMirror )
967     {
968         pMirrorContext->AddAttribute(
969                         GetTransformer().GetNamespaceMap().GetQNameByKey(
970                                 XML_NAMESPACE_STYLE, GetXMLToken( XML_MIRROR ) ),
971                         aStyleMirrorAttrValue);
972     }
973     else if ( bExistDrawMirror )
974     {
975         pMirrorContext->AddAttribute(
976                         GetTransformer().GetNamespaceMap().GetQNameByKey(
977                                 XML_NAMESPACE_STYLE, GetXMLToken( XML_MIRROR ) ),
978                         aDrawMirrorAttrValue);
979     }
980     // <--
981 
982 	if( bMoveProtect || bSizeProtect || aProtectAttrValue.getLength() )
983 	{
984 		if( (bMoveProtect ||bSizeProtect) && IsXMLToken( aProtectAttrValue, XML_NONE ) )
985 			aProtectAttrValue = OUString();
986 
987 		const OUString& rPosition = GetXMLToken( XML_POSITION );
988 		if( bMoveProtect && -1 == aProtectAttrValue.indexOf( rPosition ) )
989 		{
990 			if( aProtectAttrValue.getLength() )
991 				aProtectAttrValue += OUString::valueOf( sal_Unicode( ' ' ) );
992 			aProtectAttrValue += rPosition;
993 		}
994 
995 		const OUString& rSize = GetXMLToken( XML_SIZE );
996 		if( bSizeProtect && -1 == aProtectAttrValue.indexOf( rSize ) )
997 		{
998 			if( aProtectAttrValue.getLength() )
999 				aProtectAttrValue += OUString::valueOf( sal_Unicode( ' ' ) );
1000 			aProtectAttrValue += rSize;
1001 		}
1002 
1003 		pProtectContext->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_STYLE, GetXMLToken( XML_PROTECT ) ), aProtectAttrValue );
1004 	}
1005 
1006     if( pIntervalMinorDivisorContext )
1007     {
1008         if( fIntervalMinor != 0.0 )
1009         {
1010             sal_Int32 nIntervalMinorDivisor = static_cast< sal_Int32 >(
1011                 ::rtl::math::round( fIntervalMajor / fIntervalMinor ));
1012 
1013             ::rtl::OUStringBuffer aBuf;
1014             SvXMLUnitConverter::convertNumber( aBuf, nIntervalMinorDivisor );
1015             pIntervalMinorDivisorContext->AddAttribute(
1016                 GetTransformer().GetNamespaceMap().GetQNameByKey(
1017                     XML_NAMESPACE_CHART,
1018                     GetXMLToken( XML_INTERVAL_MINOR_DIVISOR )),
1019                 aBuf.makeStringAndClear());
1020         }
1021     }
1022 }
1023 
1024 void XMLPropertiesOOoTContext_Impl::EndElement()
1025 {
1026 	if( !m_bPersistent )
1027 		Export();
1028 }
1029 
1030 void XMLPropertiesOOoTContext_Impl::Characters( const OUString& )
1031 {
1032 	// ignore them
1033 }
1034 
1035 void XMLPropertiesOOoTContext_Impl::Export()
1036 {
1037 
1038 	for( sal_uInt16 i=0; i < MAX_PROP_TYPES; i++ )
1039 	{
1040 		if( m_aPropContexts[i].is() )
1041 			m_aPropContexts[i]->Export();
1042 	}
1043 }
1044 
1045 sal_Bool XMLPropertiesOOoTContext_Impl::IsPersistent() const
1046 {
1047 	return m_bPersistent;
1048 }
1049 
1050 
1051 //------------------------------------------------------------------------------
1052 
1053 TYPEINIT1( XMLStyleOOoTContext, XMLPersElemContentTContext );
1054 
1055 XMLStyleOOoTContext::XMLStyleOOoTContext( XMLTransformerBase& rImp,
1056 							  			  const OUString& rQName,
1057 		   				   				  XMLFamilyType eT,
1058 	   									  sal_Bool bPersistent ) :
1059 	XMLPersElemContentTContext( rImp, rQName ),
1060 	m_eFamily( eT ),
1061 	m_bPersistent( bPersistent )
1062 {
1063 }
1064 
1065 XMLStyleOOoTContext::XMLStyleOOoTContext(
1066 		XMLTransformerBase& rImp,
1067 	  	const OUString& rQName,
1068 	    XMLFamilyType eT,
1069 	    sal_uInt16 nPrefix,
1070 		::xmloff::token::XMLTokenEnum eToken,
1071 	   	sal_Bool bPersistent ) :
1072 	XMLPersElemContentTContext( rImp, rQName, nPrefix, eToken ),
1073 	m_eFamily( eT ),
1074 	m_bPersistent( bPersistent )
1075 {
1076 }
1077 
1078 XMLStyleOOoTContext::~XMLStyleOOoTContext()
1079 {
1080 }
1081 
1082 XMLTransformerContext *XMLStyleOOoTContext::CreateChildContext(
1083 			sal_uInt16 nPrefix,
1084 			const OUString& rLocalName,
1085 			const OUString& rQName,
1086 			const Reference< XAttributeList >& rAttrList )
1087 {
1088 	XMLTransformerContext *pContext = 0;
1089 
1090 	if( XML_NAMESPACE_STYLE == nPrefix &&
1091 		IsXMLToken( rLocalName, XML_PROPERTIES ) )
1092 	{
1093 		if( aPropTypes[m_eFamily][0] == XML_PROP_TYPE_END )
1094 		{
1095 			OSL_ENSURE( !this, "unexpected properties element" );
1096 			pContext = m_bPersistent
1097 							? XMLPersElemContentTContext::CreateChildContext(
1098 									nPrefix, rLocalName, rQName, rAttrList )
1099 							: XMLTransformerContext::CreateChildContext(
1100 									nPrefix, rLocalName, rQName, rAttrList );
1101 		}
1102 		else if( aPropTypes[m_eFamily][1] == XML_PROP_TYPE_END )
1103 		{
1104 			sal_uInt16 nActionMap =
1105 				aAttrActionMaps[aPropTypes[m_eFamily][0]];
1106 			if( nActionMap < MAX_OOO_PROP_ACTIONS )
1107 			{
1108 				pContext = new XMLPropertiesOOoTContext_Impl(
1109 									GetTransformer(), rQName,
1110 									aPropTypes[m_eFamily], m_bPersistent );
1111 			}
1112 			else
1113 			{
1114 				if( m_bPersistent )
1115 					pContext = new XMLPersElemContentTContext(
1116 									GetTransformer(), rQName,
1117 									XML_NAMESPACE_STYLE,
1118 									aPropTokens[aPropTypes[m_eFamily][0]] );
1119 				else
1120 					pContext = new XMLRenameElemTransformerContext(
1121 									GetTransformer(), rQName,
1122 									XML_NAMESPACE_STYLE,
1123 									aPropTokens[aPropTypes[m_eFamily][0]] );
1124 			}
1125 		}
1126 		else
1127 		{
1128 			pContext = new XMLPropertiesOOoTContext_Impl(
1129 								GetTransformer(), rQName,
1130 								aPropTypes[m_eFamily], m_bPersistent);
1131 		}
1132 
1133 		if( m_bPersistent )
1134 			AddContent( pContext );
1135 	}
1136 	else
1137 	{
1138 		pContext = m_bPersistent
1139 						? XMLPersElemContentTContext::CreateChildContext(
1140 								nPrefix, rLocalName, rQName, rAttrList )
1141 						: XMLTransformerContext::CreateChildContext(
1142 								nPrefix, rLocalName, rQName, rAttrList );
1143 	}
1144 
1145 	return pContext;
1146 }
1147 
1148 void XMLStyleOOoTContext::StartElement(
1149 		const Reference< XAttributeList >& rAttrList )
1150 {
1151 	XMLTransformerActions *pActions =
1152 		GetTransformer().GetUserDefinedActions( OOO_STYLE_ACTIONS );
1153 	OSL_ENSURE( pActions, "go no actions" );
1154 
1155 	Reference< XAttributeList > xAttrList( rAttrList );
1156 	XMLMutableAttributeList *pMutableAttrList = 0;
1157 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1158 	for( sal_Int16 i=0; i < nAttrCount; i++ )
1159 	{
1160 		const OUString sAttrName = xAttrList->getNameByIndex( i );
1161 		OUString aLocalName;
1162 		sal_uInt16 nPrefix =
1163 			GetTransformer().GetNamespaceMap().GetKeyByAttrName( sAttrName,
1164 																 &aLocalName );
1165 		XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
1166 		XMLTransformerActions::const_iterator aIter =
1167 			pActions->find( aKey );
1168 		if( !(aIter == pActions->end() ) )
1169 		{
1170 			if( !pMutableAttrList )
1171 			{
1172 				pMutableAttrList =
1173 					new XMLMutableAttributeList( xAttrList );
1174 				xAttrList = pMutableAttrList;
1175 			}
1176 			const OUString sAttrValue = xAttrList->getValueByIndex( i );
1177 			switch( (*aIter).second.m_nActionType )
1178 			{
1179 			case XML_ATACTION_STYLE_FAMILY:
1180 				{
1181 					sal_Bool bControl = sal_False;
1182 					if( XML_FAMILY_TYPE_END == m_eFamily )
1183 					{
1184 						if( IsXMLToken( sAttrValue, XML_GRAPHICS ) )
1185 							m_eFamily = XML_FAMILY_TYPE_GRAPHIC;
1186 						else if( IsXMLToken( sAttrValue, XML_PRESENTATION ) )
1187 							m_eFamily = XML_FAMILY_TYPE_PRESENTATION;
1188 						else if( IsXMLToken( sAttrValue, XML_DRAWING_PAGE ) )
1189 							m_eFamily = XML_FAMILY_TYPE_DRAWING_PAGE;
1190 						else if( IsXMLToken( sAttrValue, XML_TEXT) )
1191 							m_eFamily = XML_FAMILY_TYPE_TEXT;
1192 						else if( IsXMLToken( sAttrValue, XML_PARAGRAPH) )
1193 							m_eFamily = XML_FAMILY_TYPE_PARAGRAPH;
1194 						else if( IsXMLToken( sAttrValue, XML_RUBY) )
1195 							m_eFamily = XML_FAMILY_TYPE_RUBY;
1196 						else if( IsXMLToken( sAttrValue, XML_SECTION) )
1197 							m_eFamily = XML_FAMILY_TYPE_SECTION;
1198 						else if( IsXMLToken( sAttrValue, XML_TABLE) )
1199 							m_eFamily = XML_FAMILY_TYPE_TABLE;
1200 						else if( IsXMLToken( sAttrValue, XML_TABLE_COLUMN) )
1201 							m_eFamily = XML_FAMILY_TYPE_TABLE_COLUMN;
1202 						else if( IsXMLToken( sAttrValue, XML_TABLE_ROW) )
1203 							m_eFamily = XML_FAMILY_TYPE_TABLE_ROW;
1204 						else if( IsXMLToken( sAttrValue, XML_TABLE_CELL) )
1205 							m_eFamily = XML_FAMILY_TYPE_TABLE_CELL;
1206 						else if( IsXMLToken( sAttrValue, XML_CHART) )
1207 							m_eFamily = XML_FAMILY_TYPE_CHART;
1208 						else if( IsXMLToken( sAttrValue, XML_CONTROL) )
1209 						{
1210 							m_eFamily = XML_FAMILY_TYPE_PARAGRAPH;
1211 							bControl = sal_True;
1212 						}
1213 					}
1214 					if( XML_FAMILY_TYPE_GRAPHIC == m_eFamily )
1215 					{
1216 						pMutableAttrList->SetValueByIndex( i,
1217 												GetXMLToken( XML_GRAPHIC ) );
1218 					}
1219 					else if( bControl )
1220 					{
1221 						pMutableAttrList->SetValueByIndex( i,
1222 												GetXMLToken( XML_PARAGRAPH ) );
1223 					}
1224 				}
1225 				break;
1226 			case XML_ATACTION_INCH2IN:
1227 				{
1228 					OUString aAttrValue( sAttrValue );
1229 					if( XMLTransformerBase::ReplaceSingleInchWithIn(
1230 								aAttrValue ) )
1231 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1232 				}
1233 				break;
1234 			case XML_ATACTION_ENCODE_STYLE_NAME:
1235 				{
1236 					OUString aAttrValue( sAttrValue );
1237 					if( GetTransformer().EncodeStyleName(aAttrValue) )
1238 					{
1239 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1240 						OUString aNewAttrQName(
1241 							GetTransformer().GetNamespaceMap().
1242 								GetQNameByKey(
1243 									nPrefix, ::xmloff::token::GetXMLToken(
1244 										XML_DISPLAY_NAME ) ) );
1245 						pMutableAttrList->AddAttribute( aNewAttrQName,
1246 														sAttrValue );
1247 					}
1248 				}
1249 				break;
1250 			case XML_ATACTION_ENCODE_STYLE_NAME_REF:
1251 				{
1252 					OUString aAttrValue( sAttrValue );
1253 					if( GetTransformer().EncodeStyleName(aAttrValue) )
1254 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1255 				}
1256 				break;
1257 			case XML_ATACTION_NEG_PERCENT:
1258 				{
1259 					OUString aAttrValue( sAttrValue );
1260 					if( GetTransformer().NegPercent(aAttrValue) )
1261 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1262 				}
1263 				break;
1264 			case XML_ATACTION_URI_OOO:
1265 				{
1266 					OUString aAttrValue( sAttrValue );
1267 					if( GetTransformer().ConvertURIToOASIS( aAttrValue,
1268 							static_cast< sal_Bool >((*aIter).second.m_nParam1)))
1269 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
1270 				}
1271 				break;
1272 			default:
1273 				OSL_ENSURE( !this, "unknown action" );
1274 				break;
1275 			}
1276 		}
1277 	}
1278 	if( XML_FAMILY_TYPE_END == m_eFamily )
1279 		m_eFamily = XML_FAMILY_TYPE_TEXT;
1280 	if( m_bPersistent )
1281 		XMLPersElemContentTContext::StartElement( xAttrList );
1282 	else
1283 		GetTransformer().GetDocHandler()->startElement( GetExportQName(),
1284 														xAttrList );
1285 }
1286 
1287 void XMLStyleOOoTContext::EndElement()
1288 {
1289 	if( m_bPersistent )
1290 		XMLPersElemContentTContext::EndElement();
1291 	else
1292 		GetTransformer().GetDocHandler()->endElement( GetExportQName() );
1293 }
1294 
1295 void XMLStyleOOoTContext::Characters( const OUString& )
1296 {
1297 	// element content only:
1298 }
1299 
1300 sal_Bool XMLStyleOOoTContext::IsPersistent() const
1301 {
1302 	return m_bPersistent;
1303 }
1304 
1305 XMLTransformerActions *XMLStyleOOoTContext::CreateTransformerActions(
1306 		sal_uInt16 nType )
1307 {
1308 	XMLTransformerActionInit *pInit = 0;
1309 
1310 	switch( nType )
1311 	{
1312 	case PROP_OOO_GRAPHIC_ATTR_ACTIONS:
1313 		pInit = aGraphicPropertyOOoAttrActionTable;
1314 		break;
1315 	case PROP_OOO_GRAPHIC_ELEM_ACTIONS:
1316 		pInit = aGraphicPropertyOOoElemActionTable;
1317 		break;
1318 	case PROP_OOO_DRAWING_PAGE_ATTR_ACTIONS:
1319 		pInit = aDrawingPagePropertyOOoAttrActionTable;
1320 		break;
1321 	case PROP_OOO_PAGE_LAYOUT_ATTR_ACTIONS:
1322 		pInit = aPageLayoutPropertyOOoAttrActionTable;
1323 		break;
1324 	case PROP_OOO_HEADER_FOOTER_ATTR_ACTIONS:
1325 		pInit = aHeaderFooterPropertyOOoAttrActionTable;
1326 		break;
1327 	case PROP_OOO_TEXT_ATTR_ACTIONS:
1328 		pInit = aTextPropertyOOoAttrActionTable;
1329 		break;
1330 	case PROP_OOO_TEXT_ELEM_ACTIONS:
1331 		pInit = aTextPropertyOOoElemActionTable;
1332 		break;
1333 	case PROP_OOO_PARAGRAPH_ATTR_ACTIONS:
1334 		pInit = aParagraphPropertyOOoAttrActionTable;
1335 		break;
1336     case PROP_OOO_PARAGRAPH_ELEM_ACTIONS:
1337 		pInit = aParagraphPropertyOOoElemActionTable;
1338 		break;
1339 	case PROP_OOO_SECTION_ATTR_ACTIONS:
1340 		pInit = aSectionPropertyOOoAttrActionTable;
1341 		break;
1342 	case PROP_OOO_TABLE_ATTR_ACTIONS:
1343 		pInit = aTablePropertyOOoAttrActionTable;
1344 		break;
1345 	case PROP_OOO_TABLE_COLUMN_ATTR_ACTIONS:
1346 		pInit = aTableColumnPropertyOOoAttrActionTable;
1347 		break;
1348 	case PROP_OOO_TABLE_ROW_ATTR_ACTIONS:
1349 		pInit = aTableRowPropertyOOoAttrActionTable;
1350 		break;
1351 	case PROP_OOO_TABLE_CELL_ATTR_ACTIONS:
1352 		pInit = aTableCellPropertyOOoAttrActionTable;
1353 		break;
1354 	case PROP_OOO_TABLE_CELL_ELEM_ACTIONS:
1355 		pInit = aTableCellPropertyOOoElemActionTable;
1356 		break;
1357 	case PROP_OOO_LIST_LEVEL_ATTR_ACTIONS:
1358 		pInit = aListLevelPropertyOOoAttrActionTable;
1359 		break;
1360 	case PROP_OOO_CHART_ATTR_ACTIONS:
1361 		pInit = aChartPropertyOOoAttrActionTable;
1362 		break;
1363 	case PROP_OOO_CHART_ELEM_ACTIONS:
1364 		pInit = aChartPropertyOOoElemActionTable;
1365 		break;
1366 	}
1367 
1368 	XMLTransformerActions *pActions = 0;
1369 	if( pInit )
1370 		pActions = new XMLTransformerActions( pInit );
1371 
1372 	return pActions;
1373 }
1374