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