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 "ximpcustomshape.hxx" 31 #include "ximpshap.hxx" 32 #include "xmlehelp.hxx" 33 #include <rtl/math.hxx> 34 #include <rtl/ustrbuf.hxx> 35 #include <rtl/ustring.hxx> 36 #include <com/sun/star/uno/Reference.h> 37 #include <com/sun/star/beans/XPropertySet.hpp> 38 #include <com/sun/star/xml/sax/XAttributeList.hpp> 39 #include <com/sun/star/container/XIndexContainer.hpp> 40 #include <xmloff/xmltoken.hxx> 41 #include "EnhancedCustomShapeToken.hxx" 42 #include <xmloff/xmlimp.hxx> 43 #include <xmloff/xmltkmap.hxx> 44 #include "xmloff/xmlnmspe.hxx" 45 #include <xmloff/nmspmap.hxx> 46 #include <xmloff/xmluconv.hxx> 47 #include "xexptran.hxx" 48 #include "xmloff/xmlerror.hxx" 49 #include <tools/debug.hxx> 50 #include <com/sun/star/drawing/Direction3D.hpp> 51 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp> 52 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp> 53 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp> 54 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp> 55 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp> 56 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp> 57 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp> 58 #include <com/sun/star/drawing/ProjectionMode.hpp> 59 #include <hash_map> 60 61 using namespace ::com::sun::star; 62 using namespace ::xmloff::token; 63 using namespace ::xmloff::EnhancedCustomShapeToken; 64 65 TYPEINIT1( XMLEnhancedCustomShapeContext, SvXMLImportContext ); 66 67 XMLEnhancedCustomShapeContext::XMLEnhancedCustomShapeContext( SvXMLImport& rImport, 68 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape, 69 sal_uInt16 nPrefix, const rtl::OUString& rLocalName, 70 std::vector< com::sun::star::beans::PropertyValue >& rCustomShapeGeometry ) : 71 SvXMLImportContext( rImport, nPrefix, rLocalName ), 72 mrUnitConverter( rImport.GetMM100UnitConverter() ), 73 mrxShape( rxShape ), 74 mrCustomShapeGeometry( rCustomShapeGeometry ) 75 { 76 } 77 78 const SvXMLEnumMapEntry aXML_GluePointEnumMap[] = 79 { 80 { XML_NONE, 0 }, 81 { XML_SEGMENTS, 1 }, 82 { XML_NONE, 2 }, 83 { XML_RECTANGLE, 3 }, 84 { XML_TOKEN_INVALID, 0 } 85 }; 86 void GetBool( std::vector< com::sun::star::beans::PropertyValue >& rDest, 87 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 88 { 89 sal_Bool bAttrBool; 90 if ( SvXMLUnitConverter::convertBool( bAttrBool, rValue ) ) 91 { 92 beans::PropertyValue aProp; 93 aProp.Name = EASGet( eDestProp ); 94 aProp.Value <<= bAttrBool; 95 rDest.push_back( aProp ); 96 } 97 } 98 99 void GetInt32( std::vector< com::sun::star::beans::PropertyValue >& rDest, 100 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 101 { 102 sal_Int32 nAttrNumber; 103 if ( SvXMLUnitConverter::convertNumber( nAttrNumber, rValue ) ) 104 { 105 beans::PropertyValue aProp; 106 aProp.Name = EASGet( eDestProp ); 107 aProp.Value <<= nAttrNumber; 108 rDest.push_back( aProp ); 109 } 110 } 111 112 void GetDouble( std::vector< com::sun::star::beans::PropertyValue >& rDest, 113 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 114 { 115 double fAttrDouble; 116 if ( SvXMLUnitConverter::convertDouble( fAttrDouble, rValue ) ) 117 { 118 beans::PropertyValue aProp; 119 aProp.Name = EASGet( eDestProp ); 120 aProp.Value <<= fAttrDouble; 121 rDest.push_back( aProp ); 122 } 123 } 124 125 void GetDistance( std::vector< com::sun::star::beans::PropertyValue >& rDest, 126 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 127 { 128 double fAttrDouble; 129 MapUnit eSrcUnit( SvXMLExportHelper::GetUnitFromString( rValue, MAP_100TH_MM ) ); 130 if ( SvXMLUnitConverter::convertDouble( fAttrDouble, rValue, eSrcUnit, MAP_100TH_MM ) ) 131 { 132 beans::PropertyValue aProp; 133 aProp.Name = EASGet( eDestProp ); 134 aProp.Value <<= fAttrDouble; 135 rDest.push_back( aProp ); 136 } 137 } 138 139 void GetString( std::vector< com::sun::star::beans::PropertyValue >& rDest, 140 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 141 { 142 beans::PropertyValue aProp; 143 aProp.Name = EASGet( eDestProp ); 144 aProp.Value <<= rValue; 145 rDest.push_back( aProp ); 146 } 147 148 void GetEnum( std::vector< com::sun::star::beans::PropertyValue >& rDest, 149 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp, 150 const SvXMLEnumMapEntry& rMap ) 151 { 152 sal_uInt16 eKind; 153 if( SvXMLUnitConverter::convertEnum( eKind, rValue, &rMap ) ) 154 { 155 sal_Int16 nEnum = (sal_Int16)eKind; 156 beans::PropertyValue aProp; 157 aProp.Name = EASGet( eDestProp ); 158 aProp.Value <<= nEnum; 159 rDest.push_back( aProp ); 160 } 161 } 162 163 void GetDoublePercentage( std::vector< com::sun::star::beans::PropertyValue >& rDest, 164 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 165 { 166 MapUnit eSrcUnit = SvXMLExportHelper::GetUnitFromString( rValue, MAP_100TH_MM ); 167 if ( eSrcUnit == MAP_RELATIVE ) 168 { 169 rtl_math_ConversionStatus eStatus; 170 double fAttrDouble = ::rtl::math::stringToDouble( rValue, 171 (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL ); 172 if ( eStatus == rtl_math_ConversionStatus_Ok ) 173 { 174 beans::PropertyValue aProp; 175 aProp.Name = EASGet( eDestProp ); 176 aProp.Value <<= fAttrDouble; 177 rDest.push_back( aProp ); 178 } 179 } 180 } 181 182 void GetB3DVector( std::vector< com::sun::star::beans::PropertyValue >& rDest, 183 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 184 { 185 ::basegfx::B3DVector aB3DVector; 186 if ( SvXMLUnitConverter::convertB3DVector( aB3DVector, rValue ) ) 187 { 188 drawing::Direction3D aDirection3D( aB3DVector.getX(), aB3DVector.getY(), aB3DVector.getZ() ); 189 beans::PropertyValue aProp; 190 aProp.Name = EASGet( eDestProp ); 191 aProp.Value <<= aDirection3D; 192 rDest.push_back( aProp ); 193 } 194 } 195 196 sal_Bool GetEquationName( const rtl::OUString& rEquation, const sal_Int32 nStart, rtl::OUString& rEquationName ) 197 { 198 sal_Int32 nIndex = nStart; 199 while( nIndex < rEquation.getLength() ) 200 { 201 sal_Unicode nChar = rEquation[ nIndex ]; 202 if ( 203 ( ( nChar >= 'a' ) && ( nChar <= 'z' ) ) 204 || ( ( nChar >= 'A' ) && ( nChar <= 'Z' ) ) 205 || ( ( nChar >= '0' ) && ( nChar <= '9' ) ) 206 ) 207 { 208 nIndex++; 209 } 210 else 211 break; 212 } 213 sal_Bool bValid = ( nIndex - nStart ) != 0; 214 if ( bValid ) 215 rEquationName = rEquation.copy( nStart, nIndex - nStart ); 216 return bValid; 217 } 218 219 sal_Bool GetNextParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter, sal_Int32& nIndex, const rtl::OUString& rParaString ) 220 { 221 if ( nIndex >= rParaString.getLength() ) 222 return sal_False; 223 224 sal_Bool bValid = sal_True; 225 sal_Bool bNumberRequired = sal_True; 226 sal_Bool bMustBePositiveWholeNumbered = sal_False; 227 228 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL; 229 if ( rParaString[ nIndex ] == (sal_Unicode)'$' ) 230 { 231 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT; 232 bMustBePositiveWholeNumbered = sal_True; 233 nIndex++; 234 } 235 else if ( rParaString[ nIndex ] == (sal_Unicode)'?' ) 236 { 237 nIndex++; 238 bNumberRequired = sal_False; 239 rtl::OUString aEquationName; 240 bValid = GetEquationName( rParaString, nIndex, aEquationName ); 241 if ( bValid ) 242 { 243 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION; 244 rParameter.Value <<= aEquationName; 245 nIndex += aEquationName.getLength(); 246 } 247 } 248 else if ( rParaString[ nIndex ] > (sal_Unicode)'9' ) 249 { 250 bNumberRequired = sal_False; 251 if ( rParaString.matchIgnoreAsciiCaseAsciiL( "left", 4, nIndex ) ) 252 { 253 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT; 254 nIndex += 4; 255 } 256 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "top", 3, nIndex ) ) 257 { 258 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP; 259 nIndex += 3; 260 } 261 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "right", 5, nIndex ) ) 262 { 263 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT; 264 nIndex += 5; 265 } 266 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "bottom", 6, nIndex ) ) 267 { 268 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM; 269 nIndex += 6; 270 } 271 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "xstretch", 8, nIndex ) ) 272 { 273 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::XSTRETCH; 274 nIndex += 8; 275 } 276 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "ystretch", 8, nIndex ) ) 277 { 278 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::YSTRETCH; 279 nIndex += 8; 280 } 281 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "hasstroke", 9, nIndex ) ) 282 { 283 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HASSTROKE; 284 nIndex += 9; 285 } 286 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "hasfill", 7, nIndex ) ) 287 { 288 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HASFILL; 289 nIndex += 7; 290 } 291 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "width", 5, nIndex ) ) 292 { 293 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::WIDTH; 294 nIndex += 5; 295 } 296 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "height", 6, nIndex ) ) 297 { 298 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::HEIGHT; 299 nIndex += 6; 300 } 301 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "logwidth", 8, nIndex ) ) 302 { 303 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGWIDTH; 304 nIndex += 8; 305 } 306 else if ( rParaString.matchIgnoreAsciiCaseAsciiL( "logheight", 9, nIndex ) ) 307 { 308 rParameter.Type = com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT; 309 nIndex += 9; 310 } 311 else 312 bValid = sal_False; 313 } 314 if ( bValid ) 315 { 316 if ( bNumberRequired ) 317 { 318 sal_Int32 nStartIndex = nIndex; 319 320 sal_Bool bM = sal_False; // set if the value is negative 321 sal_Bool bE = sal_False; // set if a double is including a "E" statement 322 sal_Bool bEM = sal_False; // set if a double is including a "E-"statement 323 sal_Bool bDot = sal_False; // set if there is a dot included 324 sal_Bool bEnd = sal_False; // set for each value that can not be part of a double/integer 325 326 while( ( nIndex < rParaString.getLength() ) && bValid ) 327 { 328 switch( rParaString[ nIndex ] ) 329 { 330 case '.' : 331 { 332 if ( bMustBePositiveWholeNumbered ) 333 bValid = sal_False; 334 else 335 { 336 if ( bDot ) 337 bValid = sal_False; 338 else 339 bDot = sal_True; 340 } 341 } 342 break; 343 case '-' : 344 { 345 if ( bMustBePositiveWholeNumbered ) 346 bValid = sal_False; 347 else 348 { 349 if ( nStartIndex == nIndex ) 350 bM = sal_True; 351 else if ( bE ) 352 bEM = sal_True; 353 else 354 bValid = sal_False; 355 } 356 } 357 break; 358 359 case 'e' : 360 case 'E' : 361 { 362 if ( bMustBePositiveWholeNumbered ) 363 bEnd = sal_True; 364 else 365 { 366 if ( !bE ) 367 bE = sal_True; 368 else 369 bEnd = sal_True; 370 } 371 } 372 break; 373 case '0' : 374 case '1' : 375 case '2' : 376 case '3' : 377 case '4' : 378 case '5' : 379 case '6' : 380 case '7' : 381 case '8' : 382 case '9' : 383 break; 384 default: 385 bEnd = sal_True; 386 } 387 if ( !bEnd ) 388 nIndex++; 389 else 390 break; 391 } 392 if ( nIndex == nStartIndex ) 393 bValid = sal_False; 394 if ( bValid ) 395 { 396 rtl::OUString aNumber( rParaString.copy( nStartIndex, nIndex - nStartIndex ) ); 397 if ( bE || bDot ) 398 { 399 double fAttrDouble; 400 if ( SvXMLUnitConverter::convertDouble( fAttrDouble, aNumber ) ) 401 rParameter.Value <<= fAttrDouble; 402 else 403 bValid = sal_False; 404 } 405 else 406 { 407 sal_Int32 nValue; 408 if ( SvXMLUnitConverter::convertNumber( nValue, aNumber ) ) 409 rParameter.Value <<= nValue; 410 else 411 bValid = sal_False; 412 } 413 } 414 } 415 } 416 if ( bValid ) 417 { // skipping white spaces 418 while( ( nIndex < rParaString.getLength() ) && rParaString[ nIndex ] == (sal_Unicode)' ' ) 419 nIndex++; 420 } 421 return bValid; 422 } 423 424 void GetPosition3D( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:extrusion-viewpoint 425 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp, 426 SvXMLUnitConverter& rUnitConverter ) 427 { 428 drawing::Position3D aPosition3D; 429 if ( rUnitConverter.convertPosition3D( aPosition3D, rValue ) ) 430 { 431 beans::PropertyValue aProp; 432 aProp.Name = EASGet( eDestProp ); 433 aProp.Value <<= aPosition3D; 434 rDest.push_back( aProp ); 435 } 436 } 437 438 void GetDoubleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-point-leaving-directions 439 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 440 { 441 std::vector< double > vDirection; 442 sal_Int32 nIndex = 0; 443 do 444 { 445 double fAttrDouble; 446 rtl::OUString aToken( rValue.getToken( 0, ',', nIndex ) ); 447 if ( !SvXMLUnitConverter::convertDouble( fAttrDouble, aToken ) ) 448 break; 449 else 450 vDirection.push_back( fAttrDouble ); 451 } 452 while ( nIndex >= 0 ); 453 454 if ( !vDirection.empty() ) 455 { 456 uno::Sequence< double > aDirectionsSeq( vDirection.size() ); 457 std::vector< double >::const_iterator aIter = vDirection.begin(); 458 std::vector< double >::const_iterator aEnd = vDirection.end(); 459 double* pValues = aDirectionsSeq.getArray(); 460 461 while ( aIter != aEnd ) 462 *pValues++ = *aIter++; 463 464 beans::PropertyValue aProp; 465 aProp.Name = EASGet( eDestProp ); 466 aProp.Value <<= aDirectionsSeq; 467 rDest.push_back( aProp ); 468 } 469 } 470 471 void GetEnhancedParameter( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position 472 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 473 { 474 sal_Int32 nIndex = 0; 475 com::sun::star::drawing::EnhancedCustomShapeParameter aParameter; 476 if ( GetNextParameter( aParameter, nIndex, rValue ) ) 477 { 478 beans::PropertyValue aProp; 479 aProp.Name = EASGet( eDestProp ); 480 aProp.Value <<= aParameter; 481 rDest.push_back( aProp ); 482 } 483 } 484 485 void GetEnhancedParameterPair( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position 486 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 487 { 488 sal_Int32 nIndex = 0; 489 com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair; 490 if ( GetNextParameter( aParameterPair.First, nIndex, rValue ) 491 && GetNextParameter( aParameterPair.Second, nIndex, rValue ) ) 492 { 493 beans::PropertyValue aProp; 494 aProp.Name = EASGet( eDestProp ); 495 aProp.Value <<= aParameterPair; 496 rDest.push_back( aProp ); 497 } 498 } 499 500 sal_Int32 GetEnhancedParameterPairSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-points 501 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 502 { 503 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vParameter; 504 com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameter; 505 506 sal_Int32 nIndex = 0; 507 while ( GetNextParameter( aParameter.First, nIndex, rValue ) 508 && GetNextParameter( aParameter.Second, nIndex, rValue ) ) 509 { 510 vParameter.push_back( aParameter ); 511 } 512 if ( !vParameter.empty() ) 513 { 514 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aParameterSeq( vParameter.size() ); 515 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aIter = vParameter.begin(); 516 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aEnd = vParameter.end(); 517 com::sun::star::drawing::EnhancedCustomShapeParameterPair* pValues = aParameterSeq.getArray(); 518 519 while ( aIter != aEnd ) 520 *pValues++ = *aIter++; 521 522 beans::PropertyValue aProp; 523 aProp.Name = EASGet( eDestProp ); 524 aProp.Value <<= aParameterSeq; 525 rDest.push_back( aProp ); 526 } 527 return vParameter.size(); 528 } 529 530 void GetEnhancedRectangleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:text-areas 531 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 532 { 533 std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame > vTextFrame; 534 com::sun::star::drawing::EnhancedCustomShapeTextFrame aParameter; 535 536 sal_Int32 nIndex = 0; 537 538 while ( GetNextParameter( aParameter.TopLeft.First, nIndex, rValue ) 539 && GetNextParameter( aParameter.TopLeft.Second, nIndex, rValue ) 540 && GetNextParameter( aParameter.BottomRight.First, nIndex, rValue ) 541 && GetNextParameter( aParameter.BottomRight.Second, nIndex, rValue ) ) 542 { 543 vTextFrame.push_back( aParameter ); 544 } 545 if ( !vTextFrame.empty() ) 546 { 547 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrameSeq( vTextFrame.size() ); 548 std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aIter = vTextFrame.begin(); 549 std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aEnd = vTextFrame.end(); 550 com::sun::star::drawing::EnhancedCustomShapeTextFrame* pValues = aTextFrameSeq.getArray(); 551 552 while ( aIter != aEnd ) 553 *pValues++ = *aIter++; 554 555 beans::PropertyValue aProp; 556 aProp.Name = EASGet( eDestProp ); 557 aProp.Value <<= aTextFrameSeq; 558 rDest.push_back( aProp ); 559 } 560 } 561 562 void GetEnhancedPath( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:enhanced-path 563 const rtl::OUString& rValue ) 564 { 565 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vCoordinates; 566 std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment > vSegments; 567 568 sal_Int32 nIndex = 0; 569 sal_Int32 nParameterCount = 0; 570 571 sal_Int32 nParametersNeeded = 1; 572 sal_Int16 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO; 573 574 sal_Bool bValid = sal_True; 575 576 while( bValid && ( nIndex < rValue.getLength() ) ) 577 { 578 switch( rValue[ nIndex ] ) 579 { 580 case 'M' : 581 { 582 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO; 583 nParametersNeeded = 1; 584 nIndex++; 585 } 586 break; 587 case 'L' : 588 { 589 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO; 590 nParametersNeeded = 1; 591 nIndex++; 592 } 593 break; 594 case 'C' : 595 { 596 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO; 597 nParametersNeeded = 3; 598 nIndex++; 599 } 600 break; 601 case 'Z' : 602 { 603 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; 604 nParametersNeeded = 0; 605 nIndex++; 606 } 607 break; 608 case 'N' : 609 { 610 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH; 611 nParametersNeeded = 0; 612 nIndex++; 613 } 614 break; 615 case 'F' : 616 { 617 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL; 618 nParametersNeeded = 0; 619 nIndex++; 620 } 621 break; 622 case 'S' : 623 { 624 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE; 625 nParametersNeeded = 0; 626 nIndex++; 627 } 628 break; 629 case 'T' : 630 { 631 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO; 632 nParametersNeeded = 3; 633 nIndex++; 634 } 635 break; 636 case 'U' : 637 { 638 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE; 639 nParametersNeeded = 3; 640 nIndex++; 641 } 642 break; 643 case 'A' : 644 { 645 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO; 646 nParametersNeeded = 4; 647 nIndex++; 648 } 649 break; 650 case 'B' : 651 { 652 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC; 653 nParametersNeeded = 4; 654 nIndex++; 655 } 656 break; 657 case 'W' : 658 { 659 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO; 660 nParametersNeeded = 4; 661 nIndex++; 662 } 663 break; 664 case 'V' : 665 { 666 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC; 667 nParametersNeeded = 4; 668 nIndex++; 669 } 670 break; 671 case 'X' : 672 { 673 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX; 674 nParametersNeeded = 1; 675 nIndex++; 676 } 677 break; 678 case 'Y' : 679 { 680 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY; 681 nParametersNeeded = 1; 682 nIndex++; 683 } 684 break; 685 case 'Q' : 686 { 687 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO; 688 nParametersNeeded = 2; 689 nIndex++; 690 } 691 break; 692 case ' ' : 693 { 694 nIndex++; 695 } 696 break; 697 698 case '$' : 699 case '?' : 700 case '0' : 701 case '1' : 702 case '2' : 703 case '3' : 704 case '4' : 705 case '5' : 706 case '6' : 707 case '7' : 708 case '8' : 709 case '9' : 710 case '.' : 711 case '-' : 712 { 713 com::sun::star::drawing::EnhancedCustomShapeParameterPair aPair; 714 if ( GetNextParameter( aPair.First, nIndex, rValue ) && 715 GetNextParameter( aPair.Second, nIndex, rValue ) ) 716 { 717 vCoordinates.push_back( aPair ); 718 nParameterCount++; 719 } 720 else 721 bValid = sal_False; 722 } 723 break; 724 default: 725 nIndex++; 726 break; 727 } 728 if ( !nParameterCount && !nParametersNeeded ) 729 { 730 com::sun::star::drawing::EnhancedCustomShapeSegment aSegment; 731 aSegment.Command = nLatestSegmentCommand; 732 aSegment.Count = 0; 733 vSegments.push_back( aSegment ); 734 nParametersNeeded = 0x7fffffff; 735 } 736 else if ( nParameterCount >= nParametersNeeded ) 737 { 738 // check if the last command is identical, 739 // if so, we just need to increment the count 740 if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) ) 741 vSegments[ vSegments.size() -1 ].Count++; 742 else 743 { 744 com::sun::star::drawing::EnhancedCustomShapeSegment aSegment; 745 aSegment.Command = nLatestSegmentCommand; 746 aSegment.Count = 1; 747 vSegments.push_back( aSegment ); 748 } 749 nParameterCount = 0; 750 } 751 } 752 // adding the Coordinates property 753 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > seqCoordinates( vCoordinates.size() ); 754 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesIter = vCoordinates.begin(); 755 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesEnd = vCoordinates.end(); 756 com::sun::star::drawing::EnhancedCustomShapeParameterPair* pCoordinateValues = seqCoordinates.getArray(); 757 758 while ( aCoordinatesIter != aCoordinatesEnd ) 759 *pCoordinateValues++ = *aCoordinatesIter++; 760 761 beans::PropertyValue aProp; 762 aProp.Name = EASGet( EAS_Coordinates ); 763 aProp.Value <<= seqCoordinates; 764 rDest.push_back( aProp ); 765 766 767 // adding the Segments property 768 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments( vSegments.size() ); 769 std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsIter = vSegments.begin(); 770 std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsEnd = vSegments.end(); 771 com::sun::star::drawing::EnhancedCustomShapeSegment* pSegmentValues = seqSegments.getArray(); 772 773 while ( aSegmentsIter != aSegmentsEnd ) 774 *pSegmentValues++ = *aSegmentsIter++; 775 776 aProp.Name = EASGet( EAS_Segments ); 777 aProp.Value <<= seqSegments; 778 rDest.push_back( aProp ); 779 } 780 781 void GetAdjustmentValues( std::vector< com::sun::star::beans::PropertyValue >& rDest, // draw:adjustments 782 const rtl::OUString& rValue ) 783 { 784 std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > vAdjustmentValue; 785 com::sun::star::drawing::EnhancedCustomShapeParameter aParameter; 786 sal_Int32 nIndex = 0; 787 while ( GetNextParameter( aParameter, nIndex, rValue ) ) 788 { 789 com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue aAdj; 790 if ( aParameter.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL ) 791 { 792 aAdj.Value <<= aParameter.Value; 793 aAdj.State = beans::PropertyState_DIRECT_VALUE; 794 } 795 else 796 aAdj.State = beans::PropertyState_DEFAULT_VALUE; // this should not be, but better than setting nothing 797 798 vAdjustmentValue.push_back( aAdj ); 799 } 800 801 sal_Int32 nAdjustmentValues = vAdjustmentValue.size(); 802 if ( nAdjustmentValues ) 803 { 804 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues( nAdjustmentValues ); 805 std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aIter = vAdjustmentValue.begin(); 806 std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aEnd = vAdjustmentValue.end(); 807 com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue* pValues = aAdjustmentValues.getArray(); 808 809 while ( aIter != aEnd ) 810 *pValues++ = *aIter++; 811 812 beans::PropertyValue aProp; 813 aProp.Name = EASGet( EAS_AdjustmentValues ); 814 aProp.Value <<= aAdjustmentValues; 815 rDest.push_back( aProp ); 816 } 817 } 818 819 void XMLEnhancedCustomShapeContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) 820 { 821 sal_Int16 nLength = xAttrList->getLength(); 822 if ( nLength ) 823 { 824 sal_Int32 nAttrNumber; 825 for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) 826 { 827 rtl::OUString aLocalName; 828 const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); 829 /* sven fixme, this must be checked! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); 830 831 switch( EASGet( aLocalName ) ) 832 { 833 case EAS_type : 834 GetString( mrCustomShapeGeometry, rValue, EAS_Type ); 835 break; 836 case EAS_mirror_horizontal : 837 GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredX ); 838 break; 839 case EAS_mirror_vertical : 840 GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredY ); 841 break; 842 case EAS_viewBox : 843 { 844 SdXMLImExViewBox aViewBox( rValue, GetImport().GetMM100UnitConverter() ); 845 awt::Rectangle aRect( aViewBox.GetX(), aViewBox.GetY(), aViewBox.GetWidth(), aViewBox.GetHeight() ); 846 beans::PropertyValue aProp; 847 aProp.Name = EASGet( EAS_ViewBox ); 848 aProp.Value <<= aRect; 849 mrCustomShapeGeometry.push_back( aProp ); 850 } 851 break; 852 case EAS_text_rotate_angle : 853 GetDouble( mrCustomShapeGeometry, rValue, EAS_TextRotateAngle ); 854 break; 855 case EAS_extrusion_allowed : 856 GetBool( maPath, rValue, EAS_ExtrusionAllowed ); 857 break; 858 case EAS_text_path_allowed : 859 GetBool( maPath, rValue, EAS_TextPathAllowed ); 860 break; 861 case EAS_concentric_gradient_fill_allowed : 862 GetBool( maPath, rValue, EAS_ConcentricGradientFillAllowed ); 863 break; 864 case EAS_extrusion : 865 GetBool( maExtrusion, rValue, EAS_Extrusion ); 866 break; 867 case EAS_extrusion_brightness : 868 GetDoublePercentage( maExtrusion, rValue, EAS_Brightness ); 869 break; 870 case EAS_extrusion_depth : 871 { 872 sal_Int32 nIndex = 0; 873 com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair; 874 com::sun::star::drawing::EnhancedCustomShapeParameter& rDepth = aParameterPair.First; 875 com::sun::star::drawing::EnhancedCustomShapeParameter& rFraction = aParameterPair.Second; 876 if ( GetNextParameter( rDepth, nIndex, rValue ) ) 877 { 878 // try to catch the unit for the depth 879 MapUnit eSrcUnit( SvXMLExportHelper::GetUnitFromString( rValue, MAP_100TH_MM ) ); 880 881 rtl::OUStringBuffer aUnitStr; 882 double fFactor = SvXMLExportHelper::GetConversionFactor( aUnitStr, MAP_100TH_MM, eSrcUnit ); 883 if ( ( fFactor != 1.0 ) && ( fFactor != 0.0 ) ) 884 { 885 double fDepth; 886 if ( rDepth.Value >>= fDepth ) 887 { 888 fDepth /= fFactor; 889 rDepth.Value <<= fDepth; 890 } 891 } 892 if ( rValue.matchIgnoreAsciiCase( rtl::OUString( aUnitStr ), nIndex ) ) 893 nIndex += aUnitStr.getLength(); 894 895 // skipping white spaces 896 while( ( nIndex < rValue.getLength() ) && rValue[ nIndex ] == (sal_Unicode)' ' ) 897 nIndex++; 898 899 if ( GetNextParameter( rFraction, nIndex, rValue ) ) 900 { 901 beans::PropertyValue aProp; 902 aProp.Name = EASGet( EAS_Depth ); 903 aProp.Value <<= aParameterPair; 904 maExtrusion.push_back( aProp ); 905 } 906 } 907 } 908 break; 909 case EAS_extrusion_diffusion : 910 GetDoublePercentage( maExtrusion, rValue, EAS_Diffusion ); 911 break; 912 case EAS_extrusion_number_of_line_segments : 913 GetInt32( maExtrusion, rValue, EAS_NumberOfLineSegments ); 914 break; 915 case EAS_extrusion_light_face : 916 GetBool( maExtrusion, rValue, EAS_LightFace ); 917 break; 918 case EAS_extrusion_first_light_harsh : 919 GetBool( maExtrusion, rValue, EAS_FirstLightHarsh ); 920 break; 921 case EAS_extrusion_second_light_harsh : 922 GetBool( maExtrusion, rValue, EAS_SecondLightHarsh ); 923 break; 924 case EAS_extrusion_first_light_level : 925 GetDoublePercentage( maExtrusion, rValue, EAS_FirstLightLevel ); 926 break; 927 case EAS_extrusion_second_light_level : 928 GetDoublePercentage( maExtrusion, rValue, EAS_SecondLightLevel ); 929 break; 930 case EAS_extrusion_first_light_direction : 931 GetB3DVector( maExtrusion, rValue, EAS_FirstLightDirection ); 932 break; 933 case EAS_extrusion_second_light_direction : 934 GetB3DVector( maExtrusion, rValue, EAS_SecondLightDirection ); 935 break; 936 case EAS_extrusion_metal : 937 GetBool( maExtrusion, rValue, EAS_Metal ); 938 break; 939 case EAS_shade_mode : 940 { 941 drawing::ShadeMode eShadeMode( drawing::ShadeMode_FLAT ); 942 if( IsXMLToken( rValue, XML_PHONG ) ) 943 eShadeMode = drawing::ShadeMode_PHONG; 944 else if ( IsXMLToken( rValue, XML_GOURAUD ) ) 945 eShadeMode = drawing::ShadeMode_SMOOTH; 946 else if ( IsXMLToken( rValue, XML_DRAFT ) ) 947 eShadeMode = drawing::ShadeMode_DRAFT; 948 949 beans::PropertyValue aProp; 950 aProp.Name = EASGet( EAS_ShadeMode ); 951 aProp.Value <<= eShadeMode; 952 maExtrusion.push_back( aProp ); 953 } 954 break; 955 case EAS_extrusion_rotation_angle : 956 GetEnhancedParameterPair( maExtrusion, rValue, EAS_RotateAngle ); 957 break; 958 case EAS_extrusion_rotation_center : 959 GetB3DVector( maExtrusion, rValue, EAS_RotationCenter ); 960 break; 961 case EAS_extrusion_shininess : 962 GetDoublePercentage( maExtrusion, rValue, EAS_Shininess ); 963 break; 964 case EAS_extrusion_skew : 965 GetEnhancedParameterPair( maExtrusion, rValue, EAS_Skew ); 966 break; 967 case EAS_extrusion_specularity : 968 GetDoublePercentage( maExtrusion, rValue, EAS_Specularity ); 969 break; 970 case EAS_projection : 971 { 972 drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PERSPECTIVE ); 973 if( IsXMLToken( rValue, XML_PARALLEL ) ) 974 eProjectionMode = drawing::ProjectionMode_PARALLEL; 975 976 beans::PropertyValue aProp; 977 aProp.Name = EASGet( EAS_ProjectionMode ); 978 aProp.Value <<= eProjectionMode; 979 maExtrusion.push_back( aProp ); 980 } 981 break; 982 case EAS_extrusion_viewpoint : 983 GetPosition3D( maExtrusion, rValue, EAS_ViewPoint, mrUnitConverter ); 984 break; 985 case EAS_extrusion_origin : 986 GetEnhancedParameterPair( maExtrusion, rValue, EAS_Origin ); 987 break; 988 case EAS_extrusion_color : 989 GetBool( maExtrusion, rValue, EAS_Color ); 990 break; 991 case EAS_enhanced_path : 992 GetEnhancedPath( maPath, rValue ); 993 break; 994 case EAS_path_stretchpoint_x : 995 { 996 if ( SvXMLUnitConverter::convertNumber( nAttrNumber, rValue ) ) 997 { 998 beans::PropertyValue aProp; 999 aProp.Name = EASGet( EAS_StretchX ); 1000 aProp.Value <<= nAttrNumber; 1001 maPath.push_back( aProp ); 1002 } 1003 } 1004 break; 1005 case EAS_path_stretchpoint_y : 1006 { 1007 if ( SvXMLUnitConverter::convertNumber( nAttrNumber, rValue ) ) 1008 { 1009 beans::PropertyValue aProp; 1010 aProp.Name = EASGet( EAS_StretchY ); 1011 aProp.Value <<= nAttrNumber; 1012 maPath.push_back( aProp ); 1013 } 1014 } 1015 break; 1016 case EAS_text_areas : 1017 GetEnhancedRectangleSequence( maPath, rValue, EAS_TextFrames ); 1018 break; 1019 case EAS_glue_points : 1020 { 1021 sal_Int32 i, nPairs = GetEnhancedParameterPairSequence( maPath, rValue, EAS_GluePoints ); 1022 GetImport().GetShapeImport()->moveGluePointMapping( mrxShape, nPairs ); 1023 for ( i = 0; i < nPairs; i++ ) 1024 GetImport().GetShapeImport()->addGluePointMapping( mrxShape, i + 4, i + 4 ); 1025 } 1026 break; 1027 case EAS_glue_point_type : 1028 GetEnum( maPath, rValue, EAS_GluePointType, *aXML_GluePointEnumMap ); 1029 break; 1030 case EAS_glue_point_leaving_directions : 1031 GetDoubleSequence( maPath, rValue, EAS_GluePointLeavingDirections ); 1032 break; 1033 case EAS_text_path : 1034 GetBool( maTextPath, rValue, EAS_TextPath ); 1035 break; 1036 case EAS_text_path_mode : 1037 { 1038 com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode( com::sun::star::drawing::EnhancedCustomShapeTextPathMode_NORMAL ); 1039 if( IsXMLToken( rValue, XML_PATH ) ) 1040 eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH; 1041 else if ( IsXMLToken( rValue, XML_SHAPE ) ) 1042 eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE; 1043 1044 beans::PropertyValue aProp; 1045 aProp.Name = EASGet( EAS_TextPathMode ); 1046 aProp.Value <<= eTextPathMode; 1047 maTextPath.push_back( aProp ); 1048 } 1049 break; 1050 case EAS_text_path_scale : 1051 { 1052 sal_Bool bScaleX = IsXMLToken( rValue, XML_SHAPE ); 1053 beans::PropertyValue aProp; 1054 aProp.Name = EASGet( EAS_ScaleX ); 1055 aProp.Value <<= bScaleX; 1056 maTextPath.push_back( aProp ); 1057 } 1058 break; 1059 case EAS_text_path_same_letter_heights : 1060 GetBool( maTextPath, rValue, EAS_SameLetterHeights ); 1061 break; 1062 case EAS_modifiers : 1063 GetAdjustmentValues( mrCustomShapeGeometry, rValue ); 1064 break; 1065 default: 1066 break; 1067 } 1068 } 1069 } 1070 } 1071 1072 void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, 1073 const std::vector< beans::PropertyValues >& rElement, 1074 const rtl::OUString& rElementName ) 1075 { 1076 if ( !rElement.empty() ) 1077 { 1078 uno::Sequence< beans::PropertyValues > aPropSeq( rElement.size() ); 1079 std::vector< beans::PropertyValues >::const_iterator aIter = rElement.begin(); 1080 std::vector< beans::PropertyValues >::const_iterator aEnd = rElement.end(); 1081 beans::PropertyValues* pValues = aPropSeq.getArray(); 1082 1083 while ( aIter != aEnd ) 1084 *pValues++ = *aIter++; 1085 1086 beans::PropertyValue aProp; 1087 aProp.Name = rElementName; 1088 aProp.Value <<= aPropSeq; 1089 rPropVec.push_back( aProp ); 1090 } 1091 } 1092 1093 void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, 1094 const std::vector< rtl::OUString >& rElement, 1095 const rtl::OUString& rElementName ) 1096 { 1097 if ( !rElement.empty() ) 1098 { 1099 uno::Sequence< rtl::OUString > aPropSeq( rElement.size() ); 1100 std::vector< rtl::OUString >::const_iterator aIter = rElement.begin(); 1101 std::vector< rtl::OUString >::const_iterator aEnd = rElement.end(); 1102 rtl::OUString* pValues = aPropSeq.getArray(); 1103 1104 while ( aIter != aEnd ) 1105 *pValues++ = *aIter++; 1106 1107 beans::PropertyValue aProp; 1108 aProp.Name = rElementName; 1109 aProp.Value <<= aPropSeq; 1110 rPropVec.push_back( aProp ); 1111 } 1112 } 1113 1114 void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, 1115 const std::vector< com::sun::star::beans::PropertyValue >& rElement, 1116 const rtl::OUString& rElementName ) 1117 { 1118 if ( !rElement.empty() ) 1119 { 1120 uno::Sequence< beans::PropertyValue > aPropSeq( rElement.size() ); 1121 std::vector< beans::PropertyValue >::const_iterator aIter = rElement.begin(); 1122 std::vector< beans::PropertyValue >::const_iterator aEnd = rElement.end(); 1123 beans::PropertyValue* pValues = aPropSeq.getArray(); 1124 1125 while ( aIter != aEnd ) 1126 *pValues++ = *aIter++; 1127 1128 beans::PropertyValue aProp; 1129 aProp.Name = rElementName; 1130 aProp.Value <<= aPropSeq; 1131 rPropVec.push_back( aProp ); 1132 } 1133 } 1134 1135 typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash, OUStringEqFunc> EquationHashMap; 1136 1137 /* if rPara.Type is from type EnhancedCustomShapeParameterType::EQUATION, the name of the equation 1138 will be converted from rtl::OUString to index */ 1139 void CheckAndResolveEquationParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rPara, EquationHashMap* pH ) 1140 { 1141 if ( rPara.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION ) 1142 { 1143 rtl::OUString aEquationName; 1144 if ( rPara.Value >>= aEquationName ) 1145 { 1146 sal_Int32 nIndex = 0; 1147 EquationHashMap::iterator aHashIter( pH->find( aEquationName ) ); 1148 if ( aHashIter != pH->end() ) 1149 nIndex = (*aHashIter).second; 1150 rPara.Value <<= nIndex; 1151 } 1152 } 1153 } 1154 1155 void XMLEnhancedCustomShapeContext::EndElement() 1156 { 1157 // resolve properties that are indexing a Equation 1158 if ( !maEquations.empty() ) 1159 { 1160 // creating hash map containing the name and index of each equation 1161 EquationHashMap* pH = new EquationHashMap; 1162 std::vector< rtl::OUString >::iterator aEquationNameIter = maEquationNames.begin(); 1163 std::vector< rtl::OUString >::iterator aEquationNameEnd = maEquationNames.end(); 1164 while( aEquationNameIter != aEquationNameEnd ) 1165 { 1166 (*pH)[ *aEquationNameIter ] = (sal_Int32)( aEquationNameIter - maEquationNames.begin() ); 1167 aEquationNameIter++; 1168 } 1169 1170 // resolve equation 1171 std::vector< rtl::OUString >::iterator aEquationIter = maEquations.begin(); 1172 std::vector< rtl::OUString >::iterator aEquationEnd = maEquations.end(); 1173 while( aEquationIter != aEquationEnd ) 1174 { 1175 sal_Int32 nIndexOf = 0; 1176 do 1177 { 1178 nIndexOf = aEquationIter->indexOf( '?', nIndexOf ); 1179 if ( nIndexOf != -1 ) 1180 { 1181 rtl::OUString aEquationName; 1182 if ( GetEquationName( *aEquationIter, nIndexOf + 1, aEquationName ) ) 1183 { 1184 // copying first characters inclusive '?' 1185 rtl::OUString aNew( aEquationIter->copy( 0, nIndexOf + 1 ) ); 1186 sal_Int32 nIndex = 0; 1187 EquationHashMap::iterator aHashIter( pH->find( aEquationName ) ); 1188 if ( aHashIter != pH->end() ) 1189 nIndex = (*aHashIter).second; 1190 aNew += rtl::OUString::valueOf( nIndex ); 1191 aNew += aEquationIter->copy( nIndexOf + aEquationName.getLength() + 1 ); 1192 *aEquationIter = aNew; 1193 } 1194 nIndexOf++; 1195 } 1196 } 1197 while( nIndexOf != -1 ); 1198 aEquationIter++; 1199 } 1200 1201 // Path 1202 sal_Int32 i; 1203 std::vector< beans::PropertyValue >::iterator aPathIter = maPath.begin(); 1204 std::vector< beans::PropertyValue >::iterator aPathEnd = maPath.end(); 1205 while ( aPathIter != aPathEnd ) 1206 { 1207 switch( EASGet( aPathIter->Name ) ) 1208 { 1209 case EAS_Coordinates : 1210 case EAS_GluePoints : 1211 { 1212 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >& rSeq = 1213 *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >*) 1214 aPathIter->Value.getValue()); 1215 for ( i = 0; i < rSeq.getLength(); i++ ) 1216 { 1217 CheckAndResolveEquationParameter( rSeq[ i ].First, pH ); 1218 CheckAndResolveEquationParameter( rSeq[ i ].Second, pH ); 1219 } 1220 } 1221 break; 1222 case EAS_TextFrames : 1223 { 1224 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >& rSeq = 1225 *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >*) 1226 aPathIter->Value.getValue()); 1227 for ( i = 0; i < rSeq.getLength(); i++ ) 1228 { 1229 CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.First, pH ); 1230 CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.Second, pH ); 1231 CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.First, pH ); 1232 CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.Second, pH ); 1233 } 1234 } 1235 break; 1236 default: 1237 break; 1238 } 1239 aPathIter++; 1240 } 1241 std::vector< beans::PropertyValues >::iterator aHandleIter = maHandles.begin(); 1242 std::vector< beans::PropertyValues >::iterator aHandleEnd = maHandles.end(); 1243 while ( aHandleIter != aHandleEnd ) 1244 { 1245 beans::PropertyValue* pValues = aHandleIter->getArray(); 1246 for ( i = 0; i < aHandleIter->getLength(); i++ ) 1247 { 1248 switch( EASGet( pValues->Name ) ) 1249 { 1250 case EAS_RangeYMinimum : 1251 case EAS_RangeYMaximum : 1252 case EAS_RangeXMinimum : 1253 case EAS_RangeXMaximum : 1254 case EAS_RadiusRangeMinimum : 1255 case EAS_RadiusRangeMaximum : 1256 { 1257 CheckAndResolveEquationParameter( *((com::sun::star::drawing::EnhancedCustomShapeParameter*) 1258 pValues->Value.getValue()), pH ); 1259 } 1260 break; 1261 1262 case EAS_Position : 1263 case EAS_Polar : 1264 { 1265 CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*) 1266 pValues->Value.getValue())).First, pH ); 1267 CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*) 1268 pValues->Value.getValue())).Second, pH ); 1269 } 1270 break; 1271 default: 1272 break; 1273 } 1274 pValues++; 1275 } 1276 aHandleIter++; 1277 } 1278 delete pH; 1279 } 1280 1281 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maExtrusion, EASGet( EAS_Extrusion ) ); 1282 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maPath, EASGet( EAS_Path ) ); 1283 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maTextPath, EASGet( EAS_TextPath ) ); 1284 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maEquations, EASGet( EAS_Equations ) ); 1285 if ( !maHandles.empty() ) 1286 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maHandles, EASGet( EAS_Handles ) ); 1287 } 1288 1289 SvXMLImportContext* XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt16 nPrefix,const rtl::OUString& rLocalName, 1290 const uno::Reference< xml::sax::XAttributeList> & xAttrList ) 1291 { 1292 EnhancedCustomShapeTokenEnum aTokenEnum = EASGet( rLocalName ); 1293 if ( aTokenEnum == EAS_equation ) 1294 { 1295 sal_Int16 nLength = xAttrList->getLength(); 1296 if ( nLength ) 1297 { 1298 rtl::OUString aFormula; 1299 rtl::OUString aFormulaName; 1300 for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) 1301 { 1302 rtl::OUString aLocalName; 1303 const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); 1304 /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); 1305 1306 switch( EASGet( aLocalName ) ) 1307 { 1308 case EAS_formula : 1309 aFormula = rValue; 1310 break; 1311 case EAS_name : 1312 aFormulaName = rValue; 1313 break; 1314 default: 1315 break; 1316 } 1317 } 1318 if ( aFormulaName.getLength() || aFormula.getLength() ) 1319 { 1320 maEquations.push_back( aFormula ); 1321 maEquationNames.push_back( aFormulaName ); 1322 } 1323 } 1324 } 1325 else if ( aTokenEnum == EAS_handle ) 1326 { 1327 std::vector< com::sun::star::beans::PropertyValue > aHandle; 1328 const sal_Int16 nLength = xAttrList->getLength(); 1329 for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) 1330 { 1331 rtl::OUString aLocalName; 1332 const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); 1333 /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); 1334 switch( EASGet( aLocalName ) ) 1335 { 1336 case EAS_handle_mirror_vertical : 1337 GetBool( aHandle, rValue, EAS_MirroredY ); 1338 break; 1339 case EAS_handle_mirror_horizontal : 1340 GetBool( aHandle, rValue, EAS_MirroredX ); 1341 break; 1342 case EAS_handle_switched : 1343 GetBool( aHandle, rValue, EAS_Switched ); 1344 break; 1345 case EAS_handle_position : 1346 GetEnhancedParameterPair( aHandle, rValue, EAS_Position ); 1347 break; 1348 case EAS_handle_range_x_minimum : 1349 GetEnhancedParameter( aHandle, rValue, EAS_RangeXMinimum ); 1350 break; 1351 case EAS_handle_range_x_maximum : 1352 GetEnhancedParameter( aHandle, rValue, EAS_RangeXMaximum ); 1353 break; 1354 case EAS_handle_range_y_minimum : 1355 GetEnhancedParameter( aHandle, rValue, EAS_RangeYMinimum ); 1356 break; 1357 case EAS_handle_range_y_maximum : 1358 GetEnhancedParameter( aHandle, rValue, EAS_RangeYMaximum ); 1359 break; 1360 case EAS_handle_polar : 1361 GetEnhancedParameterPair( aHandle, rValue, EAS_Polar ); 1362 break; 1363 case EAS_handle_radius_range_minimum : 1364 GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMinimum ); 1365 break; 1366 case EAS_handle_radius_range_maximum : 1367 GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMaximum ); 1368 break; 1369 default: 1370 break; 1371 } 1372 } 1373 beans::PropertyValues aPropSeq( aHandle.size() ); 1374 std::vector< beans::PropertyValue >::const_iterator aIter = aHandle.begin(); 1375 std::vector< beans::PropertyValue >::const_iterator aEnd = aHandle.end(); 1376 beans::PropertyValue* pValues = aPropSeq.getArray(); 1377 1378 while ( aIter != aEnd ) 1379 *pValues++ = *aIter++; 1380 1381 maHandles.push_back( aPropSeq ); 1382 } 1383 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList ); 1384 } 1385