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_svx.hxx" 26 #include <com/sun/star/container/XIdentifierContainer.hpp> 27 #include <com/sun/star/container/XIndexContainer.hpp> 28 #ifndef _COM_SUN_STAR_DRAWING_GLUEPOINT2_HDL_ 29 #include <com/sun/star/drawing/GluePoint2.hpp> 30 #endif 31 32 #include <cppuhelper/implbase2.hxx> 33 34 #include <svx/svdmodel.hxx> 35 #include <svx/svdobj.hxx> 36 #include <svx/svdglue.hxx> 37 #include <svx/svdpage.hxx> 38 39 using namespace ::com::sun::star; 40 using namespace ::rtl; 41 using namespace ::cppu; 42 43 const sal_uInt16 NON_USER_DEFINED_GLUE_POINTS = 4; 44 45 class SvxUnoGluePointAccess : public WeakImplHelper2< container::XIndexContainer, container::XIdentifierContainer > 46 { 47 private: 48 SdrObjectWeakRef mpObject; 49 50 public: 51 SvxUnoGluePointAccess( SdrObject* pObject ) throw(); 52 virtual ~SvxUnoGluePointAccess() throw(); 53 54 // XIdentifierContainer 55 virtual sal_Int32 SAL_CALL insert( const uno::Any& aElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException); 56 virtual void SAL_CALL removeByIdentifier( sal_Int32 Identifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException); 57 58 // XIdentifierReplace 59 virtual void SAL_CALL replaceByIdentifer( sal_Int32 Identifier, const uno::Any& aElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException); 60 61 // XIdentifierReplace 62 virtual uno::Any SAL_CALL getByIdentifier( sal_Int32 Identifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException); 63 virtual uno::Sequence< sal_Int32 > SAL_CALL getIdentifiers( ) throw (uno::RuntimeException); 64 65 /* deprecated */ 66 // XIndexContainer 67 virtual void SAL_CALL insertByIndex( sal_Int32 Index, const uno::Any& Element ) throw(lang::IllegalArgumentException, lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); 68 virtual void SAL_CALL removeByIndex( sal_Int32 Index ) throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); 69 70 /* deprecated */ 71 // XIndexReplace 72 virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const uno::Any& Element ) throw(lang::IllegalArgumentException, lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); 73 74 /* deprecated */ 75 // XIndexAccess 76 virtual sal_Int32 SAL_CALL getCount( ) throw(uno::RuntimeException); 77 virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); 78 79 // XElementAccess 80 virtual uno::Type SAL_CALL getElementType( ) throw( uno::RuntimeException); 81 virtual sal_Bool SAL_CALL hasElements( ) throw( uno::RuntimeException); 82 }; 83 84 static void convert( const SdrGluePoint& rSdrGlue, drawing::GluePoint2& rUnoGlue ) throw() 85 { 86 rUnoGlue.Position.X = rSdrGlue.GetPos().X(); 87 rUnoGlue.Position.Y = rSdrGlue.GetPos().Y(); 88 rUnoGlue.IsRelative = rSdrGlue.IsPercent(); 89 90 switch( rSdrGlue.GetAlign() ) 91 { 92 case SDRVERTALIGN_TOP|SDRHORZALIGN_LEFT: 93 rUnoGlue.PositionAlignment = drawing::Alignment_TOP_LEFT; 94 break; 95 case SDRHORZALIGN_CENTER|SDRVERTALIGN_TOP: 96 rUnoGlue.PositionAlignment = drawing::Alignment_TOP; 97 break; 98 case SDRVERTALIGN_TOP|SDRHORZALIGN_RIGHT: 99 rUnoGlue.PositionAlignment = drawing::Alignment_TOP_RIGHT; 100 break; 101 case SDRHORZALIGN_CENTER|SDRVERTALIGN_CENTER: 102 rUnoGlue.PositionAlignment = drawing::Alignment_CENTER; 103 break; 104 case SDRHORZALIGN_RIGHT|SDRVERTALIGN_CENTER: 105 rUnoGlue.PositionAlignment = drawing::Alignment_RIGHT; 106 break; 107 case SDRHORZALIGN_LEFT|SDRVERTALIGN_BOTTOM: 108 rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM_LEFT; 109 break; 110 case SDRHORZALIGN_CENTER|SDRVERTALIGN_BOTTOM: 111 rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM; 112 break; 113 case SDRHORZALIGN_RIGHT|SDRVERTALIGN_BOTTOM: 114 rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM_RIGHT; 115 break; 116 // case SDRHORZALIGN_LEFT: 117 default: 118 rUnoGlue.PositionAlignment = drawing::Alignment_LEFT; 119 break; 120 } 121 122 switch( rSdrGlue.GetEscDir() ) 123 { 124 case SDRESC_LEFT: 125 rUnoGlue.Escape = drawing::EscapeDirection_LEFT; 126 break; 127 case SDRESC_RIGHT: 128 rUnoGlue.Escape = drawing::EscapeDirection_RIGHT; 129 break; 130 case SDRESC_TOP: 131 rUnoGlue.Escape = drawing::EscapeDirection_UP; 132 break; 133 case SDRESC_BOTTOM: 134 rUnoGlue.Escape = drawing::EscapeDirection_DOWN; 135 break; 136 case SDRESC_HORZ: 137 rUnoGlue.Escape = drawing::EscapeDirection_HORIZONTAL; 138 break; 139 case SDRESC_VERT: 140 rUnoGlue.Escape = drawing::EscapeDirection_VERTICAL; 141 break; 142 // case SDRESC_SMART: 143 default: 144 rUnoGlue.Escape = drawing::EscapeDirection_SMART; 145 break; 146 } 147 } 148 149 static void convert( const drawing::GluePoint2& rUnoGlue, SdrGluePoint& rSdrGlue ) throw() 150 { 151 rSdrGlue.SetPos( Point( rUnoGlue.Position.X, rUnoGlue.Position.Y ) ); 152 rSdrGlue.SetPercent( rUnoGlue.IsRelative ); 153 154 switch( rUnoGlue.PositionAlignment ) 155 { 156 case drawing::Alignment_TOP_LEFT: 157 rSdrGlue.SetAlign( SDRVERTALIGN_TOP|SDRHORZALIGN_LEFT ); 158 break; 159 case drawing::Alignment_TOP: 160 rSdrGlue.SetAlign( SDRHORZALIGN_CENTER|SDRVERTALIGN_TOP ); 161 break; 162 case drawing::Alignment_TOP_RIGHT: 163 rSdrGlue.SetAlign( SDRVERTALIGN_TOP|SDRHORZALIGN_RIGHT ); 164 break; 165 case drawing::Alignment_CENTER: 166 rSdrGlue.SetAlign( SDRHORZALIGN_CENTER|SDRVERTALIGN_CENTER ); 167 break; 168 case drawing::Alignment_RIGHT: 169 rSdrGlue.SetAlign( SDRHORZALIGN_RIGHT|SDRVERTALIGN_CENTER ); 170 break; 171 case drawing::Alignment_BOTTOM_LEFT: 172 rSdrGlue.SetAlign( SDRHORZALIGN_LEFT|SDRVERTALIGN_BOTTOM ); 173 break; 174 case drawing::Alignment_BOTTOM: 175 rSdrGlue.SetAlign( SDRHORZALIGN_CENTER|SDRVERTALIGN_BOTTOM ); 176 break; 177 case drawing::Alignment_BOTTOM_RIGHT: 178 rSdrGlue.SetAlign( SDRHORZALIGN_RIGHT|SDRVERTALIGN_BOTTOM ); 179 break; 180 // case SDRHORZALIGN_LEFT: 181 default: 182 rSdrGlue.SetAlign( SDRHORZALIGN_LEFT ); 183 break; 184 } 185 switch( rUnoGlue.Escape ) 186 { 187 case drawing::EscapeDirection_LEFT: 188 rSdrGlue.SetEscDir(SDRESC_LEFT); 189 break; 190 case drawing::EscapeDirection_RIGHT: 191 rSdrGlue.SetEscDir(SDRESC_RIGHT); 192 break; 193 case drawing::EscapeDirection_UP: 194 rSdrGlue.SetEscDir(SDRESC_TOP); 195 break; 196 case drawing::EscapeDirection_DOWN: 197 rSdrGlue.SetEscDir(SDRESC_BOTTOM); 198 break; 199 case drawing::EscapeDirection_HORIZONTAL: 200 rSdrGlue.SetEscDir(SDRESC_HORZ); 201 break; 202 case drawing::EscapeDirection_VERTICAL: 203 rSdrGlue.SetEscDir(SDRESC_VERT); 204 break; 205 // case drawing::EscapeDirection_SMART: 206 default: 207 rSdrGlue.SetEscDir(SDRESC_SMART); 208 break; 209 } 210 } 211 212 SvxUnoGluePointAccess::SvxUnoGluePointAccess( SdrObject* pObject ) throw() 213 : mpObject( pObject ) 214 { 215 } 216 217 SvxUnoGluePointAccess::~SvxUnoGluePointAccess() throw() 218 { 219 } 220 221 // XIdentifierContainer 222 sal_Int32 SAL_CALL SvxUnoGluePointAccess::insert( const uno::Any& aElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) 223 { 224 if( mpObject.is() ) 225 { 226 SdrGluePointList* pList = mpObject->ForceGluePointList(); 227 if( pList ) 228 { 229 // second, insert the new glue point 230 drawing::GluePoint2 aUnoGlue; 231 232 if( aElement >>= aUnoGlue ) 233 { 234 SdrGluePoint aSdrGlue; 235 convert( aUnoGlue, aSdrGlue ); 236 sal_uInt16 nId = pList->Insert( aSdrGlue ); 237 238 // only repaint, no objectchange 239 mpObject->ActionChanged(); 240 // mpObject->BroadcastObjectChange(); 241 242 return (sal_Int32)((*pList)[nId].GetId() + NON_USER_DEFINED_GLUE_POINTS) - 1; 243 } 244 245 throw lang::IllegalArgumentException(); 246 } 247 } 248 249 return -1; 250 } 251 252 void SAL_CALL SvxUnoGluePointAccess::removeByIdentifier( sal_Int32 Identifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 253 { 254 if( mpObject.is() && ( Identifier >= NON_USER_DEFINED_GLUE_POINTS )) 255 { 256 const sal_uInt16 nId = (sal_uInt16)(Identifier - NON_USER_DEFINED_GLUE_POINTS) + 1; 257 258 SdrGluePointList* pList = const_cast<SdrGluePointList*>(mpObject->GetGluePointList()); 259 const sal_uInt16 nCount = pList ? pList->GetCount() : 0; 260 sal_uInt16 i; 261 262 for( i = 0; i < nCount; i++ ) 263 { 264 if( (*pList)[i].GetId() == nId ) 265 { 266 pList->Delete( i ); 267 268 // only repaint, no objectchange 269 mpObject->ActionChanged(); 270 // mpObject->BroadcastObjectChange(); 271 272 return; 273 } 274 } 275 } 276 277 throw container::NoSuchElementException(); 278 } 279 280 // XIdentifierReplace 281 void SAL_CALL SvxUnoGluePointAccess::replaceByIdentifer( sal_Int32 Identifier, const uno::Any& aElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 282 { 283 if( mpObject.is() && mpObject->IsNode() ) 284 { 285 struct drawing::GluePoint2 aGluePoint; 286 if( (Identifier < NON_USER_DEFINED_GLUE_POINTS) || !(aElement >>= aGluePoint)) 287 throw lang::IllegalArgumentException(); 288 289 const sal_uInt16 nId = (sal_uInt16)( Identifier - NON_USER_DEFINED_GLUE_POINTS ) + 1; 290 291 SdrGluePointList* pList = const_cast< SdrGluePointList* >( mpObject->GetGluePointList() ); 292 const sal_uInt16 nCount = pList ? pList->GetCount() : 0; 293 sal_uInt16 i; 294 for( i = 0; i < nCount; i++ ) 295 { 296 if( (*pList)[i].GetId() == nId ) 297 { 298 // change the glue point 299 SdrGluePoint& rTempPoint = (*pList)[i]; 300 convert( aGluePoint, rTempPoint ); 301 302 // only repaint, no objectchange 303 mpObject->ActionChanged(); 304 // mpObject->BroadcastObjectChange(); 305 306 return; 307 } 308 } 309 310 throw container::NoSuchElementException(); 311 } 312 } 313 314 // XIdentifierAccess 315 uno::Any SAL_CALL SvxUnoGluePointAccess::getByIdentifier( sal_Int32 Identifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 316 { 317 if( mpObject.is() && mpObject->IsNode() ) 318 { 319 struct drawing::GluePoint2 aGluePoint; 320 321 if( Identifier < NON_USER_DEFINED_GLUE_POINTS ) // default glue point? 322 { 323 SdrGluePoint aTempPoint = mpObject->GetVertexGluePoint( (sal_uInt16)Identifier ); 324 aGluePoint.IsUserDefined = sal_False; 325 convert( aTempPoint, aGluePoint ); 326 return uno::makeAny( aGluePoint ); 327 } 328 else 329 { 330 const sal_uInt16 nId = (sal_uInt16)( Identifier - NON_USER_DEFINED_GLUE_POINTS ) + 1; 331 332 const SdrGluePointList* pList = mpObject->GetGluePointList(); 333 const sal_uInt16 nCount = pList ? pList->GetCount() : 0; 334 for( sal_uInt16 i = 0; i < nCount; i++ ) 335 { 336 const SdrGluePoint& rTempPoint = (*pList)[i]; 337 if( rTempPoint.GetId() == nId ) 338 { 339 // #i38892# 340 if(rTempPoint.IsUserDefined()) 341 { 342 aGluePoint.IsUserDefined = sal_True; 343 } 344 345 convert( rTempPoint, aGluePoint ); 346 return uno::makeAny( aGluePoint ); 347 } 348 } 349 } 350 } 351 352 throw lang::IndexOutOfBoundsException(); 353 } 354 355 uno::Sequence< sal_Int32 > SAL_CALL SvxUnoGluePointAccess::getIdentifiers() throw (uno::RuntimeException) 356 { 357 if( mpObject.is() ) 358 { 359 const SdrGluePointList* pList = mpObject->GetGluePointList(); 360 const sal_uInt16 nCount = pList ? pList->GetCount() : 0; 361 362 sal_uInt16 i; 363 364 uno::Sequence< sal_Int32 > aIdSequence( nCount + NON_USER_DEFINED_GLUE_POINTS ); 365 sal_Int32 *pIdentifier = aIdSequence.getArray(); 366 367 for( i = 0; i < NON_USER_DEFINED_GLUE_POINTS; i++ ) 368 *pIdentifier++ = (sal_Int32)i; 369 370 for( i = 0; i < nCount; i++ ) 371 *pIdentifier++ = (sal_Int32) ( (*pList)[i].GetId() + NON_USER_DEFINED_GLUE_POINTS ) - 1; 372 373 return aIdSequence; 374 } 375 else 376 { 377 uno::Sequence< sal_Int32 > aEmpty; 378 return aEmpty; 379 } 380 } 381 382 /* deprecated */ 383 384 // XIndexContainer 385 void SAL_CALL SvxUnoGluePointAccess::insertByIndex( sal_Int32, const uno::Any& Element ) 386 throw(lang::IllegalArgumentException, lang::IndexOutOfBoundsException, 387 lang::WrappedTargetException, uno::RuntimeException) 388 { 389 if( mpObject.is() ) 390 { 391 SdrGluePointList* pList = mpObject->ForceGluePointList(); 392 if( pList ) 393 { 394 SdrGluePoint aSdrGlue; 395 drawing::GluePoint2 aUnoGlue; 396 397 if( Element >>= aUnoGlue ) 398 { 399 convert( aUnoGlue, aSdrGlue ); 400 pList->Insert( aSdrGlue ); 401 402 // only repaint, no objectchange 403 mpObject->ActionChanged(); 404 // mpObject->BroadcastObjectChange(); 405 406 return; 407 } 408 409 throw lang::IllegalArgumentException(); 410 } 411 } 412 413 throw lang::IndexOutOfBoundsException(); 414 } 415 416 void SAL_CALL SvxUnoGluePointAccess::removeByIndex( sal_Int32 Index ) 417 throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) 418 { 419 if( mpObject.is() ) 420 { 421 SdrGluePointList* pList = mpObject->ForceGluePointList(); 422 if( pList ) 423 { 424 Index -= 4; 425 if( Index >= 0 && Index < pList->GetCount() ) 426 { 427 pList->Delete( (sal_uInt16)Index ); 428 429 // only repaint, no objectchange 430 mpObject->ActionChanged(); 431 // mpObject->BroadcastObjectChange(); 432 433 return; 434 } 435 } 436 } 437 438 throw lang::IndexOutOfBoundsException(); 439 } 440 441 // XIndexReplace 442 void SAL_CALL SvxUnoGluePointAccess::replaceByIndex( sal_Int32 Index, const uno::Any& Element ) 443 throw(lang::IllegalArgumentException, lang::IndexOutOfBoundsException, lang::WrappedTargetException, 444 uno::RuntimeException) 445 { 446 drawing::GluePoint2 aUnoGlue; 447 if(!(Element >>= aUnoGlue)) 448 throw lang::IllegalArgumentException(); 449 450 Index -= 4; 451 if( mpObject.is() && Index >= 0 ) 452 { 453 SdrGluePointList* pList = const_cast< SdrGluePointList* >( mpObject->GetGluePointList() ); 454 if( pList && Index < pList->GetCount() ) 455 { 456 SdrGluePoint& rGlue = (*pList)[(sal_uInt16)Index]; 457 convert( aUnoGlue, rGlue ); 458 459 // only repaint, no objectchange 460 mpObject->ActionChanged(); 461 // mpObject->BroadcastObjectChange(); 462 } 463 } 464 465 throw lang::IndexOutOfBoundsException(); 466 } 467 468 // XIndexAccess 469 sal_Int32 SAL_CALL SvxUnoGluePointAccess::getCount() 470 throw(uno::RuntimeException) 471 { 472 sal_Int32 nCount = 0; 473 if( mpObject.is() ) 474 { 475 // each node has a default of 4 glue points 476 // and any number of user defined glue points 477 if( mpObject->IsNode() ) 478 { 479 nCount += 4; 480 481 const SdrGluePointList* pList = mpObject->GetGluePointList(); 482 if( pList ) 483 nCount += pList->GetCount(); 484 } 485 } 486 487 return nCount; 488 } 489 490 uno::Any SAL_CALL SvxUnoGluePointAccess::getByIndex( sal_Int32 Index ) 491 throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) 492 { 493 if( Index >= 0 && mpObject.is() && mpObject->IsNode() ) 494 { 495 struct drawing::GluePoint2 aGluePoint; 496 497 if( Index < 4 ) // default glue point? 498 { 499 SdrGluePoint aTempPoint = mpObject->GetVertexGluePoint( (sal_uInt16)Index ); 500 aGluePoint.IsUserDefined = sal_False; 501 convert( aTempPoint, aGluePoint ); 502 uno::Any aAny; 503 aAny <<= aGluePoint; 504 return aAny; 505 } 506 else 507 { 508 Index -= 4; 509 const SdrGluePointList* pList = mpObject->GetGluePointList(); 510 if( pList && Index < pList->GetCount() ) 511 { 512 const SdrGluePoint& rTempPoint = (*pList)[(sal_uInt16)Index]; 513 aGluePoint.IsUserDefined = sal_True; 514 convert( rTempPoint, aGluePoint ); 515 uno::Any aAny; 516 aAny <<= aGluePoint; 517 return aAny; 518 } 519 } 520 } 521 522 throw lang::IndexOutOfBoundsException(); 523 } 524 525 // XElementAccess 526 uno::Type SAL_CALL SvxUnoGluePointAccess::getElementType() 527 throw( uno::RuntimeException) 528 { 529 return ::getCppuType((const struct drawing::GluePoint2*)0); 530 } 531 532 sal_Bool SAL_CALL SvxUnoGluePointAccess::hasElements() 533 throw( uno::RuntimeException) 534 { 535 return mpObject.is() && mpObject->IsNode(); 536 } 537 538 /** 539 * Create a SvxUnoGluePointAccess 540 */ 541 uno::Reference< uno::XInterface > SAL_CALL SvxUnoGluePointAccess_createInstance( SdrObject* pObject ) 542 { 543 return *new SvxUnoGluePointAccess(pObject); 544 } 545