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