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