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