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