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