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_sc.hxx" 30 31 #include <tools/debug.hxx> 32 #include <comphelper/uno3.hxx> 33 #include <comphelper/stl_types.hxx> 34 #include <svtools/unoevent.hxx> 35 #include <svtools/unoimap.hxx> 36 #include <svx/svdobj.hxx> 37 #include <svx/unoshape.hxx> 38 #include <editeng/unofield.hxx> 39 #include <svx/shapepropertynotifier.hxx> 40 #include <toolkit/helper/convert.hxx> 41 #include <cppuhelper/implbase2.hxx> 42 43 #include <com/sun/star/drawing/XShape.hpp> 44 #include <com/sun/star/beans/PropertyAttribute.hpp> 45 46 #include "shapeuno.hxx" 47 #include "miscuno.hxx" 48 #include "cellsuno.hxx" 49 #include "textuno.hxx" 50 #include "fielduno.hxx" 51 #include "docsh.hxx" 52 #include "drwlayer.hxx" 53 #include "userdat.hxx" 54 #include "unonames.hxx" 55 #include "unoguard.hxx" 56 57 using namespace ::com::sun::star; 58 59 //------------------------------------------------------------------------ 60 61 DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence< sal_Int8 > *, ScShapeImplementationIdMap ); 62 63 static ScShapeImplementationIdMap aImplementationIdMap; 64 65 const SfxItemPropertyMapEntry* lcl_GetShapeMap() 66 { 67 static SfxItemPropertyMapEntry aShapeMap_Impl[] = 68 { 69 {MAP_CHAR_LEN(SC_UNONAME_ANCHOR), 0, &getCppuType((uno::Reference<uno::XInterface>*)0), 0, 0 }, 70 {MAP_CHAR_LEN(SC_UNONAME_HORIPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 }, 71 {MAP_CHAR_LEN(SC_UNONAME_IMAGEMAP), 0, &getCppuType((uno::Reference<container::XIndexContainer>*)0), 0, 0 }, 72 {MAP_CHAR_LEN(SC_UNONAME_VERTPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 }, 73 {0,0,0,0,0,0} 74 }; 75 return aShapeMap_Impl; 76 } 77 78 // static 79 const SvEventDescription* ScShapeObj::GetSupportedMacroItems() 80 { 81 static const SvEventDescription aMacroDescriptionsImpl[] = 82 { 83 { 0, NULL } 84 }; 85 return aMacroDescriptionsImpl; 86 } 87 88 //------------------------------------------------------------------------ 89 90 namespace 91 { 92 void lcl_initializeNotifier( SdrObject& _rSdrObj, ::cppu::OWeakObject& _rShape ) 93 { 94 ::svx::PPropertyValueProvider pProvider( new ::svx::PropertyValueProvider( _rShape, "Anchor" ) ); 95 _rSdrObj.getShapePropertyChangeNotifier().registerProvider( ::svx::eSpreadsheetAnchor, pProvider ); 96 } 97 } 98 99 //------------------------------------------------------------------------ 100 101 ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) : 102 pShapePropertySet(NULL), 103 pShapePropertyState(NULL), 104 pImplementationId(NULL), 105 bIsTextShape(false), 106 bIsNoteCaption(false), 107 bInitializedNotifier(false) 108 { 109 comphelper::increment( m_refCount ); 110 111 { 112 mxShapeAgg = uno::Reference<uno::XAggregation>( xShape, uno::UNO_QUERY ); 113 // extra block to force deletion of the temporary before setDelegator 114 } 115 116 if (mxShapeAgg.is()) 117 { 118 xShape = NULL; // during setDelegator, mxShapeAgg must be the only ref 119 120 mxShapeAgg->setDelegator( (cppu::OWeakObject*)this ); 121 122 xShape.set(uno::Reference<drawing::XShape>( mxShapeAgg, uno::UNO_QUERY )); 123 124 bIsTextShape = ( SvxUnoTextBase::getImplementation( mxShapeAgg ) != NULL ); 125 } 126 127 { 128 SdrObject* pObj = GetSdrObject(); 129 if ( pObj ) 130 { 131 bIsNoteCaption = ScDrawLayer::IsNoteCaption( pObj ); 132 lcl_initializeNotifier( *pObj, *this ); 133 bInitializedNotifier = true; 134 } 135 } 136 137 comphelper::decrement( m_refCount ); 138 } 139 140 ScShapeObj::~ScShapeObj() 141 { 142 // if (mxShapeAgg.is()) 143 // mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>()); 144 } 145 146 // XInterface 147 148 uno::Any SAL_CALL ScShapeObj::queryInterface( const uno::Type& rType ) 149 throw(uno::RuntimeException) 150 { 151 uno::Any aRet = ScShapeObj_Base::queryInterface( rType ); 152 153 if ( !aRet.hasValue() && bIsTextShape ) 154 aRet = ScShapeObj_TextBase::queryInterface( rType ); 155 156 if ( !aRet.hasValue() && bIsNoteCaption ) 157 aRet = ScShapeObj_ChildBase::queryInterface( rType ); 158 159 if ( !aRet.hasValue() && mxShapeAgg.is() ) 160 aRet = mxShapeAgg->queryAggregation( rType ); 161 162 return aRet; 163 } 164 165 void SAL_CALL ScShapeObj::acquire() throw() 166 { 167 OWeakObject::acquire(); 168 } 169 170 void SAL_CALL ScShapeObj::release() throw() 171 { 172 OWeakObject::release(); 173 } 174 175 void ScShapeObj::GetShapePropertySet() 176 { 177 // #i61908# Store the result of queryAggregation in a member. 178 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid. 179 180 if (!pShapePropertySet) 181 { 182 uno::Reference<beans::XPropertySet> xProp; 183 if ( mxShapeAgg.is() ) 184 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertySet>*) 0) ) >>= xProp; 185 pShapePropertySet = xProp.get(); 186 } 187 } 188 189 void ScShapeObj::GetShapePropertyState() 190 { 191 // #i61908# Store the result of queryAggregation in a member. 192 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid. 193 194 if (!pShapePropertyState) 195 { 196 uno::Reference<beans::XPropertyState> xState; 197 if ( mxShapeAgg.is() ) 198 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertyState>*) 0) ) >>= xState; 199 pShapePropertyState = xState.get(); 200 } 201 } 202 203 uno::Reference<lang::XComponent> lcl_GetComponent( const uno::Reference<uno::XAggregation>& xAgg ) 204 { 205 uno::Reference<lang::XComponent> xRet; 206 if ( xAgg.is() ) 207 xAgg->queryAggregation( getCppuType((uno::Reference<lang::XComponent>*) 0) ) >>= xRet; 208 return xRet; 209 } 210 211 uno::Reference<text::XText> lcl_GetText( const uno::Reference<uno::XAggregation>& xAgg ) 212 { 213 uno::Reference<text::XText> xRet; 214 if ( xAgg.is() ) 215 xAgg->queryAggregation( getCppuType((uno::Reference<text::XText>*) 0) ) >>= xRet; 216 return xRet; 217 } 218 219 uno::Reference<text::XSimpleText> lcl_GetSimpleText( const uno::Reference<uno::XAggregation>& xAgg ) 220 { 221 uno::Reference<text::XSimpleText> xRet; 222 if ( xAgg.is() ) 223 xAgg->queryAggregation( getCppuType((uno::Reference<text::XSimpleText>*) 0) ) >>= xRet; 224 return xRet; 225 } 226 227 uno::Reference<text::XTextRange> lcl_GetTextRange( const uno::Reference<uno::XAggregation>& xAgg ) 228 { 229 uno::Reference<text::XTextRange> xRet; 230 if ( xAgg.is() ) 231 xAgg->queryAggregation( getCppuType((uno::Reference<text::XTextRange>*) 0) ) >>= xRet; 232 return xRet; 233 } 234 235 // XPropertySet 236 237 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScShapeObj::getPropertySetInfo() 238 throw(uno::RuntimeException) 239 { 240 ScUnoGuard aGuard; 241 242 // #i61527# cache property set info for this object 243 if ( !mxPropSetInfo.is() ) 244 { 245 // mix own and aggregated properties: 246 GetShapePropertySet(); 247 if (pShapePropertySet) 248 { 249 uno::Reference<beans::XPropertySetInfo> xAggInfo(pShapePropertySet->getPropertySetInfo()); 250 const uno::Sequence<beans::Property> aPropSeq(xAggInfo->getProperties()); 251 mxPropSetInfo.set(new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), aPropSeq )); 252 } 253 } 254 return mxPropSetInfo; 255 } 256 257 sal_Bool lcl_GetPageNum( SdrPage* pPage, SdrModel& rModel, SCTAB& rNum ) 258 { 259 sal_uInt16 nCount = rModel.GetPageCount(); 260 for (sal_uInt16 i=0; i<nCount; i++) 261 if ( rModel.GetPage(i) == pPage ) 262 { 263 rNum = static_cast<SCTAB>(i); 264 return sal_True; 265 } 266 267 return sal_False; 268 } 269 270 sal_Bool lcl_GetCaptionPoint( uno::Reference< drawing::XShape >& xShape, awt::Point& rCaptionPoint ) 271 { 272 sal_Bool bReturn = sal_False; 273 rtl::OUString sType(xShape->getShapeType()); 274 sal_Bool bCaptionShape(sType.equalsAscii("com.sun.star.drawing.CaptionShape")); 275 if (bCaptionShape) 276 { 277 uno::Reference < beans::XPropertySet > xShapeProp (xShape, uno::UNO_QUERY); 278 if (xShapeProp.is()) 279 { 280 xShapeProp->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )) ) >>= rCaptionPoint; 281 bReturn = sal_True; 282 } 283 } 284 return bReturn; 285 } 286 287 ScRange lcl_GetAnchorCell( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab, 288 awt::Point& rUnoPoint, awt::Size& rUnoSize, awt::Point& rCaptionPoint ) 289 { 290 ScRange aReturn; 291 rUnoPoint = xShape->getPosition(); 292 rtl::OUString sType(xShape->getShapeType()); 293 sal_Bool bCaptionShape(lcl_GetCaptionPoint(xShape, rCaptionPoint)); 294 if (pDoc->IsNegativePage(nTab)) 295 { 296 rUnoSize = xShape->getSize(); 297 rUnoPoint.X += rUnoSize.Width; // the right top point is base 298 if (bCaptionShape) 299 { 300 if (rCaptionPoint.X > 0 && rCaptionPoint.X > rUnoSize.Width) 301 rUnoPoint.X += rCaptionPoint.X - rUnoSize.Width; 302 if (rCaptionPoint.Y < 0) 303 rUnoPoint.Y += rCaptionPoint.Y; 304 } 305 aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) )); 306 } 307 else 308 { 309 if (bCaptionShape) 310 { 311 if (rCaptionPoint.X < 0) 312 rUnoPoint.X += rCaptionPoint.X; 313 if (rCaptionPoint.Y < 0) 314 rUnoPoint.Y += rCaptionPoint.Y; 315 } 316 aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) )); 317 } 318 319 return aReturn; 320 } 321 322 awt::Point lcl_GetRelativePos( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab, ScRange& rRange, 323 awt::Size& rUnoSize, awt::Point& rCaptionPoint) 324 { 325 awt::Point aUnoPoint; 326 rRange = lcl_GetAnchorCell(xShape, pDoc, nTab, aUnoPoint, rUnoSize, rCaptionPoint); 327 if (pDoc->IsNegativePage(nTab)) 328 { 329 Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() )); 330 Point aPoint(aRect.TopRight()); 331 aUnoPoint.X -= aPoint.X(); 332 aUnoPoint.Y -= aPoint.Y(); 333 } 334 else 335 { 336 ScRange aRange = pDoc->GetRange( nTab, Rectangle( VCLPoint(aUnoPoint), VCLPoint(aUnoPoint) )); 337 Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() )); 338 Point aPoint(aRect.TopLeft()); 339 aUnoPoint.X -= aPoint.X(); 340 aUnoPoint.Y -= aPoint.Y(); 341 } 342 343 return aUnoPoint; 344 } 345 346 void SAL_CALL ScShapeObj::setPropertyValue( 347 const rtl::OUString& aPropertyName, const uno::Any& aValue ) 348 throw(beans::UnknownPropertyException, beans::PropertyVetoException, 349 lang::IllegalArgumentException, lang::WrappedTargetException, 350 uno::RuntimeException) 351 { 352 ScUnoGuard aGuard; 353 String aNameString(aPropertyName); 354 355 if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) ) 356 { 357 uno::Reference<sheet::XCellRangeAddressable> xRangeAdd(aValue, uno::UNO_QUERY); 358 if (xRangeAdd.is()) 359 { 360 SdrObject *pObj = GetSdrObject(); 361 if (pObj) 362 { 363 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); 364 SdrPage* pPage = pObj->GetPage(); 365 if ( pModel && pPage ) 366 { 367 ScDocument* pDoc = pModel->GetDocument(); 368 if ( pDoc ) 369 { 370 SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); 371 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 372 { 373 ScDocShell* pDocSh = (ScDocShell*)pObjSh; 374 375 SCTAB nTab = 0; 376 if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) 377 { 378 table::CellRangeAddress aAddress = xRangeAdd->getRangeAddress(); 379 if (nTab == aAddress.Sheet) 380 { 381 if (aAddress.StartRow != aAddress.EndRow) //should be a Spreadsheet 382 { 383 DBG_ASSERT(aAddress.StartRow == 0 && aAddress.EndRow == MAXROW && 384 aAddress.StartColumn == 0 && aAddress.EndColumn == MAXCOL, "here should be a XSpreadsheet"); 385 ScDrawLayer::SetAnchor(pObj, SCA_PAGE); 386 } 387 else 388 { 389 DBG_ASSERT(aAddress.StartRow == aAddress.EndRow && 390 aAddress.StartColumn == aAddress.EndColumn, "here should be a XCell"); 391 ScDrawLayer::SetAnchor(pObj, SCA_CELL); 392 } 393 Rectangle aRect(pDoc->GetMMRect( static_cast<SCCOL>(aAddress.StartColumn), static_cast<SCROW>(aAddress.StartRow), 394 static_cast<SCCOL>(aAddress.EndColumn), static_cast<SCROW>(aAddress.EndRow), aAddress.Sheet )); 395 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY ); 396 if (xShape.is()) 397 { 398 Point aPoint; 399 Point aEndPoint; 400 if (pDoc->IsNegativePage(nTab)) 401 { 402 aPoint = aRect.TopRight(); 403 aEndPoint = aRect.BottomLeft(); 404 } 405 else 406 { 407 aPoint = aRect.TopLeft(); 408 aEndPoint = aRect.BottomRight(); 409 } 410 awt::Size aUnoSize; 411 awt::Point aCaptionPoint; 412 ScRange aRange; 413 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint )); 414 415 aUnoPoint.X += aPoint.X(); 416 aUnoPoint.Y += aPoint.Y(); 417 418 if ( aUnoPoint.Y > aEndPoint.Y() ) 419 aUnoPoint.Y = aEndPoint.Y() - 2; 420 if (pDoc->IsNegativePage(nTab)) 421 { 422 if ( aUnoPoint.X < aEndPoint.X() ) 423 aUnoPoint.X = aEndPoint.X() + 2; 424 aUnoPoint.X -= aUnoSize.Width; 425 // remove difference to caption point 426 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width) 427 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width; 428 } 429 else 430 { 431 if ( aUnoPoint.X > aEndPoint.X() ) 432 aUnoPoint.X = aEndPoint.X() - 2; 433 if (aCaptionPoint.X < 0) 434 aUnoPoint.X -= aCaptionPoint.X; 435 } 436 if (aCaptionPoint.Y < 0) 437 aUnoPoint.Y -= aCaptionPoint.Y; 438 439 xShape->setPosition(aUnoPoint); 440 pDocSh->SetModified(); 441 } 442 } 443 } 444 } 445 } 446 } 447 } 448 } 449 else 450 throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("only XCell or XSpreadsheet objects allowed")), static_cast<cppu::OWeakObject*>(this), 0); 451 } 452 else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) ) 453 { 454 SdrObject* pObj = GetSdrObject(); 455 if ( pObj ) 456 { 457 ImageMap aImageMap; 458 uno::Reference< uno::XInterface > xImageMapInt(aValue, uno::UNO_QUERY); 459 460 if( !xImageMapInt.is() || !SvUnoImageMap_fillImageMap( xImageMapInt, aImageMap ) ) 461 throw lang::IllegalArgumentException(); 462 463 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj); 464 if( pIMapInfo ) 465 { 466 // replace existing image map 467 pIMapInfo->SetImageMap( aImageMap ); 468 } 469 else 470 { 471 // insert new user data with image map 472 pObj->InsertUserData(new ScIMapInfo(aImageMap) ); 473 } 474 } 475 } 476 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) ) 477 { 478 sal_Int32 nPos = 0; 479 if (aValue >>= nPos) 480 { 481 SdrObject *pObj = GetSdrObject(); 482 if (pObj) 483 { 484 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); 485 SdrPage* pPage = pObj->GetPage(); 486 if ( pModel && pPage ) 487 { 488 SCTAB nTab = 0; 489 if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) 490 { 491 ScDocument* pDoc = pModel->GetDocument(); 492 if ( pDoc ) 493 { 494 SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); 495 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 496 { 497 ScDocShell* pDocSh = (ScDocShell*)pObjSh; 498 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY ); 499 if (xShape.is()) 500 { 501 if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE) 502 { 503 awt::Point aPoint(xShape->getPosition()); 504 awt::Size aSize(xShape->getSize()); 505 awt::Point aCaptionPoint; 506 if (pDoc->IsNegativePage(nTab)) 507 { 508 nPos *= -1; 509 nPos -= aSize.Width; 510 } 511 if (lcl_GetCaptionPoint(xShape, aCaptionPoint)) 512 { 513 if (pDoc->IsNegativePage(nTab)) 514 { 515 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aSize.Width) 516 nPos -= aCaptionPoint.X - aSize.Width; 517 } 518 else 519 { 520 if (aCaptionPoint.X < 0) 521 nPos -= aCaptionPoint.X; 522 } 523 } 524 aPoint.X = nPos; 525 xShape->setPosition(aPoint); 526 pDocSh->SetModified(); 527 } 528 else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL) 529 { 530 awt::Size aUnoSize; 531 awt::Point aCaptionPoint; 532 ScRange aRange; 533 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint )); 534 Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() )); 535 if (pDoc->IsNegativePage(nTab)) 536 { 537 aUnoPoint.X = -nPos; 538 Point aPoint(aRect.TopRight()); 539 Point aEndPoint(aRect.BottomLeft()); 540 aUnoPoint.X += aPoint.X(); 541 if (aUnoPoint.X < aEndPoint.X()) 542 aUnoPoint.X = aEndPoint.X() + 2; 543 aUnoPoint.X -= aUnoSize.Width; 544 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width) 545 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width; 546 } 547 else 548 { 549 aUnoPoint.X = nPos; 550 Point aPoint(aRect.TopLeft()); 551 Point aEndPoint(aRect.BottomRight()); 552 aUnoPoint.X += aPoint.X(); 553 if (aUnoPoint.X > aEndPoint.X()) 554 aUnoPoint.X = aEndPoint.X() - 2; 555 if (aCaptionPoint.X < 0) 556 aUnoPoint.X -= aCaptionPoint.X; 557 } 558 aUnoPoint.Y = xShape->getPosition().Y; 559 xShape->setPosition(aUnoPoint); 560 pDocSh->SetModified(); 561 } 562 else 563 { 564 DBG_ERROR("unknown anchor type"); 565 } 566 } 567 } 568 } 569 } 570 } 571 } 572 } 573 } 574 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) ) 575 { 576 sal_Int32 nPos = 0; 577 if (aValue >>= nPos) 578 { 579 SdrObject *pObj = GetSdrObject(); 580 if (pObj) 581 { 582 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); 583 SdrPage* pPage = pObj->GetPage(); 584 if ( pModel && pPage ) 585 { 586 SCTAB nTab = 0; 587 if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) 588 { 589 ScDocument* pDoc = pModel->GetDocument(); 590 if ( pDoc ) 591 { 592 SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); 593 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 594 { 595 ScDocShell* pDocSh = (ScDocShell*)pObjSh; 596 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY ); 597 if (xShape.is()) 598 { 599 if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE) 600 { 601 awt::Point aPoint = xShape->getPosition(); 602 awt::Point aCaptionPoint; 603 if (lcl_GetCaptionPoint(xShape, aCaptionPoint)) 604 { 605 if (aCaptionPoint.Y < 0) 606 nPos -= aCaptionPoint.Y; 607 } 608 aPoint.Y = nPos; 609 xShape->setPosition(aPoint); 610 pDocSh->SetModified(); 611 } 612 else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL) 613 { 614 awt::Size aUnoSize; 615 awt::Point aCaptionPoint; 616 ScRange aRange; 617 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint )); 618 Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() )); 619 Point aPoint(aRect.TopRight()); 620 Point aEndPoint(aRect.BottomLeft()); 621 aUnoPoint.Y = nPos; 622 aUnoPoint.Y += aPoint.Y(); 623 if (aUnoPoint.Y > aEndPoint.Y()) 624 aUnoPoint.Y = aEndPoint.Y() - 2; 625 if (aCaptionPoint.Y < 0) 626 aUnoPoint.Y -= aCaptionPoint.Y; 627 aUnoPoint.X = xShape->getPosition().X; 628 xShape->setPosition(aUnoPoint); 629 pDocSh->SetModified(); 630 } 631 else 632 { 633 DBG_ERROR("unknown anchor type"); 634 } 635 } 636 } 637 } 638 } 639 } 640 } 641 } 642 } 643 else 644 { 645 GetShapePropertySet(); 646 if (pShapePropertySet) 647 pShapePropertySet->setPropertyValue( aPropertyName, aValue ); 648 } 649 } 650 651 uno::Any SAL_CALL ScShapeObj::getPropertyValue( const rtl::OUString& aPropertyName ) 652 throw(beans::UnknownPropertyException, lang::WrappedTargetException, 653 uno::RuntimeException) 654 { 655 ScUnoGuard aGuard; 656 String aNameString = aPropertyName; 657 658 uno::Any aAny; 659 if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) ) 660 { 661 SdrObject *pObj = GetSdrObject(); 662 if (pObj) 663 { 664 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); 665 SdrPage* pPage = pObj->GetPage(); 666 if ( pModel && pPage ) 667 { 668 ScDocument* pDoc = pModel->GetDocument(); 669 if ( pDoc ) 670 { 671 SCTAB nTab = 0; 672 if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) 673 { 674 SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); 675 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 676 { 677 ScDocShell* pDocSh = (ScDocShell*)pObjSh; 678 uno::Reference< uno::XInterface > xAnchor; 679 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL) 680 { 681 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY ); 682 if (xShape.is()) 683 { 684 awt::Size aUnoSize; 685 awt::Point aCaptionPoint; 686 ScRange aRange; 687 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint )); 688 689 xAnchor.set(static_cast<cppu::OWeakObject*>(new ScCellObj( pDocSh, aRange.aStart ))); 690 } 691 } 692 else 693 { 694 xAnchor.set(static_cast<cppu::OWeakObject*>(new ScTableSheetObj( pDocSh, nTab ))); 695 } 696 aAny <<= xAnchor; 697 } 698 } 699 } 700 } 701 } 702 } 703 else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) ) 704 { 705 uno::Reference< uno::XInterface > xImageMap; 706 SdrObject* pObj = GetSdrObject(); 707 if ( pObj ) 708 { 709 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(GetSdrObject()); 710 if( pIMapInfo ) 711 { 712 const ImageMap& rIMap = pIMapInfo->GetImageMap(); 713 xImageMap.set(SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() )); 714 } 715 else 716 xImageMap = SvUnoImageMap_createInstance( GetSupportedMacroItems() ); 717 } 718 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap ); 719 } 720 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) ) 721 { 722 SdrObject *pObj = GetSdrObject(); 723 if (pObj) 724 { 725 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); 726 SdrPage* pPage = pObj->GetPage(); 727 if ( pModel && pPage ) 728 { 729 ScDocument* pDoc = pModel->GetDocument(); 730 if ( pDoc ) 731 { 732 SCTAB nTab = 0; 733 if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) 734 { 735 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY ); 736 if (xShape.is()) 737 { 738 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL) 739 { 740 awt::Size aUnoSize; 741 awt::Point aCaptionPoint; 742 ScRange aRange; 743 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint )); 744 if (pDoc->IsNegativePage(nTab)) 745 aUnoPoint.X *= -1; 746 aAny <<= aUnoPoint.X; 747 } 748 else 749 { 750 awt::Point aCaptionPoint; 751 awt::Point aUnoPoint(xShape->getPosition()); 752 awt::Size aUnoSize(xShape->getSize()); 753 if (pDoc->IsNegativePage(nTab)) 754 { 755 aUnoPoint.X *= -1; 756 aUnoPoint.X -= aUnoSize.Width; 757 } 758 if (lcl_GetCaptionPoint(xShape, aCaptionPoint)) 759 { 760 if (pDoc->IsNegativePage(nTab)) 761 { 762 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width) 763 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width; 764 } 765 else 766 { 767 if (aCaptionPoint.X < 0) 768 aUnoPoint.X += aCaptionPoint.X; 769 } 770 } 771 aAny <<= aUnoPoint.X; 772 } 773 } 774 } 775 } 776 } 777 } 778 } 779 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) ) 780 { 781 SdrObject *pObj = GetSdrObject(); 782 if (pObj) 783 { 784 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); 785 SdrPage* pPage = pObj->GetPage(); 786 if ( pModel && pPage ) 787 { 788 ScDocument* pDoc = pModel->GetDocument(); 789 if ( pDoc ) 790 { 791 SCTAB nTab = 0; 792 if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) 793 { 794 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY ); 795 if (xShape.is()) 796 { 797 uno::Reference< uno::XInterface > xAnchor; 798 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL) 799 { 800 awt::Size aUnoSize; 801 awt::Point aCaptionPoint; 802 ScRange aRange; 803 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint )); 804 805 aAny <<= aUnoPoint.Y; 806 } 807 else 808 { 809 awt::Point aUnoPoint(xShape->getPosition()); 810 awt::Point aCaptionPoint; 811 if (lcl_GetCaptionPoint(xShape, aCaptionPoint)) 812 { 813 if (aCaptionPoint.Y < 0) 814 aUnoPoint.Y += aCaptionPoint.Y; 815 } 816 aAny <<= aUnoPoint.Y; 817 } 818 } 819 } 820 } 821 } 822 } 823 } 824 else 825 { 826 GetShapePropertySet(); 827 if (pShapePropertySet) 828 aAny = pShapePropertySet->getPropertyValue( aPropertyName ); 829 } 830 831 return aAny; 832 } 833 834 void SAL_CALL ScShapeObj::addPropertyChangeListener( const rtl::OUString& aPropertyName, 835 const uno::Reference<beans::XPropertyChangeListener>& aListener) 836 throw(beans::UnknownPropertyException, 837 lang::WrappedTargetException, uno::RuntimeException) 838 { 839 ScUnoGuard aGuard; 840 841 GetShapePropertySet(); 842 if (pShapePropertySet) 843 pShapePropertySet->addPropertyChangeListener( aPropertyName, aListener ); 844 845 if ( !bInitializedNotifier ) 846 { 847 // here's the latest chance to initialize the property notification at the SdrObject 848 // (in the ctor, where we also attempt to do this, we do not necessarily have 849 // and SdrObject, yet) 850 SdrObject* pObj = GetSdrObject(); 851 OSL_ENSURE( pObj, "ScShapeObj::addPropertyChangeListener: no SdrObject -> no property change notification!" ); 852 if ( pObj ) 853 lcl_initializeNotifier( *pObj, *this ); 854 bInitializedNotifier = true; 855 } 856 } 857 858 void SAL_CALL ScShapeObj::removePropertyChangeListener( const rtl::OUString& aPropertyName, 859 const uno::Reference<beans::XPropertyChangeListener>& aListener) 860 throw(beans::UnknownPropertyException, 861 lang::WrappedTargetException, uno::RuntimeException) 862 { 863 ScUnoGuard aGuard; 864 865 GetShapePropertySet(); 866 if (pShapePropertySet) 867 pShapePropertySet->removePropertyChangeListener( aPropertyName, aListener ); 868 } 869 870 void SAL_CALL ScShapeObj::addVetoableChangeListener( const rtl::OUString& aPropertyName, 871 const uno::Reference<beans::XVetoableChangeListener>& aListener) 872 throw(beans::UnknownPropertyException, 873 lang::WrappedTargetException, uno::RuntimeException) 874 { 875 ScUnoGuard aGuard; 876 877 GetShapePropertySet(); 878 if (pShapePropertySet) 879 pShapePropertySet->addVetoableChangeListener( aPropertyName, aListener ); 880 } 881 882 void SAL_CALL ScShapeObj::removeVetoableChangeListener( const rtl::OUString& aPropertyName, 883 const uno::Reference<beans::XVetoableChangeListener>& aListener) 884 throw(beans::UnknownPropertyException, 885 lang::WrappedTargetException, uno::RuntimeException) 886 { 887 ScUnoGuard aGuard; 888 889 GetShapePropertySet(); 890 if (pShapePropertySet) 891 pShapePropertySet->removeVetoableChangeListener( aPropertyName, aListener ); 892 } 893 894 // XPropertyState 895 896 beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const rtl::OUString& aPropertyName ) 897 throw(beans::UnknownPropertyException, uno::RuntimeException) 898 { 899 ScUnoGuard aGuard; 900 String aNameString(aPropertyName); 901 902 beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE; 903 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) ) 904 { 905 // ImageMap is always "direct" 906 } 907 else if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) ) 908 { 909 // Anchor is always "direct" 910 } 911 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) ) 912 { 913 // HoriPos is always "direct" 914 } 915 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) ) 916 { 917 // VertPos is always "direct" 918 } 919 else 920 { 921 GetShapePropertyState(); 922 if (pShapePropertyState) 923 eRet = pShapePropertyState->getPropertyState( aPropertyName ); 924 } 925 926 return eRet; 927 } 928 929 uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates( 930 const uno::Sequence<rtl::OUString>& aPropertyNames ) 931 throw(beans::UnknownPropertyException, uno::RuntimeException) 932 { 933 ScUnoGuard aGuard; 934 935 // simple loop to get own and aggregated states 936 937 const rtl::OUString* pNames = aPropertyNames.getConstArray(); 938 uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength()); 939 beans::PropertyState* pStates = aRet.getArray(); 940 for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++) 941 pStates[i] = getPropertyState(pNames[i]); 942 return aRet; 943 } 944 945 void SAL_CALL ScShapeObj::setPropertyToDefault( const rtl::OUString& aPropertyName ) 946 throw(beans::UnknownPropertyException, uno::RuntimeException) 947 { 948 ScUnoGuard aGuard; 949 String aNameString(aPropertyName); 950 951 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) ) 952 { 953 SdrObject* pObj = GetSdrObject(); 954 if ( pObj ) 955 { 956 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj); 957 if( pIMapInfo ) 958 { 959 ImageMap aEmpty; 960 pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map 961 } 962 else 963 { 964 // nothing to do (no need to insert user data for an empty map) 965 } 966 } 967 } 968 else 969 { 970 GetShapePropertyState(); 971 if (pShapePropertyState) 972 pShapePropertyState->setPropertyToDefault( aPropertyName ); 973 } 974 } 975 976 uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const rtl::OUString& aPropertyName ) 977 throw(beans::UnknownPropertyException, lang::WrappedTargetException, 978 uno::RuntimeException) 979 { 980 ScUnoGuard aGuard; 981 String aNameString = aPropertyName; 982 983 uno::Any aAny; 984 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) ) 985 { 986 // default: empty ImageMap 987 uno::Reference< uno::XInterface > xImageMap(SvUnoImageMap_createInstance( GetSupportedMacroItems() )); 988 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap ); 989 } 990 else 991 { 992 GetShapePropertyState(); 993 if (pShapePropertyState) 994 aAny = pShapePropertyState->getPropertyDefault( aPropertyName ); 995 } 996 997 return aAny; 998 } 999 1000 // XTextContent 1001 1002 void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& /* xTextRange */ ) 1003 throw(lang::IllegalArgumentException, uno::RuntimeException) 1004 { 1005 ScUnoGuard aGuard; 1006 1007 throw lang::IllegalArgumentException(); // anchor cannot be changed 1008 } 1009 1010 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor() throw(uno::RuntimeException) 1011 { 1012 ScUnoGuard aGuard; 1013 1014 uno::Reference<text::XTextRange> xRet; 1015 1016 SdrObject* pObj = GetSdrObject(); 1017 if( pObj ) 1018 { 1019 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); 1020 SdrPage* pPage = pObj->GetPage(); 1021 if ( pModel ) 1022 { 1023 ScDocument* pDoc = pModel->GetDocument(); 1024 if ( pDoc ) 1025 { 1026 SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); 1027 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 1028 { 1029 ScDocShell* pDocSh = (ScDocShell*)pObjSh; 1030 1031 SCTAB nTab = 0; 1032 if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) 1033 { 1034 Point aPos(pObj->GetCurrentBoundRect().TopLeft()); 1035 ScRange aRange(pDoc->GetRange( nTab, Rectangle( aPos, aPos ) )); 1036 1037 // anchor is always the cell 1038 1039 xRet.set(new ScCellObj( pDocSh, aRange.aStart )); 1040 } 1041 } 1042 } 1043 } 1044 } 1045 1046 return xRet; 1047 } 1048 1049 // XComponent 1050 1051 void SAL_CALL ScShapeObj::dispose() throw(uno::RuntimeException) 1052 { 1053 ScUnoGuard aGuard; 1054 1055 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg)); 1056 if ( xAggComp.is() ) 1057 xAggComp->dispose(); 1058 } 1059 1060 void SAL_CALL ScShapeObj::addEventListener( 1061 const uno::Reference<lang::XEventListener>& xListener ) 1062 throw(uno::RuntimeException) 1063 { 1064 ScUnoGuard aGuard; 1065 1066 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg)); 1067 if ( xAggComp.is() ) 1068 xAggComp->addEventListener(xListener); 1069 } 1070 1071 void SAL_CALL ScShapeObj::removeEventListener( 1072 const uno::Reference<lang::XEventListener>& xListener ) 1073 throw(uno::RuntimeException) 1074 { 1075 ScUnoGuard aGuard; 1076 1077 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg)); 1078 if ( xAggComp.is() ) 1079 xAggComp->removeEventListener(xListener); 1080 } 1081 1082 // XText 1083 // (special handling for ScCellFieldObj) 1084 1085 void lcl_CopyOneProperty( beans::XPropertySet& rDest, beans::XPropertySet& rSource, const sal_Char* pName ) 1086 { 1087 rtl::OUString aNameStr(rtl::OUString::createFromAscii(pName)); 1088 try 1089 { 1090 rDest.setPropertyValue( aNameStr, rSource.getPropertyValue( aNameStr ) ); 1091 } 1092 catch (uno::Exception&) 1093 { 1094 DBG_ERROR("Exception in text field"); 1095 } 1096 } 1097 1098 void SAL_CALL ScShapeObj::insertTextContent( const uno::Reference<text::XTextRange>& xRange, 1099 const uno::Reference<text::XTextContent>& xContent, 1100 sal_Bool bAbsorb ) 1101 throw(lang::IllegalArgumentException, uno::RuntimeException) 1102 { 1103 ScUnoGuard aGuard; 1104 1105 uno::Reference<text::XTextContent> xEffContent; 1106 1107 ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent ); 1108 if ( pCellField ) 1109 { 1110 // #105585# createInstance("TextField.URL") from the document creates a ScCellFieldObj. 1111 // To insert it into drawing text, a SvxUnoTextField is needed instead. 1112 // The ScCellFieldObj object is left in non-inserted state. 1113 1114 SvxUnoTextField* pDrawField = new SvxUnoTextField( ID_URLFIELD ); 1115 xEffContent.set(pDrawField); 1116 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL ); 1117 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR ); 1118 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET ); 1119 } 1120 else 1121 xEffContent.set(xContent); 1122 1123 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg)); 1124 if ( xAggText.is() ) 1125 xAggText->insertTextContent( xRange, xEffContent, bAbsorb ); 1126 } 1127 1128 void SAL_CALL ScShapeObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent ) 1129 throw(container::NoSuchElementException, uno::RuntimeException) 1130 { 1131 ScUnoGuard aGuard; 1132 1133 // ScCellFieldObj can't be used here. 1134 1135 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg)); 1136 if ( xAggText.is() ) 1137 xAggText->removeTextContent( xContent ); 1138 } 1139 1140 // XSimpleText (parent of XText) 1141 // Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object 1142 1143 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursor() 1144 throw(uno::RuntimeException) 1145 { 1146 ScUnoGuard aGuard; 1147 1148 if ( mxShapeAgg.is() ) 1149 { 1150 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText 1151 1152 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg ); 1153 if (pText) 1154 return new ScDrawTextCursor( this, *pText ); 1155 } 1156 1157 return uno::Reference<text::XTextCursor>(); 1158 } 1159 1160 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursorByRange( 1161 const uno::Reference<text::XTextRange>& aTextPosition ) 1162 throw(uno::RuntimeException) 1163 { 1164 ScUnoGuard aGuard; 1165 1166 if ( mxShapeAgg.is() && aTextPosition.is() ) 1167 { 1168 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText 1169 1170 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg ); 1171 SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition ); 1172 if ( pText && pRange ) 1173 { 1174 SvxUnoTextCursor* pCursor = new ScDrawTextCursor( this, *pText ); 1175 uno::Reference<text::XTextCursor> xCursor( pCursor ); 1176 pCursor->SetSelection( pRange->GetSelection() ); 1177 return xCursor; 1178 } 1179 } 1180 1181 return uno::Reference<text::XTextCursor>(); 1182 } 1183 1184 void SAL_CALL ScShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange, 1185 const rtl::OUString& aString, sal_Bool bAbsorb ) 1186 throw(uno::RuntimeException) 1187 { 1188 ScUnoGuard aGuard; 1189 1190 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg)); 1191 if ( xAggSimpleText.is() ) 1192 xAggSimpleText->insertString( xRange, aString, bAbsorb ); 1193 else 1194 throw uno::RuntimeException(); 1195 } 1196 1197 void SAL_CALL ScShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange, 1198 sal_Int16 nControlCharacter, sal_Bool bAbsorb ) 1199 throw(lang::IllegalArgumentException, uno::RuntimeException) 1200 { 1201 ScUnoGuard aGuard; 1202 1203 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg)); 1204 if ( xAggSimpleText.is() ) 1205 xAggSimpleText->insertControlCharacter( xRange, nControlCharacter, bAbsorb ); 1206 else 1207 throw uno::RuntimeException(); 1208 } 1209 1210 // XTextRange 1211 // (parent of XSimpleText) 1212 1213 uno::Reference<text::XText> SAL_CALL ScShapeObj::getText() throw(uno::RuntimeException) 1214 { 1215 ScUnoGuard aGuard; 1216 return this; 1217 } 1218 1219 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart() throw(uno::RuntimeException) 1220 { 1221 ScUnoGuard aGuard; 1222 1223 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg)); 1224 if ( xAggTextRange.is() ) 1225 return xAggTextRange->getStart(); 1226 else 1227 throw uno::RuntimeException(); 1228 1229 // return uno::Reference<text::XTextRange>(); 1230 } 1231 1232 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getEnd() throw(uno::RuntimeException) 1233 { 1234 ScUnoGuard aGuard; 1235 1236 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg)); 1237 if ( xAggTextRange.is() ) 1238 return xAggTextRange->getEnd(); 1239 else 1240 throw uno::RuntimeException(); 1241 1242 // return uno::Reference<text::XTextRange>(); 1243 } 1244 1245 rtl::OUString SAL_CALL ScShapeObj::getString() throw(uno::RuntimeException) 1246 { 1247 ScUnoGuard aGuard; 1248 1249 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg)); 1250 if ( xAggTextRange.is() ) 1251 return xAggTextRange->getString(); 1252 else 1253 throw uno::RuntimeException(); 1254 1255 // return rtl::OUString(); 1256 } 1257 1258 void SAL_CALL ScShapeObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException) 1259 { 1260 ScUnoGuard aGuard; 1261 1262 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg)); 1263 if ( xAggTextRange.is() ) 1264 xAggTextRange->setString( aText ); 1265 else 1266 throw uno::RuntimeException(); 1267 } 1268 1269 // XChild 1270 1271 uno::Reference< uno::XInterface > SAL_CALL ScShapeObj::getParent() throw (uno::RuntimeException) 1272 { 1273 ScUnoGuard aGuard; 1274 1275 // receive cell position from caption object (parent of a note caption is the note cell) 1276 SdrObject* pObj = GetSdrObject(); 1277 if( pObj ) 1278 { 1279 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); 1280 SdrPage* pPage = pObj->GetPage(); 1281 if ( pModel ) 1282 { 1283 ScDocument* pDoc = pModel->GetDocument(); 1284 if ( pDoc ) 1285 { 1286 SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); 1287 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 1288 { 1289 ScDocShell* pDocSh = (ScDocShell*)pObjSh; 1290 1291 SCTAB nTab = 0; 1292 if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) 1293 { 1294 const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab ); 1295 if( pCaptData ) 1296 return static_cast< ::cppu::OWeakObject* >( new ScCellObj( pDocSh, pCaptData->maStart ) ); 1297 } 1298 } 1299 } 1300 } 1301 } 1302 1303 return 0; 1304 } 1305 1306 void SAL_CALL ScShapeObj::setParent( const uno::Reference< uno::XInterface >& ) throw (lang::NoSupportException, uno::RuntimeException) 1307 { 1308 throw lang::NoSupportException(); 1309 } 1310 1311 // XTypeProvider 1312 1313 uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes() throw(uno::RuntimeException) 1314 { 1315 uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() ); 1316 1317 uno::Sequence< uno::Type > aTextTypes; 1318 if ( bIsTextShape ) 1319 aTextTypes = ScShapeObj_TextBase::getTypes(); 1320 1321 uno::Reference<lang::XTypeProvider> xBaseProvider; 1322 if ( mxShapeAgg.is() ) 1323 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<lang::XTypeProvider>*) 0) ) >>= xBaseProvider; 1324 DBG_ASSERT( xBaseProvider.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" ); 1325 1326 uno::Sequence< uno::Type > aAggTypes; 1327 if( xBaseProvider.is() ) 1328 aAggTypes = xBaseProvider->getTypes(); 1329 1330 return ::comphelper::concatSequences( aBaseTypes, aTextTypes, aAggTypes ); 1331 } 1332 1333 uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId() 1334 throw(uno::RuntimeException) 1335 { 1336 ScUnoGuard aGuard; 1337 // do we need to compute the implementation id for this instance? 1338 if( !pImplementationId && mxShapeAgg.is()) 1339 { 1340 uno::Reference< drawing::XShape > xAggShape; 1341 mxShapeAgg->queryAggregation( ::getCppuType((uno::Reference< drawing::XShape >*)0) ) >>= xAggShape; 1342 1343 if( xAggShape.is() ) 1344 { 1345 const rtl::OUString aShapeType( xAggShape->getShapeType() ); 1346 // did we already compute an implementation id for the agregated shape type? 1347 ScShapeImplementationIdMap::iterator aIter( aImplementationIdMap.find(aShapeType ) ); 1348 if( aIter == aImplementationIdMap.end() ) 1349 { 1350 // we need to create a new implementation id for this 1351 // note: this memory is not free'd until application exists 1352 // but since we have a fixed set of shapetypes and the 1353 // memory will be reused this is ok. 1354 pImplementationId = new uno::Sequence< sal_Int8 >( 16 ); 1355 rtl_createUuid( (sal_uInt8 *) pImplementationId->getArray(), 0, sal_True ); 1356 aImplementationIdMap[ aShapeType ] = pImplementationId; 1357 } 1358 else 1359 { 1360 // use the already computed implementation id 1361 pImplementationId = (*aIter).second; 1362 } 1363 } 1364 } 1365 if( NULL == pImplementationId ) 1366 { 1367 DBG_ERROR( "Could not create an implementation id for a ScXShape!" ); 1368 return uno::Sequence< sal_Int8 > (); 1369 } 1370 else 1371 { 1372 return *pImplementationId; 1373 } 1374 } 1375 1376 SdrObject* ScShapeObj::GetSdrObject() const throw() 1377 { 1378 if(mxShapeAgg.is()) 1379 { 1380 SvxShape* pShape = SvxShape::getImplementation( mxShapeAgg ); 1381 if(pShape) 1382 return pShape->GetSdrObject(); 1383 } 1384 1385 return NULL; 1386 } 1387 1388 #define SC_EVENTACC_ONCLICK ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) ) 1389 #ifdef ISSUE66550_HLINK_FOR_SHAPES 1390 #define SC_EVENTACC_ONACTION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAction" ) ) 1391 #define SC_EVENTACC_URL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) 1392 #define SC_EVENTACC_ACTION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Action" ) ) 1393 #endif 1394 #define SC_EVENTACC_SCRIPT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Script" ) ) 1395 #define SC_EVENTACC_EVENTTYPE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) ) 1396 1397 typedef ::cppu::WeakImplHelper1< container::XNameReplace > ShapeUnoEventAcess_BASE; 1398 class ShapeUnoEventAccessImpl : public ShapeUnoEventAcess_BASE 1399 { 1400 private: 1401 ScShapeObj* mpShape; 1402 1403 ScMacroInfo* getInfo( sal_Bool bCreate = sal_False ) 1404 { 1405 if( mpShape ) 1406 if( SdrObject* pObj = mpShape->GetSdrObject() ) 1407 return ScDrawLayer::GetMacroInfo( pObj, bCreate ); 1408 return 0; 1409 } 1410 1411 public: 1412 ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape ) 1413 { 1414 } 1415 1416 // XNameReplace 1417 virtual void SAL_CALL replaceByName( const rtl::OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 1418 { 1419 if ( !hasByName( aName ) ) 1420 throw container::NoSuchElementException(); 1421 uno::Sequence< beans::PropertyValue > aProperties; 1422 aElement >>= aProperties; 1423 const beans::PropertyValue* pProperties = aProperties.getConstArray(); 1424 const sal_Int32 nCount = aProperties.getLength(); 1425 sal_Int32 nIndex; 1426 bool isEventType = false; 1427 for( nIndex = 0; nIndex < nCount; nIndex++, pProperties++ ) 1428 { 1429 if ( pProperties->Name.equals( SC_EVENTACC_EVENTTYPE ) ) 1430 { 1431 isEventType = true; 1432 continue; 1433 } 1434 #ifdef ISSUE66550_HLINK_FOR_SHAPES 1435 if ( isEventType && ((pProperties->Name == SC_EVENTACC_SCRIPT) || (pProperties->Name == SC_EVENTACC_URL)) ) 1436 #else 1437 if ( isEventType && (pProperties->Name == SC_EVENTACC_SCRIPT) ) 1438 #endif 1439 { 1440 rtl::OUString sValue; 1441 if ( pProperties->Value >>= sValue ) 1442 { 1443 ScMacroInfo* pInfo = getInfo( sal_True ); 1444 DBG_ASSERT( pInfo, "shape macro info could not be created!" ); 1445 if ( !pInfo ) 1446 break; 1447 if ( pProperties->Name == SC_EVENTACC_SCRIPT ) 1448 pInfo->SetMacro( sValue ); 1449 #ifdef ISSUE66550_HLINK_FOR_SHAPES 1450 else 1451 pInfo->SetHlink( sValue ); 1452 #endif 1453 } 1454 } 1455 } 1456 } 1457 1458 // XNameAccess 1459 virtual uno::Any SAL_CALL getByName( const rtl::OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 1460 { 1461 uno::Sequence< beans::PropertyValue > aProperties; 1462 ScMacroInfo* pInfo = getInfo(); 1463 1464 if ( aName == SC_EVENTACC_ONCLICK ) 1465 { 1466 if ( pInfo && (pInfo->GetMacro().getLength() > 0) ) 1467 { 1468 aProperties.realloc( 2 ); 1469 aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE; 1470 aProperties[ 0 ].Value <<= SC_EVENTACC_SCRIPT; 1471 aProperties[ 1 ].Name = SC_EVENTACC_SCRIPT; 1472 aProperties[ 1 ].Value <<= pInfo->GetMacro(); 1473 } 1474 } 1475 #ifdef ISSUE66550_HLINK_FOR_SHAPES 1476 else if( aName == SC_EVENTACC_ONACTION ) 1477 { 1478 if ( pInfo && (pInfo->GetHlink().getLength() > 0) ) 1479 { 1480 aProperties.realloc( 2 ); 1481 aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE; 1482 aProperties[ 0 ].Value <<= SC_EVENTACC_ACTION; 1483 aProperties[ 1 ].Name = SC_EVENTACC_URL; 1484 aProperties[ 1 ].Value <<= pInfo->GetHlink(); 1485 } 1486 } 1487 #endif 1488 else 1489 { 1490 throw container::NoSuchElementException(); 1491 } 1492 1493 return uno::Any( aProperties ); 1494 } 1495 1496 virtual uno::Sequence< rtl::OUString > SAL_CALL getElementNames() throw(uno::RuntimeException) 1497 { 1498 #ifdef ISSUE66550_HLINK_FOR_SHAPES 1499 uno::Sequence< rtl::OUString > aSeq( 2 ); 1500 #else 1501 uno::Sequence< rtl::OUString > aSeq( 1 ); 1502 #endif 1503 aSeq[ 0 ] = SC_EVENTACC_ONCLICK; 1504 #ifdef ISSUE66550_HLINK_FOR_SHAPES 1505 aSeq[ 1 ] = SC_EVENTACC_ONACTION; 1506 #endif 1507 return aSeq; 1508 } 1509 1510 virtual sal_Bool SAL_CALL hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException) 1511 { 1512 #ifdef ISSUE66550_HLINK_FOR_SHAPES 1513 return (aName == SC_EVENTACC_ONCLICK) || (aName == SC_EVENTACC_ONACTION); 1514 #else 1515 return aName == SC_EVENTACC_ONCLICK; 1516 #endif 1517 } 1518 1519 // XElementAccess 1520 virtual uno::Type SAL_CALL getElementType() throw(uno::RuntimeException) 1521 { 1522 return *SEQTYPE(::getCppuType((const uno::Sequence< beans::PropertyValue >*)0)); 1523 } 1524 1525 virtual sal_Bool SAL_CALL hasElements() throw(uno::RuntimeException) 1526 { 1527 // elements are always present (but contained property sequences may be empty) 1528 return sal_True; 1529 } 1530 }; 1531 1532 ::uno::Reference< container::XNameReplace > SAL_CALL 1533 ScShapeObj::getEvents( ) throw(uno::RuntimeException) 1534 { 1535 return new ShapeUnoEventAccessImpl( this ); 1536 } 1537 1538 ::rtl::OUString SAL_CALL ScShapeObj::getImplementationName( ) throw (uno::RuntimeException) 1539 { 1540 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sc.ScShapeObj" ) ); 1541 } 1542 1543 ::sal_Bool SAL_CALL ScShapeObj::supportsService( const ::rtl::OUString& _ServiceName ) throw (uno::RuntimeException) 1544 { 1545 uno::Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); 1546 for ( const ::rtl::OUString* pSupported = aSupported.getConstArray(); 1547 pSupported != aSupported.getConstArray() + aSupported.getLength(); 1548 ++pSupported 1549 ) 1550 if ( _ServiceName == *pSupported ) 1551 return sal_True; 1552 return sal_False; 1553 } 1554 1555 uno::Sequence< ::rtl::OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( ) throw (uno::RuntimeException) 1556 { 1557 uno::Reference<lang::XServiceInfo> xSI; 1558 if ( mxShapeAgg.is() ) 1559 mxShapeAgg->queryAggregation( lang::XServiceInfo::static_type() ) >>= xSI; 1560 1561 uno::Sequence< ::rtl::OUString > aSupported; 1562 if ( xSI.is() ) 1563 aSupported = xSI->getSupportedServiceNames(); 1564 1565 aSupported.realloc( aSupported.getLength() + 1 ); 1566 aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) ); 1567 1568 if( bIsNoteCaption ) 1569 { 1570 aSupported.realloc( aSupported.getLength() + 1 ); 1571 aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.CellAnnotationShape" ) ); 1572 } 1573 1574 return aSupported; 1575 } 1576