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 { // skipping white spaces 414 while( ( nIndex < rParaString.getLength() ) && rParaString[ nIndex ] == (sal_Unicode)' ' ) 415 nIndex++; 416 } 417 return bValid; 418 } 419 420 void GetPosition3D( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:extrusion-viewpoint 421 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp, 422 SvXMLUnitConverter& rUnitConverter ) 423 { 424 drawing::Position3D aPosition3D; 425 if ( rUnitConverter.convertPosition3D( aPosition3D, rValue ) ) 426 { 427 beans::PropertyValue aProp; 428 aProp.Name = EASGet( eDestProp ); 429 aProp.Value <<= aPosition3D; 430 rDest.push_back( aProp ); 431 } 432 } 433 434 void GetDoubleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-point-leaving-directions 435 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 436 { 437 std::vector< double > vDirection; 438 sal_Int32 nIndex = 0; 439 do 440 { 441 double fAttrDouble; 442 rtl::OUString aToken( rValue.getToken( 0, ',', nIndex ) ); 443 if ( !SvXMLUnitConverter::convertDouble( fAttrDouble, aToken ) ) 444 break; 445 else 446 vDirection.push_back( fAttrDouble ); 447 } 448 while ( nIndex >= 0 ); 449 450 if ( !vDirection.empty() ) 451 { 452 uno::Sequence< double > aDirectionsSeq( vDirection.size() ); 453 std::vector< double >::const_iterator aIter = vDirection.begin(); 454 std::vector< double >::const_iterator aEnd = vDirection.end(); 455 double* pValues = aDirectionsSeq.getArray(); 456 457 while ( aIter != aEnd ) 458 *pValues++ = *aIter++; 459 460 beans::PropertyValue aProp; 461 aProp.Name = EASGet( eDestProp ); 462 aProp.Value <<= aDirectionsSeq; 463 rDest.push_back( aProp ); 464 } 465 } 466 467 void GetEnhancedParameter( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position 468 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 469 { 470 sal_Int32 nIndex = 0; 471 com::sun::star::drawing::EnhancedCustomShapeParameter aParameter; 472 if ( GetNextParameter( aParameter, nIndex, rValue ) ) 473 { 474 beans::PropertyValue aProp; 475 aProp.Name = EASGet( eDestProp ); 476 aProp.Value <<= aParameter; 477 rDest.push_back( aProp ); 478 } 479 } 480 481 void GetEnhancedParameterPair( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:handle-position 482 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 483 { 484 sal_Int32 nIndex = 0; 485 com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair; 486 if ( GetNextParameter( aParameterPair.First, nIndex, rValue ) 487 && GetNextParameter( aParameterPair.Second, nIndex, rValue ) ) 488 { 489 beans::PropertyValue aProp; 490 aProp.Name = EASGet( eDestProp ); 491 aProp.Value <<= aParameterPair; 492 rDest.push_back( aProp ); 493 } 494 } 495 496 sal_Int32 GetEnhancedParameterPairSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:glue-points 497 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 498 { 499 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vParameter; 500 com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameter; 501 502 sal_Int32 nIndex = 0; 503 while ( GetNextParameter( aParameter.First, nIndex, rValue ) 504 && GetNextParameter( aParameter.Second, nIndex, rValue ) ) 505 { 506 vParameter.push_back( aParameter ); 507 } 508 if ( !vParameter.empty() ) 509 { 510 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aParameterSeq( vParameter.size() ); 511 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aIter = vParameter.begin(); 512 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aEnd = vParameter.end(); 513 com::sun::star::drawing::EnhancedCustomShapeParameterPair* pValues = aParameterSeq.getArray(); 514 515 while ( aIter != aEnd ) 516 *pValues++ = *aIter++; 517 518 beans::PropertyValue aProp; 519 aProp.Name = EASGet( eDestProp ); 520 aProp.Value <<= aParameterSeq; 521 rDest.push_back( aProp ); 522 } 523 return vParameter.size(); 524 } 525 526 void GetEnhancedRectangleSequence( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:text-areas 527 const rtl::OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp ) 528 { 529 std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame > vTextFrame; 530 com::sun::star::drawing::EnhancedCustomShapeTextFrame aParameter; 531 532 sal_Int32 nIndex = 0; 533 534 while ( GetNextParameter( aParameter.TopLeft.First, nIndex, rValue ) 535 && GetNextParameter( aParameter.TopLeft.Second, nIndex, rValue ) 536 && GetNextParameter( aParameter.BottomRight.First, nIndex, rValue ) 537 && GetNextParameter( aParameter.BottomRight.Second, nIndex, rValue ) ) 538 { 539 vTextFrame.push_back( aParameter ); 540 } 541 if ( !vTextFrame.empty() ) 542 { 543 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrameSeq( vTextFrame.size() ); 544 std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aIter = vTextFrame.begin(); 545 std::vector< com::sun::star::drawing::EnhancedCustomShapeTextFrame >::const_iterator aEnd = vTextFrame.end(); 546 com::sun::star::drawing::EnhancedCustomShapeTextFrame* pValues = aTextFrameSeq.getArray(); 547 548 while ( aIter != aEnd ) 549 *pValues++ = *aIter++; 550 551 beans::PropertyValue aProp; 552 aProp.Name = EASGet( eDestProp ); 553 aProp.Value <<= aTextFrameSeq; 554 rDest.push_back( aProp ); 555 } 556 } 557 558 void GetEnhancedPath( std::vector< com::sun::star::beans::PropertyValue >& rDest, // e.g. draw:enhanced-path 559 const rtl::OUString& rValue ) 560 { 561 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > vCoordinates; 562 std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment > vSegments; 563 564 sal_Int32 nIndex = 0; 565 sal_Int32 nParameterCount = 0; 566 567 sal_Int32 nParametersNeeded = 1; 568 sal_Int16 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO; 569 570 sal_Bool bValid = sal_True; 571 572 while( bValid && ( nIndex < rValue.getLength() ) ) 573 { 574 switch( rValue[ nIndex ] ) 575 { 576 case 'M' : 577 { 578 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO; 579 nParametersNeeded = 1; 580 nIndex++; 581 } 582 break; 583 case 'L' : 584 { 585 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO; 586 nParametersNeeded = 1; 587 nIndex++; 588 } 589 break; 590 case 'C' : 591 { 592 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO; 593 nParametersNeeded = 3; 594 nIndex++; 595 } 596 break; 597 case 'Z' : 598 { 599 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; 600 nParametersNeeded = 0; 601 nIndex++; 602 } 603 break; 604 case 'N' : 605 { 606 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH; 607 nParametersNeeded = 0; 608 nIndex++; 609 } 610 break; 611 case 'F' : 612 { 613 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL; 614 nParametersNeeded = 0; 615 nIndex++; 616 } 617 break; 618 case 'S' : 619 { 620 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE; 621 nParametersNeeded = 0; 622 nIndex++; 623 } 624 break; 625 case 'T' : 626 { 627 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO; 628 nParametersNeeded = 3; 629 nIndex++; 630 } 631 break; 632 case 'U' : 633 { 634 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE; 635 nParametersNeeded = 3; 636 nIndex++; 637 } 638 break; 639 case 'A' : 640 { 641 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO; 642 nParametersNeeded = 4; 643 nIndex++; 644 } 645 break; 646 case 'B' : 647 { 648 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC; 649 nParametersNeeded = 4; 650 nIndex++; 651 } 652 break; 653 case 'W' : 654 { 655 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO; 656 nParametersNeeded = 4; 657 nIndex++; 658 } 659 break; 660 case 'V' : 661 { 662 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC; 663 nParametersNeeded = 4; 664 nIndex++; 665 } 666 break; 667 case 'X' : 668 { 669 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX; 670 nParametersNeeded = 1; 671 nIndex++; 672 } 673 break; 674 case 'Y' : 675 { 676 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY; 677 nParametersNeeded = 1; 678 nIndex++; 679 } 680 break; 681 case 'Q' : 682 { 683 nLatestSegmentCommand = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO; 684 nParametersNeeded = 2; 685 nIndex++; 686 } 687 break; 688 case ' ' : 689 { 690 nIndex++; 691 } 692 break; 693 694 case '$' : 695 case '?' : 696 case '0' : 697 case '1' : 698 case '2' : 699 case '3' : 700 case '4' : 701 case '5' : 702 case '6' : 703 case '7' : 704 case '8' : 705 case '9' : 706 case '.' : 707 case '-' : 708 { 709 com::sun::star::drawing::EnhancedCustomShapeParameterPair aPair; 710 if ( GetNextParameter( aPair.First, nIndex, rValue ) && 711 GetNextParameter( aPair.Second, nIndex, rValue ) ) 712 { 713 vCoordinates.push_back( aPair ); 714 nParameterCount++; 715 } 716 else 717 bValid = sal_False; 718 } 719 break; 720 default: 721 nIndex++; 722 break; 723 } 724 if ( !nParameterCount && !nParametersNeeded ) 725 { 726 com::sun::star::drawing::EnhancedCustomShapeSegment aSegment; 727 aSegment.Command = nLatestSegmentCommand; 728 aSegment.Count = 0; 729 vSegments.push_back( aSegment ); 730 nParametersNeeded = 0x7fffffff; 731 } 732 else if ( nParameterCount >= nParametersNeeded ) 733 { 734 // check if the last command is identical, 735 // if so, we just need to increment the count 736 if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) ) 737 vSegments[ vSegments.size() -1 ].Count++; 738 else 739 { 740 com::sun::star::drawing::EnhancedCustomShapeSegment aSegment; 741 aSegment.Command = nLatestSegmentCommand; 742 aSegment.Count = 1; 743 vSegments.push_back( aSegment ); 744 } 745 nParameterCount = 0; 746 } 747 } 748 // adding the Coordinates property 749 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > seqCoordinates( vCoordinates.size() ); 750 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesIter = vCoordinates.begin(); 751 std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair >::const_iterator aCoordinatesEnd = vCoordinates.end(); 752 com::sun::star::drawing::EnhancedCustomShapeParameterPair* pCoordinateValues = seqCoordinates.getArray(); 753 754 while ( aCoordinatesIter != aCoordinatesEnd ) 755 *pCoordinateValues++ = *aCoordinatesIter++; 756 757 beans::PropertyValue aProp; 758 aProp.Name = EASGet( EAS_Coordinates ); 759 aProp.Value <<= seqCoordinates; 760 rDest.push_back( aProp ); 761 762 763 // adding the Segments property 764 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments( vSegments.size() ); 765 std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsIter = vSegments.begin(); 766 std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >::const_iterator aSegmentsEnd = vSegments.end(); 767 com::sun::star::drawing::EnhancedCustomShapeSegment* pSegmentValues = seqSegments.getArray(); 768 769 while ( aSegmentsIter != aSegmentsEnd ) 770 *pSegmentValues++ = *aSegmentsIter++; 771 772 aProp.Name = EASGet( EAS_Segments ); 773 aProp.Value <<= seqSegments; 774 rDest.push_back( aProp ); 775 } 776 777 void GetAdjustmentValues( std::vector< com::sun::star::beans::PropertyValue >& rDest, // draw:adjustments 778 const rtl::OUString& rValue ) 779 { 780 std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > vAdjustmentValue; 781 com::sun::star::drawing::EnhancedCustomShapeParameter aParameter; 782 sal_Int32 nIndex = 0; 783 while ( GetNextParameter( aParameter, nIndex, rValue ) ) 784 { 785 com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue aAdj; 786 if ( aParameter.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL ) 787 { 788 aAdj.Value <<= aParameter.Value; 789 aAdj.State = beans::PropertyState_DIRECT_VALUE; 790 } 791 else 792 aAdj.State = beans::PropertyState_DEFAULT_VALUE; // this should not be, but better than setting nothing 793 794 vAdjustmentValue.push_back( aAdj ); 795 } 796 797 sal_Int32 nAdjustmentValues = vAdjustmentValue.size(); 798 if ( nAdjustmentValues ) 799 { 800 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues( nAdjustmentValues ); 801 std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aIter = vAdjustmentValue.begin(); 802 std::vector< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue >::const_iterator aEnd = vAdjustmentValue.end(); 803 com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue* pValues = aAdjustmentValues.getArray(); 804 805 while ( aIter != aEnd ) 806 *pValues++ = *aIter++; 807 808 beans::PropertyValue aProp; 809 aProp.Name = EASGet( EAS_AdjustmentValues ); 810 aProp.Value <<= aAdjustmentValues; 811 rDest.push_back( aProp ); 812 } 813 } 814 815 void XMLEnhancedCustomShapeContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) 816 { 817 sal_Int16 nLength = xAttrList->getLength(); 818 if ( nLength ) 819 { 820 sal_Int32 nAttrNumber; 821 for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) 822 { 823 rtl::OUString aLocalName; 824 const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); 825 /* sven fixme, this must be checked! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); 826 827 switch( EASGet( aLocalName ) ) 828 { 829 case EAS_type : 830 GetString( mrCustomShapeGeometry, rValue, EAS_Type ); 831 break; 832 case EAS_mirror_horizontal : 833 GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredX ); 834 break; 835 case EAS_mirror_vertical : 836 GetBool( mrCustomShapeGeometry, rValue, EAS_MirroredY ); 837 break; 838 case EAS_viewBox : 839 { 840 SdXMLImExViewBox aViewBox( rValue, GetImport().GetMM100UnitConverter() ); 841 awt::Rectangle aRect( aViewBox.GetX(), aViewBox.GetY(), aViewBox.GetWidth(), aViewBox.GetHeight() ); 842 beans::PropertyValue aProp; 843 aProp.Name = EASGet( EAS_ViewBox ); 844 aProp.Value <<= aRect; 845 mrCustomShapeGeometry.push_back( aProp ); 846 } 847 break; 848 case EAS_text_rotate_angle : 849 GetDouble( mrCustomShapeGeometry, rValue, EAS_TextRotateAngle ); 850 break; 851 case EAS_extrusion_allowed : 852 GetBool( maPath, rValue, EAS_ExtrusionAllowed ); 853 break; 854 case EAS_text_path_allowed : 855 GetBool( maPath, rValue, EAS_TextPathAllowed ); 856 break; 857 case EAS_concentric_gradient_fill_allowed : 858 GetBool( maPath, rValue, EAS_ConcentricGradientFillAllowed ); 859 break; 860 case EAS_extrusion : 861 GetBool( maExtrusion, rValue, EAS_Extrusion ); 862 break; 863 case EAS_extrusion_brightness : 864 GetDoublePercentage( maExtrusion, rValue, EAS_Brightness ); 865 break; 866 case EAS_extrusion_depth : 867 { 868 sal_Int32 nIndex = 0; 869 com::sun::star::drawing::EnhancedCustomShapeParameterPair aParameterPair; 870 com::sun::star::drawing::EnhancedCustomShapeParameter& rDepth = aParameterPair.First; 871 com::sun::star::drawing::EnhancedCustomShapeParameter& rFraction = aParameterPair.Second; 872 if ( GetNextParameter( rDepth, nIndex, rValue ) ) 873 { 874 // try to catch the unit for the depth 875 MapUnit eSrcUnit( SvXMLExportHelper::GetUnitFromString( rValue, MAP_100TH_MM ) ); 876 877 rtl::OUStringBuffer aUnitStr; 878 double fFactor = SvXMLExportHelper::GetConversionFactor( aUnitStr, MAP_100TH_MM, eSrcUnit ); 879 if ( ( fFactor != 1.0 ) && ( fFactor != 0.0 ) ) 880 { 881 double fDepth; 882 if ( rDepth.Value >>= fDepth ) 883 { 884 fDepth /= fFactor; 885 rDepth.Value <<= fDepth; 886 } 887 } 888 if ( rValue.matchIgnoreAsciiCase( rtl::OUString( aUnitStr ), nIndex ) ) 889 nIndex += aUnitStr.getLength(); 890 891 // skipping white spaces 892 while( ( nIndex < rValue.getLength() ) && rValue[ nIndex ] == (sal_Unicode)' ' ) 893 nIndex++; 894 895 if ( GetNextParameter( rFraction, nIndex, rValue ) ) 896 { 897 beans::PropertyValue aProp; 898 aProp.Name = EASGet( EAS_Depth ); 899 aProp.Value <<= aParameterPair; 900 maExtrusion.push_back( aProp ); 901 } 902 } 903 } 904 break; 905 case EAS_extrusion_diffusion : 906 GetDoublePercentage( maExtrusion, rValue, EAS_Diffusion ); 907 break; 908 case EAS_extrusion_number_of_line_segments : 909 GetInt32( maExtrusion, rValue, EAS_NumberOfLineSegments ); 910 break; 911 case EAS_extrusion_light_face : 912 GetBool( maExtrusion, rValue, EAS_LightFace ); 913 break; 914 case EAS_extrusion_first_light_harsh : 915 GetBool( maExtrusion, rValue, EAS_FirstLightHarsh ); 916 break; 917 case EAS_extrusion_second_light_harsh : 918 GetBool( maExtrusion, rValue, EAS_SecondLightHarsh ); 919 break; 920 case EAS_extrusion_first_light_level : 921 GetDoublePercentage( maExtrusion, rValue, EAS_FirstLightLevel ); 922 break; 923 case EAS_extrusion_second_light_level : 924 GetDoublePercentage( maExtrusion, rValue, EAS_SecondLightLevel ); 925 break; 926 case EAS_extrusion_first_light_direction : 927 GetB3DVector( maExtrusion, rValue, EAS_FirstLightDirection ); 928 break; 929 case EAS_extrusion_second_light_direction : 930 GetB3DVector( maExtrusion, rValue, EAS_SecondLightDirection ); 931 break; 932 case EAS_extrusion_metal : 933 GetBool( maExtrusion, rValue, EAS_Metal ); 934 break; 935 case EAS_shade_mode : 936 { 937 drawing::ShadeMode eShadeMode( drawing::ShadeMode_FLAT ); 938 if( IsXMLToken( rValue, XML_PHONG ) ) 939 eShadeMode = drawing::ShadeMode_PHONG; 940 else if ( IsXMLToken( rValue, XML_GOURAUD ) ) 941 eShadeMode = drawing::ShadeMode_SMOOTH; 942 else if ( IsXMLToken( rValue, XML_DRAFT ) ) 943 eShadeMode = drawing::ShadeMode_DRAFT; 944 945 beans::PropertyValue aProp; 946 aProp.Name = EASGet( EAS_ShadeMode ); 947 aProp.Value <<= eShadeMode; 948 maExtrusion.push_back( aProp ); 949 } 950 break; 951 case EAS_extrusion_rotation_angle : 952 GetEnhancedParameterPair( maExtrusion, rValue, EAS_RotateAngle ); 953 break; 954 case EAS_extrusion_rotation_center : 955 GetB3DVector( maExtrusion, rValue, EAS_RotationCenter ); 956 break; 957 case EAS_extrusion_shininess : 958 GetDoublePercentage( maExtrusion, rValue, EAS_Shininess ); 959 break; 960 case EAS_extrusion_skew : 961 GetEnhancedParameterPair( maExtrusion, rValue, EAS_Skew ); 962 break; 963 case EAS_extrusion_specularity : 964 GetDoublePercentage( maExtrusion, rValue, EAS_Specularity ); 965 break; 966 case EAS_projection : 967 { 968 drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PERSPECTIVE ); 969 if( IsXMLToken( rValue, XML_PARALLEL ) ) 970 eProjectionMode = drawing::ProjectionMode_PARALLEL; 971 972 beans::PropertyValue aProp; 973 aProp.Name = EASGet( EAS_ProjectionMode ); 974 aProp.Value <<= eProjectionMode; 975 maExtrusion.push_back( aProp ); 976 } 977 break; 978 case EAS_extrusion_viewpoint : 979 GetPosition3D( maExtrusion, rValue, EAS_ViewPoint, mrUnitConverter ); 980 break; 981 case EAS_extrusion_origin : 982 GetEnhancedParameterPair( maExtrusion, rValue, EAS_Origin ); 983 break; 984 case EAS_extrusion_color : 985 GetBool( maExtrusion, rValue, EAS_Color ); 986 break; 987 case EAS_enhanced_path : 988 GetEnhancedPath( maPath, rValue ); 989 break; 990 case EAS_path_stretchpoint_x : 991 { 992 if ( SvXMLUnitConverter::convertNumber( nAttrNumber, rValue ) ) 993 { 994 beans::PropertyValue aProp; 995 aProp.Name = EASGet( EAS_StretchX ); 996 aProp.Value <<= nAttrNumber; 997 maPath.push_back( aProp ); 998 } 999 } 1000 break; 1001 case EAS_path_stretchpoint_y : 1002 { 1003 if ( SvXMLUnitConverter::convertNumber( nAttrNumber, rValue ) ) 1004 { 1005 beans::PropertyValue aProp; 1006 aProp.Name = EASGet( EAS_StretchY ); 1007 aProp.Value <<= nAttrNumber; 1008 maPath.push_back( aProp ); 1009 } 1010 } 1011 break; 1012 case EAS_text_areas : 1013 GetEnhancedRectangleSequence( maPath, rValue, EAS_TextFrames ); 1014 break; 1015 case EAS_glue_points : 1016 { 1017 sal_Int32 i, nPairs = GetEnhancedParameterPairSequence( maPath, rValue, EAS_GluePoints ); 1018 GetImport().GetShapeImport()->moveGluePointMapping( mrxShape, nPairs ); 1019 for ( i = 0; i < nPairs; i++ ) 1020 GetImport().GetShapeImport()->addGluePointMapping( mrxShape, i + 4, i + 4 ); 1021 } 1022 break; 1023 case EAS_glue_point_type : 1024 GetEnum( maPath, rValue, EAS_GluePointType, *aXML_GluePointEnumMap ); 1025 break; 1026 case EAS_glue_point_leaving_directions : 1027 GetDoubleSequence( maPath, rValue, EAS_GluePointLeavingDirections ); 1028 break; 1029 case EAS_text_path : 1030 GetBool( maTextPath, rValue, EAS_TextPath ); 1031 break; 1032 case EAS_text_path_mode : 1033 { 1034 com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode( com::sun::star::drawing::EnhancedCustomShapeTextPathMode_NORMAL ); 1035 if( IsXMLToken( rValue, XML_PATH ) ) 1036 eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH; 1037 else if ( IsXMLToken( rValue, XML_SHAPE ) ) 1038 eTextPathMode = com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE; 1039 1040 beans::PropertyValue aProp; 1041 aProp.Name = EASGet( EAS_TextPathMode ); 1042 aProp.Value <<= eTextPathMode; 1043 maTextPath.push_back( aProp ); 1044 } 1045 break; 1046 case EAS_text_path_scale : 1047 { 1048 sal_Bool bScaleX = IsXMLToken( rValue, XML_SHAPE ); 1049 beans::PropertyValue aProp; 1050 aProp.Name = EASGet( EAS_ScaleX ); 1051 aProp.Value <<= bScaleX; 1052 maTextPath.push_back( aProp ); 1053 } 1054 break; 1055 case EAS_text_path_same_letter_heights : 1056 GetBool( maTextPath, rValue, EAS_SameLetterHeights ); 1057 break; 1058 case EAS_modifiers : 1059 GetAdjustmentValues( mrCustomShapeGeometry, rValue ); 1060 break; 1061 default: 1062 break; 1063 } 1064 } 1065 } 1066 } 1067 1068 void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, 1069 const std::vector< beans::PropertyValues >& rElement, 1070 const rtl::OUString& rElementName ) 1071 { 1072 if ( !rElement.empty() ) 1073 { 1074 uno::Sequence< beans::PropertyValues > aPropSeq( rElement.size() ); 1075 std::vector< beans::PropertyValues >::const_iterator aIter = rElement.begin(); 1076 std::vector< beans::PropertyValues >::const_iterator aEnd = rElement.end(); 1077 beans::PropertyValues* pValues = aPropSeq.getArray(); 1078 1079 while ( aIter != aEnd ) 1080 *pValues++ = *aIter++; 1081 1082 beans::PropertyValue aProp; 1083 aProp.Name = rElementName; 1084 aProp.Value <<= aPropSeq; 1085 rPropVec.push_back( aProp ); 1086 } 1087 } 1088 1089 void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, 1090 const std::vector< rtl::OUString >& rElement, 1091 const rtl::OUString& rElementName ) 1092 { 1093 if ( !rElement.empty() ) 1094 { 1095 uno::Sequence< rtl::OUString > aPropSeq( rElement.size() ); 1096 std::vector< rtl::OUString >::const_iterator aIter = rElement.begin(); 1097 std::vector< rtl::OUString >::const_iterator aEnd = rElement.end(); 1098 rtl::OUString* pValues = aPropSeq.getArray(); 1099 1100 while ( aIter != aEnd ) 1101 *pValues++ = *aIter++; 1102 1103 beans::PropertyValue aProp; 1104 aProp.Name = rElementName; 1105 aProp.Value <<= aPropSeq; 1106 rPropVec.push_back( aProp ); 1107 } 1108 } 1109 1110 void SdXMLCustomShapePropertyMerge( std::vector< com::sun::star::beans::PropertyValue >& rPropVec, 1111 const std::vector< com::sun::star::beans::PropertyValue >& rElement, 1112 const rtl::OUString& rElementName ) 1113 { 1114 if ( !rElement.empty() ) 1115 { 1116 uno::Sequence< beans::PropertyValue > aPropSeq( rElement.size() ); 1117 std::vector< beans::PropertyValue >::const_iterator aIter = rElement.begin(); 1118 std::vector< beans::PropertyValue >::const_iterator aEnd = rElement.end(); 1119 beans::PropertyValue* pValues = aPropSeq.getArray(); 1120 1121 while ( aIter != aEnd ) 1122 *pValues++ = *aIter++; 1123 1124 beans::PropertyValue aProp; 1125 aProp.Name = rElementName; 1126 aProp.Value <<= aPropSeq; 1127 rPropVec.push_back( aProp ); 1128 } 1129 } 1130 1131 typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash, OUStringEqFunc> EquationHashMap; 1132 1133 /* if rPara.Type is from type EnhancedCustomShapeParameterType::EQUATION, the name of the equation 1134 will be converted from rtl::OUString to index */ 1135 void CheckAndResolveEquationParameter( com::sun::star::drawing::EnhancedCustomShapeParameter& rPara, EquationHashMap* pH ) 1136 { 1137 if ( rPara.Type == com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION ) 1138 { 1139 rtl::OUString aEquationName; 1140 if ( rPara.Value >>= aEquationName ) 1141 { 1142 sal_Int32 nIndex = 0; 1143 EquationHashMap::iterator aHashIter( pH->find( aEquationName ) ); 1144 if ( aHashIter != pH->end() ) 1145 nIndex = (*aHashIter).second; 1146 rPara.Value <<= nIndex; 1147 } 1148 } 1149 } 1150 1151 void XMLEnhancedCustomShapeContext::EndElement() 1152 { 1153 // resolve properties that are indexing a Equation 1154 if ( !maEquations.empty() ) 1155 { 1156 // creating hash map containing the name and index of each equation 1157 EquationHashMap* pH = new EquationHashMap; 1158 std::vector< rtl::OUString >::iterator aEquationNameIter = maEquationNames.begin(); 1159 std::vector< rtl::OUString >::iterator aEquationNameEnd = maEquationNames.end(); 1160 while( aEquationNameIter != aEquationNameEnd ) 1161 { 1162 (*pH)[ *aEquationNameIter ] = (sal_Int32)( aEquationNameIter - maEquationNames.begin() ); 1163 aEquationNameIter++; 1164 } 1165 1166 // resolve equation 1167 std::vector< rtl::OUString >::iterator aEquationIter = maEquations.begin(); 1168 std::vector< rtl::OUString >::iterator aEquationEnd = maEquations.end(); 1169 while( aEquationIter != aEquationEnd ) 1170 { 1171 sal_Int32 nIndexOf = 0; 1172 do 1173 { 1174 nIndexOf = aEquationIter->indexOf( '?', nIndexOf ); 1175 if ( nIndexOf != -1 ) 1176 { 1177 rtl::OUString aEquationName; 1178 if ( GetEquationName( *aEquationIter, nIndexOf + 1, aEquationName ) ) 1179 { 1180 // copying first characters inclusive '?' 1181 rtl::OUString aNew( aEquationIter->copy( 0, nIndexOf + 1 ) ); 1182 sal_Int32 nIndex = 0; 1183 EquationHashMap::iterator aHashIter( pH->find( aEquationName ) ); 1184 if ( aHashIter != pH->end() ) 1185 nIndex = (*aHashIter).second; 1186 aNew += rtl::OUString::valueOf( nIndex ); 1187 aNew += aEquationIter->copy( nIndexOf + aEquationName.getLength() + 1 ); 1188 *aEquationIter = aNew; 1189 } 1190 nIndexOf++; 1191 } 1192 } 1193 while( nIndexOf != -1 ); 1194 aEquationIter++; 1195 } 1196 1197 // Path 1198 sal_Int32 i; 1199 std::vector< beans::PropertyValue >::iterator aPathIter = maPath.begin(); 1200 std::vector< beans::PropertyValue >::iterator aPathEnd = maPath.end(); 1201 while ( aPathIter != aPathEnd ) 1202 { 1203 switch( EASGet( aPathIter->Name ) ) 1204 { 1205 case EAS_Coordinates : 1206 case EAS_GluePoints : 1207 { 1208 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >& rSeq = 1209 *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >*) 1210 aPathIter->Value.getValue()); 1211 for ( i = 0; i < rSeq.getLength(); i++ ) 1212 { 1213 CheckAndResolveEquationParameter( rSeq[ i ].First, pH ); 1214 CheckAndResolveEquationParameter( rSeq[ i ].Second, pH ); 1215 } 1216 } 1217 break; 1218 case EAS_TextFrames : 1219 { 1220 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >& rSeq = 1221 *((uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame >*) 1222 aPathIter->Value.getValue()); 1223 for ( i = 0; i < rSeq.getLength(); i++ ) 1224 { 1225 CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.First, pH ); 1226 CheckAndResolveEquationParameter( rSeq[ i ].TopLeft.Second, pH ); 1227 CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.First, pH ); 1228 CheckAndResolveEquationParameter( rSeq[ i ].BottomRight.Second, pH ); 1229 } 1230 } 1231 break; 1232 default: 1233 break; 1234 } 1235 aPathIter++; 1236 } 1237 std::vector< beans::PropertyValues >::iterator aHandleIter = maHandles.begin(); 1238 std::vector< beans::PropertyValues >::iterator aHandleEnd = maHandles.end(); 1239 while ( aHandleIter != aHandleEnd ) 1240 { 1241 beans::PropertyValue* pValues = aHandleIter->getArray(); 1242 for ( i = 0; i < aHandleIter->getLength(); i++ ) 1243 { 1244 switch( EASGet( pValues->Name ) ) 1245 { 1246 case EAS_RangeYMinimum : 1247 case EAS_RangeYMaximum : 1248 case EAS_RangeXMinimum : 1249 case EAS_RangeXMaximum : 1250 case EAS_RadiusRangeMinimum : 1251 case EAS_RadiusRangeMaximum : 1252 { 1253 CheckAndResolveEquationParameter( *((com::sun::star::drawing::EnhancedCustomShapeParameter*) 1254 pValues->Value.getValue()), pH ); 1255 } 1256 break; 1257 1258 case EAS_Position : 1259 case EAS_Polar : 1260 { 1261 CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*) 1262 pValues->Value.getValue())).First, pH ); 1263 CheckAndResolveEquationParameter( (*((com::sun::star::drawing::EnhancedCustomShapeParameterPair*) 1264 pValues->Value.getValue())).Second, pH ); 1265 } 1266 break; 1267 default: 1268 break; 1269 } 1270 pValues++; 1271 } 1272 aHandleIter++; 1273 } 1274 delete pH; 1275 } 1276 1277 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maExtrusion, EASGet( EAS_Extrusion ) ); 1278 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maPath, EASGet( EAS_Path ) ); 1279 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maTextPath, EASGet( EAS_TextPath ) ); 1280 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maEquations, EASGet( EAS_Equations ) ); 1281 if ( !maHandles.empty() ) 1282 SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maHandles, EASGet( EAS_Handles ) ); 1283 } 1284 1285 SvXMLImportContext* XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt16 nPrefix,const rtl::OUString& rLocalName, 1286 const uno::Reference< xml::sax::XAttributeList> & xAttrList ) 1287 { 1288 EnhancedCustomShapeTokenEnum aTokenEnum = EASGet( rLocalName ); 1289 if ( aTokenEnum == EAS_equation ) 1290 { 1291 sal_Int16 nLength = xAttrList->getLength(); 1292 if ( nLength ) 1293 { 1294 rtl::OUString aFormula; 1295 rtl::OUString aFormulaName; 1296 for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) 1297 { 1298 rtl::OUString aLocalName; 1299 const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); 1300 /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); 1301 1302 switch( EASGet( aLocalName ) ) 1303 { 1304 case EAS_formula : 1305 aFormula = rValue; 1306 break; 1307 case EAS_name : 1308 aFormulaName = rValue; 1309 break; 1310 default: 1311 break; 1312 } 1313 } 1314 if ( aFormulaName.getLength() || aFormula.getLength() ) 1315 { 1316 maEquations.push_back( aFormula ); 1317 maEquationNames.push_back( aFormulaName ); 1318 } 1319 } 1320 } 1321 else if ( aTokenEnum == EAS_handle ) 1322 { 1323 std::vector< com::sun::star::beans::PropertyValue > aHandle; 1324 const sal_Int16 nLength = xAttrList->getLength(); 1325 for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ ) 1326 { 1327 rtl::OUString aLocalName; 1328 const rtl::OUString& rValue = xAttrList->getValueByIndex( nAttr ); 1329 /* fixme sven, this needs to be chekced! sal_uInt16 nPrefix = */ GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttr ), &aLocalName ); 1330 switch( EASGet( aLocalName ) ) 1331 { 1332 case EAS_handle_mirror_vertical : 1333 GetBool( aHandle, rValue, EAS_MirroredY ); 1334 break; 1335 case EAS_handle_mirror_horizontal : 1336 GetBool( aHandle, rValue, EAS_MirroredX ); 1337 break; 1338 case EAS_handle_switched : 1339 GetBool( aHandle, rValue, EAS_Switched ); 1340 break; 1341 case EAS_handle_position : 1342 GetEnhancedParameterPair( aHandle, rValue, EAS_Position ); 1343 break; 1344 case EAS_handle_range_x_minimum : 1345 GetEnhancedParameter( aHandle, rValue, EAS_RangeXMinimum ); 1346 break; 1347 case EAS_handle_range_x_maximum : 1348 GetEnhancedParameter( aHandle, rValue, EAS_RangeXMaximum ); 1349 break; 1350 case EAS_handle_range_y_minimum : 1351 GetEnhancedParameter( aHandle, rValue, EAS_RangeYMinimum ); 1352 break; 1353 case EAS_handle_range_y_maximum : 1354 GetEnhancedParameter( aHandle, rValue, EAS_RangeYMaximum ); 1355 break; 1356 case EAS_handle_polar : 1357 GetEnhancedParameterPair( aHandle, rValue, EAS_Polar ); 1358 break; 1359 case EAS_handle_radius_range_minimum : 1360 GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMinimum ); 1361 break; 1362 case EAS_handle_radius_range_maximum : 1363 GetEnhancedParameter( aHandle, rValue, EAS_RadiusRangeMaximum ); 1364 break; 1365 default: 1366 break; 1367 } 1368 } 1369 beans::PropertyValues aPropSeq( aHandle.size() ); 1370 std::vector< beans::PropertyValue >::const_iterator aIter = aHandle.begin(); 1371 std::vector< beans::PropertyValue >::const_iterator aEnd = aHandle.end(); 1372 beans::PropertyValue* pValues = aPropSeq.getArray(); 1373 1374 while ( aIter != aEnd ) 1375 *pValues++ = *aIter++; 1376 1377 maHandles.push_back( aPropSeq ); 1378 } 1379 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList ); 1380 } 1381