Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / unoobj / shapeuno.cxx
blob2b71b12f1be5732b9130e3f473d3e70960c5b355
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <comphelper/uno3.hxx>
22 #include <comphelper/stl_types.hxx>
23 #include <svtools/unoevent.hxx>
24 #include <svtools/unoimap.hxx>
25 #include <svx/svdobj.hxx>
26 #include <vcl/svapp.hxx>
27 #include <svx/unoshape.hxx>
28 #include <editeng/unofield.hxx>
29 #include <svx/shapepropertynotifier.hxx>
30 #include <toolkit/helper/convert.hxx>
31 #include <cppuhelper/implbase2.hxx>
33 #include <com/sun/star/drawing/XShape.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include "shapeuno.hxx"
37 #include "miscuno.hxx"
38 #include "cellsuno.hxx"
39 #include "textuno.hxx"
40 #include "fielduno.hxx"
41 #include "docsh.hxx"
42 #include "drwlayer.hxx"
43 #include "userdat.hxx"
44 #include "unonames.hxx"
46 using namespace ::com::sun::star;
48 //------------------------------------------------------------------------
50 DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence< sal_Int8 > *, ScShapeImplementationIdMap );
52 static ScShapeImplementationIdMap aImplementationIdMap;
54 static const SfxItemPropertyMapEntry* lcl_GetShapeMap()
56 static const SfxItemPropertyMapEntry aShapeMap_Impl[] =
58 {MAP_CHAR_LEN(SC_UNONAME_ANCHOR), 0, &getCppuType((uno::Reference<uno::XInterface>*)0), 0, 0 },
59 {MAP_CHAR_LEN(SC_UNONAME_HORIPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
60 {MAP_CHAR_LEN(SC_UNONAME_IMAGEMAP), 0, &getCppuType((uno::Reference<container::XIndexContainer>*)0), 0, 0 },
61 {MAP_CHAR_LEN(SC_UNONAME_VERTPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
62 {MAP_CHAR_LEN(SC_UNONAME_MOVEPROTECT), 0, &getCppuType((sal_Bool*)0), 0, 0 },
63 // #i66550 HLINK_FOR_SHAPES
64 {MAP_CHAR_LEN(SC_UNONAME_HYPERLINK), 0, &getCppuType((OUString*)0), 0, 0 },
65 {MAP_CHAR_LEN(SC_UNONAME_URL), 0, &getCppuType((OUString*)0), 0, 0 },
67 {0,0,0,0,0,0}
69 return aShapeMap_Impl;
72 const SvEventDescription* ScShapeObj::GetSupportedMacroItems()
74 static const SvEventDescription aMacroDescriptionsImpl[] =
76 { 0, NULL }
78 return aMacroDescriptionsImpl;
80 // #i66550 HLINK_FOR_SHAPES
81 ScMacroInfo* ScShapeObj_getShapeHyperMacroInfo( ScShapeObj* pShape, sal_Bool bCreate = false )
83 if( pShape )
84 if( SdrObject* pObj = pShape->GetSdrObject() )
85 return ScDrawLayer::GetMacroInfo( pObj, bCreate );
86 return 0;
89 //------------------------------------------------------------------------
91 namespace
93 void lcl_initializeNotifier( SdrObject& _rSdrObj, ::cppu::OWeakObject& _rShape )
95 ::svx::PPropertyValueProvider pProvider( new ::svx::PropertyValueProvider( _rShape, "Anchor" ) );
96 _rSdrObj.getShapePropertyChangeNotifier().registerProvider( ::svx::eSpreadsheetAnchor, pProvider );
100 //------------------------------------------------------------------------
102 ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) :
103 pShapePropertySet(NULL),
104 pShapePropertyState(NULL),
105 pImplementationId(NULL),
106 bIsTextShape(false),
107 bIsNoteCaption(false),
108 bInitializedNotifier(false)
110 comphelper::increment( m_refCount );
113 mxShapeAgg = uno::Reference<uno::XAggregation>( xShape, uno::UNO_QUERY );
114 // extra block to force deletion of the temporary before setDelegator
117 if (mxShapeAgg.is())
119 xShape = NULL; // during setDelegator, mxShapeAgg must be the only ref
121 mxShapeAgg->setDelegator( (cppu::OWeakObject*)this );
123 xShape.set(uno::Reference<drawing::XShape>( mxShapeAgg, uno::UNO_QUERY ));
125 bIsTextShape = ( SvxUnoTextBase::getImplementation( mxShapeAgg ) != NULL );
129 SdrObject* pObj = GetSdrObject();
130 if ( pObj )
132 bIsNoteCaption = ScDrawLayer::IsNoteCaption( pObj );
133 lcl_initializeNotifier( *pObj, *this );
134 bInitializedNotifier = true;
138 comphelper::decrement( m_refCount );
141 ScShapeObj::~ScShapeObj()
143 // if (mxShapeAgg.is())
144 // mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>());
147 // XInterface
149 uno::Any SAL_CALL ScShapeObj::queryInterface( const uno::Type& rType )
150 throw(uno::RuntimeException)
152 uno::Any aRet = ScShapeObj_Base::queryInterface( rType );
154 if ( !aRet.hasValue() && bIsTextShape )
155 aRet = ScShapeObj_TextBase::queryInterface( rType );
157 if ( !aRet.hasValue() && bIsNoteCaption )
158 aRet = ScShapeObj_ChildBase::queryInterface( rType );
160 if ( !aRet.hasValue() && mxShapeAgg.is() )
161 aRet = mxShapeAgg->queryAggregation( rType );
163 return aRet;
166 void SAL_CALL ScShapeObj::acquire() throw()
168 OWeakObject::acquire();
171 void SAL_CALL ScShapeObj::release() throw()
173 OWeakObject::release();
176 void ScShapeObj::GetShapePropertySet()
178 // #i61908# Store the result of queryAggregation in a member.
179 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
181 if (!pShapePropertySet)
183 uno::Reference<beans::XPropertySet> xProp;
184 if ( mxShapeAgg.is() )
185 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertySet>*) 0) ) >>= xProp;
186 pShapePropertySet = xProp.get();
190 void ScShapeObj::GetShapePropertyState()
192 // #i61908# Store the result of queryAggregation in a member.
193 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
195 if (!pShapePropertyState)
197 uno::Reference<beans::XPropertyState> xState;
198 if ( mxShapeAgg.is() )
199 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertyState>*) 0) ) >>= xState;
200 pShapePropertyState = xState.get();
204 static uno::Reference<lang::XComponent> lcl_GetComponent( const uno::Reference<uno::XAggregation>& xAgg )
206 uno::Reference<lang::XComponent> xRet;
207 if ( xAgg.is() )
208 xAgg->queryAggregation( getCppuType((uno::Reference<lang::XComponent>*) 0) ) >>= xRet;
209 return xRet;
212 static uno::Reference<text::XText> lcl_GetText( const uno::Reference<uno::XAggregation>& xAgg )
214 uno::Reference<text::XText> xRet;
215 if ( xAgg.is() )
216 xAgg->queryAggregation( getCppuType((uno::Reference<text::XText>*) 0) ) >>= xRet;
217 return xRet;
220 static uno::Reference<text::XSimpleText> lcl_GetSimpleText( const uno::Reference<uno::XAggregation>& xAgg )
222 uno::Reference<text::XSimpleText> xRet;
223 if ( xAgg.is() )
224 xAgg->queryAggregation( getCppuType((uno::Reference<text::XSimpleText>*) 0) ) >>= xRet;
225 return xRet;
228 static uno::Reference<text::XTextRange> lcl_GetTextRange( const uno::Reference<uno::XAggregation>& xAgg )
230 uno::Reference<text::XTextRange> xRet;
231 if ( xAgg.is() )
232 xAgg->queryAggregation( getCppuType((uno::Reference<text::XTextRange>*) 0) ) >>= xRet;
233 return xRet;
236 // XPropertySet
238 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScShapeObj::getPropertySetInfo()
239 throw(uno::RuntimeException)
241 SolarMutexGuard aGuard;
243 // #i61527# cache property set info for this object
244 if ( !mxPropSetInfo.is() )
246 // mix own and aggregated properties:
247 GetShapePropertySet();
248 if (pShapePropertySet)
250 uno::Reference<beans::XPropertySetInfo> xAggInfo(pShapePropertySet->getPropertySetInfo());
251 const uno::Sequence<beans::Property> aPropSeq(xAggInfo->getProperties());
252 mxPropSetInfo.set(new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), aPropSeq ));
255 return mxPropSetInfo;
258 static sal_Bool lcl_GetPageNum( SdrPage* pPage, SdrModel& rModel, SCTAB& rNum )
260 sal_uInt16 nCount = rModel.GetPageCount();
261 for (sal_uInt16 i=0; i<nCount; i++)
262 if ( rModel.GetPage(i) == pPage )
264 rNum = static_cast<SCTAB>(i);
265 return sal_True;
268 return false;
271 static sal_Bool lcl_GetCaptionPoint( uno::Reference< drawing::XShape >& xShape, awt::Point& rCaptionPoint )
273 sal_Bool bReturn = false;
274 OUString sType(xShape->getShapeType());
275 sal_Bool bCaptionShape( sType == "com.sun.star.drawing.CaptionShape" );
276 if (bCaptionShape)
278 uno::Reference < beans::XPropertySet > xShapeProp (xShape, uno::UNO_QUERY);
279 if (xShapeProp.is())
281 xShapeProp->getPropertyValue("CaptionPoint") >>= rCaptionPoint;
282 bReturn = sal_True;
285 return bReturn;
288 static ScRange lcl_GetAnchorCell( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab,
289 awt::Point& rUnoPoint, awt::Size& rUnoSize, awt::Point& rCaptionPoint )
291 ScRange aReturn;
292 rUnoPoint = xShape->getPosition();
293 sal_Bool bCaptionShape(lcl_GetCaptionPoint(xShape, rCaptionPoint));
294 if (pDoc->IsNegativePage(nTab))
296 rUnoSize = xShape->getSize();
297 rUnoPoint.X += rUnoSize.Width; // the right top point is base
298 if (bCaptionShape)
300 if (rCaptionPoint.X > 0 && rCaptionPoint.X > rUnoSize.Width)
301 rUnoPoint.X += rCaptionPoint.X - rUnoSize.Width;
302 if (rCaptionPoint.Y < 0)
303 rUnoPoint.Y += rCaptionPoint.Y;
305 aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
307 else
309 if (bCaptionShape)
311 if (rCaptionPoint.X < 0)
312 rUnoPoint.X += rCaptionPoint.X;
313 if (rCaptionPoint.Y < 0)
314 rUnoPoint.Y += rCaptionPoint.Y;
316 aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
319 return aReturn;
322 static awt::Point lcl_GetRelativePos( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab, ScRange& rRange,
323 awt::Size& rUnoSize, awt::Point& rCaptionPoint)
325 awt::Point aUnoPoint;
326 rRange = lcl_GetAnchorCell(xShape, pDoc, nTab, aUnoPoint, rUnoSize, rCaptionPoint);
327 Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
328 Point aPoint = pDoc->IsNegativePage(nTab) ? aRect.TopRight() : aRect.TopLeft();
329 aUnoPoint.X -= aPoint.X();
330 aUnoPoint.Y -= aPoint.Y();
331 return aUnoPoint;
334 void SAL_CALL ScShapeObj::setPropertyValue(
335 const OUString& aPropertyName, const uno::Any& aValue )
336 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
337 lang::IllegalArgumentException, lang::WrappedTargetException,
338 uno::RuntimeException)
340 SolarMutexGuard aGuard;
341 OUString aNameString(aPropertyName);
343 if ( aNameString.equalsAscii( SC_UNONAME_ANCHOR ) )
345 uno::Reference<sheet::XCellRangeAddressable> xRangeAdd(aValue, uno::UNO_QUERY);
346 if (xRangeAdd.is())
348 SdrObject *pObj = GetSdrObject();
349 if (pObj)
351 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
352 SdrPage* pPage = pObj->GetPage();
353 if ( pModel && pPage )
355 ScDocument* pDoc = pModel->GetDocument();
356 if ( pDoc )
358 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
359 if ( pObjSh && pObjSh->ISA(ScDocShell) )
361 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
363 SCTAB nTab = 0;
364 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
366 table::CellRangeAddress aAddress = xRangeAdd->getRangeAddress();
367 if (nTab == aAddress.Sheet)
369 Rectangle aRect(pDoc->GetMMRect( static_cast<SCCOL>(aAddress.StartColumn), static_cast<SCROW>(aAddress.StartRow),
370 static_cast<SCCOL>(aAddress.EndColumn), static_cast<SCROW>(aAddress.EndRow), aAddress.Sheet ));
371 awt::Point aRelPoint;
372 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
373 if (xShape.is())
375 Point aPoint;
376 Point aEndPoint;
377 if (pDoc->IsNegativePage(nTab))
379 aPoint = aRect.TopRight();
380 aEndPoint = aRect.BottomLeft();
382 else
384 aPoint = aRect.TopLeft();
385 aEndPoint = aRect.BottomRight();
387 awt::Size aUnoSize;
388 awt::Point aCaptionPoint;
389 ScRange aRange;
390 aRelPoint = lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint );
391 awt::Point aUnoPoint(aRelPoint);
393 aUnoPoint.X += aPoint.X();
394 aUnoPoint.Y += aPoint.Y();
396 if ( aUnoPoint.Y > aEndPoint.Y() )
397 aUnoPoint.Y = aEndPoint.Y() - 2;
398 if (pDoc->IsNegativePage(nTab))
400 if ( aUnoPoint.X < aEndPoint.X() )
401 aUnoPoint.X = aEndPoint.X() + 2;
402 aUnoPoint.X -= aUnoSize.Width;
403 // remove difference to caption point
404 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
405 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
407 else
409 if ( aUnoPoint.X > aEndPoint.X() )
410 aUnoPoint.X = aEndPoint.X() - 2;
411 if (aCaptionPoint.X < 0)
412 aUnoPoint.X -= aCaptionPoint.X;
414 if (aCaptionPoint.Y < 0)
415 aUnoPoint.Y -= aCaptionPoint.Y;
417 xShape->setPosition(aUnoPoint);
418 pDocSh->SetModified();
421 if (aAddress.StartRow != aAddress.EndRow) //should be a Spreadsheet
423 OSL_ENSURE(aAddress.StartRow == 0 && aAddress.EndRow == MAXROW &&
424 aAddress.StartColumn == 0 && aAddress.EndColumn == MAXCOL, "here should be a XSpreadsheet");
425 ScDrawLayer::SetPageAnchored(*pObj);
427 else
429 OSL_ENSURE(aAddress.StartRow == aAddress.EndRow &&
430 aAddress.StartColumn == aAddress.EndColumn, "here should be a XCell");
431 ScDrawObjData aAnchor;
432 aAnchor.maStart = ScAddress(aAddress.StartColumn, aAddress.StartRow, aAddress.Sheet);
433 aAnchor.maStartOffset = Point(aRelPoint.X, aRelPoint.Y);
434 //Uno sets the Anchor in terms of the unorotated shape, not much we can do
435 //about that since uno also displays the shape geometry in terms of the unrotated
436 //shape. #TODO think about changing the anchoring behaviour here too
437 //Currently we've only got a start anchor, not an end-anchor, so generate that now
438 ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, aAnchor, *pDoc, aAddress.Sheet);
439 ScDrawLayer::SetCellAnchored(*pObj, aAnchor);
448 else
449 throw lang::IllegalArgumentException("only XCell or XSpreadsheet objects allowed", static_cast<cppu::OWeakObject*>(this), 0);
451 else if ( aNameString.equalsAscii( SC_UNONAME_IMAGEMAP ) )
453 SdrObject* pObj = GetSdrObject();
454 if ( pObj )
456 ImageMap aImageMap;
457 uno::Reference< uno::XInterface > xImageMapInt(aValue, uno::UNO_QUERY);
459 if( !xImageMapInt.is() || !SvUnoImageMap_fillImageMap( xImageMapInt, aImageMap ) )
460 throw lang::IllegalArgumentException();
462 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
463 if( pIMapInfo )
465 // replace existing image map
466 pIMapInfo->SetImageMap( aImageMap );
468 else
470 // insert new user data with image map
471 pObj->AppendUserData(new ScIMapInfo(aImageMap) );
475 else if ( aNameString.equalsAscii( SC_UNONAME_HORIPOS ) )
477 sal_Int32 nPos = 0;
478 if (aValue >>= nPos)
480 SdrObject *pObj = GetSdrObject();
481 if (pObj)
483 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
484 SdrPage* pPage = pObj->GetPage();
485 if ( pModel && pPage )
487 SCTAB nTab = 0;
488 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
490 ScDocument* pDoc = pModel->GetDocument();
491 if ( pDoc )
493 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
494 if ( pObjSh && pObjSh->ISA(ScDocShell) )
496 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
497 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
498 if (xShape.is())
500 if (ScDrawLayer::GetAnchorType(*pObj) == SCA_PAGE)
502 awt::Point aPoint(xShape->getPosition());
503 awt::Size aSize(xShape->getSize());
504 awt::Point aCaptionPoint;
505 if (pDoc->IsNegativePage(nTab))
507 nPos *= -1;
508 nPos -= aSize.Width;
510 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
512 if (pDoc->IsNegativePage(nTab))
514 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aSize.Width)
515 nPos -= aCaptionPoint.X - aSize.Width;
517 else
519 if (aCaptionPoint.X < 0)
520 nPos -= aCaptionPoint.X;
523 aPoint.X = nPos;
524 xShape->setPosition(aPoint);
525 pDocSh->SetModified();
527 else if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL)
529 awt::Size aUnoSize;
530 awt::Point aCaptionPoint;
531 ScRange aRange;
532 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
533 Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
534 if (pDoc->IsNegativePage(nTab))
536 aUnoPoint.X = -nPos;
537 Point aPoint(aRect.TopRight());
538 Point aEndPoint(aRect.BottomLeft());
539 aUnoPoint.X += aPoint.X();
540 if (aUnoPoint.X < aEndPoint.X())
541 aUnoPoint.X = aEndPoint.X() + 2;
542 aUnoPoint.X -= aUnoSize.Width;
543 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
544 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
546 else
548 aUnoPoint.X = nPos;
549 Point aPoint(aRect.TopLeft());
550 Point aEndPoint(aRect.BottomRight());
551 aUnoPoint.X += aPoint.X();
552 if (aUnoPoint.X > aEndPoint.X())
553 aUnoPoint.X = aEndPoint.X() - 2;
554 if (aCaptionPoint.X < 0)
555 aUnoPoint.X -= aCaptionPoint.X;
557 aUnoPoint.Y = xShape->getPosition().Y;
558 xShape->setPosition(aUnoPoint);
559 pDocSh->SetModified();
561 else
563 OSL_FAIL("unknown anchor type");
573 else if ( aNameString.equalsAscii( SC_UNONAME_VERTPOS ) )
575 sal_Int32 nPos = 0;
576 if (aValue >>= nPos)
578 SdrObject *pObj = GetSdrObject();
579 if (pObj)
581 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
582 SdrPage* pPage = pObj->GetPage();
583 if ( pModel && pPage )
585 SCTAB nTab = 0;
586 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
588 ScDocument* pDoc = pModel->GetDocument();
589 if ( pDoc )
591 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
592 if ( pObjSh && pObjSh->ISA(ScDocShell) )
594 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
595 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
596 if (xShape.is())
598 if (ScDrawLayer::GetAnchorType(*pObj) == SCA_PAGE)
600 awt::Point aPoint = xShape->getPosition();
601 awt::Point aCaptionPoint;
602 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
604 if (aCaptionPoint.Y < 0)
605 nPos -= aCaptionPoint.Y;
607 aPoint.Y = nPos;
608 xShape->setPosition(aPoint);
609 pDocSh->SetModified();
611 else if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL)
613 awt::Size aUnoSize;
614 awt::Point aCaptionPoint;
615 ScRange aRange;
616 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
617 Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
618 Point aPoint(aRect.TopRight());
619 Point aEndPoint(aRect.BottomLeft());
620 aUnoPoint.Y = nPos;
621 aUnoPoint.Y += aPoint.Y();
622 if (aUnoPoint.Y > aEndPoint.Y())
623 aUnoPoint.Y = aEndPoint.Y() - 2;
624 if (aCaptionPoint.Y < 0)
625 aUnoPoint.Y -= aCaptionPoint.Y;
626 aUnoPoint.X = xShape->getPosition().X;
627 xShape->setPosition(aUnoPoint);
628 pDocSh->SetModified();
630 else
632 OSL_FAIL("unknown anchor type");
642 else if ( aNameString.equalsAscii( SC_UNONAME_HYPERLINK ) ||
643 aNameString.equalsAscii( SC_UNONAME_URL) )
645 OUString sHlink;
646 ScMacroInfo* pInfo = ScShapeObj_getShapeHyperMacroInfo(this, true);
647 if ( ( aValue >>= sHlink ) && pInfo )
648 pInfo->SetHlink( sHlink );
650 else if ( aNameString.equalsAscii( SC_UNONAME_MOVEPROTECT ) )
652 if( SdrObject* pObj = this->GetSdrObject() )
654 sal_Bool aProt = false;
655 if( aValue >>= aProt )
656 pObj->SetMoveProtect( aProt );
659 else
661 GetShapePropertySet();
662 if (pShapePropertySet)
663 pShapePropertySet->setPropertyValue( aPropertyName, aValue );
667 uno::Any SAL_CALL ScShapeObj::getPropertyValue( const OUString& aPropertyName )
668 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
669 uno::RuntimeException)
671 SolarMutexGuard aGuard;
672 OUString aNameString = aPropertyName;
674 uno::Any aAny;
675 if ( aNameString.equalsAscii( SC_UNONAME_ANCHOR ) )
677 SdrObject *pObj = GetSdrObject();
678 if (pObj)
680 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
681 SdrPage* pPage = pObj->GetPage();
682 if ( pModel && pPage )
684 ScDocument* pDoc = pModel->GetDocument();
685 if ( pDoc )
687 SCTAB nTab = 0;
688 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
690 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
691 if ( pObjSh && pObjSh->ISA(ScDocShell) )
693 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
694 uno::Reference< uno::XInterface > xAnchor;
695 if (ScDrawObjData *pAnchor = ScDrawLayer::GetObjDataTab(pObj, nTab))
696 xAnchor.set(static_cast<cppu::OWeakObject*>(new ScCellObj( pDocSh, pAnchor->maStart)));
697 else
698 xAnchor.set(static_cast<cppu::OWeakObject*>(new ScTableSheetObj( pDocSh, nTab )));
699 aAny <<= xAnchor;
706 else if ( aNameString.equalsAscii( SC_UNONAME_IMAGEMAP ) )
708 uno::Reference< uno::XInterface > xImageMap;
709 SdrObject* pObj = GetSdrObject();
710 if ( pObj )
712 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(GetSdrObject());
713 if( pIMapInfo )
715 const ImageMap& rIMap = pIMapInfo->GetImageMap();
716 xImageMap.set(SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() ));
718 else
719 xImageMap = SvUnoImageMap_createInstance( GetSupportedMacroItems() );
721 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
723 else if ( aNameString.equalsAscii( SC_UNONAME_HORIPOS ) )
725 SdrObject *pObj = GetSdrObject();
726 if (pObj)
728 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
729 SdrPage* pPage = pObj->GetPage();
730 if ( pModel && pPage )
732 ScDocument* pDoc = pModel->GetDocument();
733 if ( pDoc )
735 SCTAB nTab = 0;
736 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
738 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
739 if (xShape.is())
741 if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL)
743 awt::Size aUnoSize;
744 awt::Point aCaptionPoint;
745 ScRange aRange;
746 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
747 if (pDoc->IsNegativePage(nTab))
748 aUnoPoint.X *= -1;
749 aAny <<= aUnoPoint.X;
751 else
753 awt::Point aCaptionPoint;
754 awt::Point aUnoPoint(xShape->getPosition());
755 awt::Size aUnoSize(xShape->getSize());
756 if (pDoc->IsNegativePage(nTab))
758 aUnoPoint.X *= -1;
759 aUnoPoint.X -= aUnoSize.Width;
761 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
763 if (pDoc->IsNegativePage(nTab))
765 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
766 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
768 else
770 if (aCaptionPoint.X < 0)
771 aUnoPoint.X += aCaptionPoint.X;
774 aAny <<= aUnoPoint.X;
782 else if ( aNameString.equalsAscii( SC_UNONAME_VERTPOS ) )
784 SdrObject *pObj = GetSdrObject();
785 if (pObj)
787 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
788 SdrPage* pPage = pObj->GetPage();
789 if ( pModel && pPage )
791 ScDocument* pDoc = pModel->GetDocument();
792 if ( pDoc )
794 SCTAB nTab = 0;
795 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
797 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
798 if (xShape.is())
800 uno::Reference< uno::XInterface > xAnchor;
801 if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL)
803 awt::Size aUnoSize;
804 awt::Point aCaptionPoint;
805 ScRange aRange;
806 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
808 aAny <<= aUnoPoint.Y;
810 else
812 awt::Point aUnoPoint(xShape->getPosition());
813 awt::Point aCaptionPoint;
814 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
816 if (aCaptionPoint.Y < 0)
817 aUnoPoint.Y += aCaptionPoint.Y;
819 aAny <<= aUnoPoint.Y;
827 else if ( aNameString.equalsAscii( SC_UNONAME_HYPERLINK ) ||
828 aNameString.equalsAscii( SC_UNONAME_URL ) )
830 OUString sHlink;
831 if ( ScMacroInfo* pInfo = ScShapeObj_getShapeHyperMacroInfo(this) )
832 sHlink = pInfo->GetHlink();
833 aAny <<= sHlink;
835 else if ( aNameString.equalsAscii( SC_UNONAME_MOVEPROTECT ) )
837 sal_Bool aProt = false;
838 if ( SdrObject* pObj = this->GetSdrObject() )
839 aProt = pObj->IsMoveProtect();
840 aAny <<= aProt;
842 else
844 if(!pShapePropertySet) //performance consideration
845 GetShapePropertySet();
846 if (pShapePropertySet)
847 aAny = pShapePropertySet->getPropertyValue( aPropertyName );
850 return aAny;
853 void SAL_CALL ScShapeObj::addPropertyChangeListener( const OUString& aPropertyName,
854 const uno::Reference<beans::XPropertyChangeListener>& aListener)
855 throw(beans::UnknownPropertyException,
856 lang::WrappedTargetException, uno::RuntimeException)
858 SolarMutexGuard aGuard;
860 GetShapePropertySet();
861 if (pShapePropertySet)
862 pShapePropertySet->addPropertyChangeListener( aPropertyName, aListener );
864 if ( !bInitializedNotifier )
866 // here's the latest chance to initialize the property notification at the SdrObject
867 // (in the ctor, where we also attempt to do this, we do not necessarily have
868 // and SdrObject, yet)
869 SdrObject* pObj = GetSdrObject();
870 OSL_ENSURE( pObj, "ScShapeObj::addPropertyChangeListener: no SdrObject -> no property change notification!" );
871 if ( pObj )
872 lcl_initializeNotifier( *pObj, *this );
873 bInitializedNotifier = true;
877 void SAL_CALL ScShapeObj::removePropertyChangeListener( const OUString& aPropertyName,
878 const uno::Reference<beans::XPropertyChangeListener>& aListener)
879 throw(beans::UnknownPropertyException,
880 lang::WrappedTargetException, uno::RuntimeException)
882 SolarMutexGuard aGuard;
884 GetShapePropertySet();
885 if (pShapePropertySet)
886 pShapePropertySet->removePropertyChangeListener( aPropertyName, aListener );
889 void SAL_CALL ScShapeObj::addVetoableChangeListener( const OUString& aPropertyName,
890 const uno::Reference<beans::XVetoableChangeListener>& aListener)
891 throw(beans::UnknownPropertyException,
892 lang::WrappedTargetException, uno::RuntimeException)
894 SolarMutexGuard aGuard;
896 GetShapePropertySet();
897 if (pShapePropertySet)
898 pShapePropertySet->addVetoableChangeListener( aPropertyName, aListener );
901 void SAL_CALL ScShapeObj::removeVetoableChangeListener( const OUString& aPropertyName,
902 const uno::Reference<beans::XVetoableChangeListener>& aListener)
903 throw(beans::UnknownPropertyException,
904 lang::WrappedTargetException, uno::RuntimeException)
906 SolarMutexGuard aGuard;
908 GetShapePropertySet();
909 if (pShapePropertySet)
910 pShapePropertySet->removeVetoableChangeListener( aPropertyName, aListener );
913 // XPropertyState
915 beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const OUString& aPropertyName )
916 throw(beans::UnknownPropertyException, uno::RuntimeException)
918 SolarMutexGuard aGuard;
919 OUString aNameString(aPropertyName);
921 beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
922 if ( aNameString.equalsAscii( SC_UNONAME_IMAGEMAP ) )
924 // ImageMap is always "direct"
926 else if ( aNameString.equalsAscii( SC_UNONAME_ANCHOR ) )
928 // Anchor is always "direct"
930 else if ( aNameString.equalsAscii( SC_UNONAME_HORIPOS ) )
932 // HoriPos is always "direct"
934 else if ( aNameString.equalsAscii( SC_UNONAME_VERTPOS ) )
936 // VertPos is always "direct"
938 else
940 GetShapePropertyState();
941 if (pShapePropertyState)
942 eRet = pShapePropertyState->getPropertyState( aPropertyName );
945 return eRet;
948 uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates(
949 const uno::Sequence<OUString>& aPropertyNames )
950 throw(beans::UnknownPropertyException, uno::RuntimeException)
952 SolarMutexGuard aGuard;
954 // simple loop to get own and aggregated states
956 const OUString* pNames = aPropertyNames.getConstArray();
957 uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
958 beans::PropertyState* pStates = aRet.getArray();
959 for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
960 pStates[i] = getPropertyState(pNames[i]);
961 return aRet;
964 void SAL_CALL ScShapeObj::setPropertyToDefault( const OUString& aPropertyName )
965 throw(beans::UnknownPropertyException, uno::RuntimeException)
967 SolarMutexGuard aGuard;
968 OUString aNameString(aPropertyName);
970 if ( aNameString.equalsAscii( SC_UNONAME_IMAGEMAP ) )
972 SdrObject* pObj = GetSdrObject();
973 if ( pObj )
975 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
976 if( pIMapInfo )
978 ImageMap aEmpty;
979 pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map
981 else
983 // nothing to do (no need to insert user data for an empty map)
987 else
989 GetShapePropertyState();
990 if (pShapePropertyState)
991 pShapePropertyState->setPropertyToDefault( aPropertyName );
995 uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const OUString& aPropertyName )
996 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
997 uno::RuntimeException)
999 SolarMutexGuard aGuard;
1000 OUString aNameString = aPropertyName;
1002 uno::Any aAny;
1003 if ( aNameString.equalsAscii( SC_UNONAME_IMAGEMAP ) )
1005 // default: empty ImageMap
1006 uno::Reference< uno::XInterface > xImageMap(SvUnoImageMap_createInstance( GetSupportedMacroItems() ));
1007 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
1009 else
1011 GetShapePropertyState();
1012 if (pShapePropertyState)
1013 aAny = pShapePropertyState->getPropertyDefault( aPropertyName );
1016 return aAny;
1019 // XTextContent
1021 void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& /* xTextRange */ )
1022 throw(lang::IllegalArgumentException, uno::RuntimeException)
1024 SolarMutexGuard aGuard;
1026 throw lang::IllegalArgumentException(); // anchor cannot be changed
1029 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor() throw(uno::RuntimeException)
1031 SolarMutexGuard aGuard;
1033 uno::Reference<text::XTextRange> xRet;
1035 SdrObject* pObj = GetSdrObject();
1036 if( pObj )
1038 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
1039 SdrPage* pPage = pObj->GetPage();
1040 if ( pModel )
1042 ScDocument* pDoc = pModel->GetDocument();
1043 if ( pDoc )
1045 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1046 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1048 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
1050 SCTAB nTab = 0;
1051 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
1053 Point aPos(pObj->GetCurrentBoundRect().TopLeft());
1054 ScRange aRange(pDoc->GetRange( nTab, Rectangle( aPos, aPos ) ));
1056 // anchor is always the cell
1058 xRet.set(new ScCellObj( pDocSh, aRange.aStart ));
1065 return xRet;
1068 // XComponent
1070 void SAL_CALL ScShapeObj::dispose() throw(uno::RuntimeException)
1072 SolarMutexGuard aGuard;
1074 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1075 if ( xAggComp.is() )
1076 xAggComp->dispose();
1079 void SAL_CALL ScShapeObj::addEventListener(
1080 const uno::Reference<lang::XEventListener>& xListener )
1081 throw(uno::RuntimeException)
1083 SolarMutexGuard aGuard;
1085 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1086 if ( xAggComp.is() )
1087 xAggComp->addEventListener(xListener);
1090 void SAL_CALL ScShapeObj::removeEventListener(
1091 const uno::Reference<lang::XEventListener>& xListener )
1092 throw(uno::RuntimeException)
1094 SolarMutexGuard aGuard;
1096 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1097 if ( xAggComp.is() )
1098 xAggComp->removeEventListener(xListener);
1101 // XText
1102 // (special handling for ScCellFieldObj)
1104 static void lcl_CopyOneProperty( beans::XPropertySet& rDest, beans::XPropertySet& rSource, const sal_Char* pName )
1106 OUString aNameStr(OUString::createFromAscii(pName));
1109 rDest.setPropertyValue( aNameStr, rSource.getPropertyValue( aNameStr ) );
1111 catch (uno::Exception&)
1113 OSL_FAIL("Exception in text field");
1117 void SAL_CALL ScShapeObj::insertTextContent( const uno::Reference<text::XTextRange>& xRange,
1118 const uno::Reference<text::XTextContent>& xContent,
1119 sal_Bool bAbsorb )
1120 throw(lang::IllegalArgumentException, uno::RuntimeException)
1122 SolarMutexGuard aGuard;
1124 uno::Reference<text::XTextContent> xEffContent;
1126 ScEditFieldObj* pCellField = ScEditFieldObj::getImplementation( xContent );
1127 if ( pCellField )
1129 // createInstance("TextField.URL") from the document creates a ScCellFieldObj.
1130 // To insert it into drawing text, a SvxUnoTextField is needed instead.
1131 // The ScCellFieldObj object is left in non-inserted state.
1133 SvxUnoTextField* pDrawField = new SvxUnoTextField( text::textfield::Type::URL );
1134 xEffContent.set(pDrawField);
1135 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL );
1136 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR );
1137 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET );
1139 else
1140 xEffContent.set(xContent);
1142 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1143 if ( xAggText.is() )
1144 xAggText->insertTextContent( xRange, xEffContent, bAbsorb );
1147 void SAL_CALL ScShapeObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
1148 throw(container::NoSuchElementException, uno::RuntimeException)
1150 SolarMutexGuard aGuard;
1152 // ScCellFieldObj can't be used here.
1154 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1155 if ( xAggText.is() )
1156 xAggText->removeTextContent( xContent );
1159 // XSimpleText (parent of XText)
1160 // Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object
1162 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursor()
1163 throw(uno::RuntimeException)
1165 SolarMutexGuard aGuard;
1167 if ( mxShapeAgg.is() )
1169 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1171 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
1172 if (pText)
1173 return new ScDrawTextCursor( this, *pText );
1176 return uno::Reference<text::XTextCursor>();
1179 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursorByRange(
1180 const uno::Reference<text::XTextRange>& aTextPosition )
1181 throw(uno::RuntimeException)
1183 SolarMutexGuard aGuard;
1185 if ( mxShapeAgg.is() && aTextPosition.is() )
1187 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1189 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
1190 SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
1191 if ( pText && pRange )
1193 SvxUnoTextCursor* pCursor = new ScDrawTextCursor( this, *pText );
1194 uno::Reference<text::XTextCursor> xCursor( pCursor );
1195 pCursor->SetSelection( pRange->GetSelection() );
1196 return xCursor;
1200 return uno::Reference<text::XTextCursor>();
1203 void SAL_CALL ScShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange,
1204 const OUString& aString, sal_Bool bAbsorb )
1205 throw(uno::RuntimeException)
1207 SolarMutexGuard aGuard;
1209 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1210 if ( xAggSimpleText.is() )
1211 xAggSimpleText->insertString( xRange, aString, bAbsorb );
1212 else
1213 throw uno::RuntimeException();
1216 void SAL_CALL ScShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
1217 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
1218 throw(lang::IllegalArgumentException, uno::RuntimeException)
1220 SolarMutexGuard aGuard;
1222 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1223 if ( xAggSimpleText.is() )
1224 xAggSimpleText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
1225 else
1226 throw uno::RuntimeException();
1229 // XTextRange
1230 // (parent of XSimpleText)
1232 uno::Reference<text::XText> SAL_CALL ScShapeObj::getText() throw(uno::RuntimeException)
1234 SolarMutexGuard aGuard;
1235 return this;
1238 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart() throw(uno::RuntimeException)
1240 SolarMutexGuard aGuard;
1242 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1243 if ( xAggTextRange.is() )
1244 return xAggTextRange->getStart();
1245 else
1246 throw uno::RuntimeException();
1248 // return uno::Reference<text::XTextRange>();
1251 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getEnd() throw(uno::RuntimeException)
1253 SolarMutexGuard aGuard;
1255 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1256 if ( xAggTextRange.is() )
1257 return xAggTextRange->getEnd();
1258 else
1259 throw uno::RuntimeException();
1261 // return uno::Reference<text::XTextRange>();
1264 OUString SAL_CALL ScShapeObj::getString() throw(uno::RuntimeException)
1266 SolarMutexGuard aGuard;
1268 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1269 if ( xAggTextRange.is() )
1270 return xAggTextRange->getString();
1271 else
1272 throw uno::RuntimeException();
1274 // return OUString();
1277 void SAL_CALL ScShapeObj::setString( const OUString& aText ) throw(uno::RuntimeException)
1279 SolarMutexGuard aGuard;
1281 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1282 if ( xAggTextRange.is() )
1283 xAggTextRange->setString( aText );
1284 else
1285 throw uno::RuntimeException();
1288 // XChild
1290 uno::Reference< uno::XInterface > SAL_CALL ScShapeObj::getParent() throw (uno::RuntimeException)
1292 SolarMutexGuard aGuard;
1294 // receive cell position from caption object (parent of a note caption is the note cell)
1295 SdrObject* pObj = GetSdrObject();
1296 if( pObj )
1298 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
1299 SdrPage* pPage = pObj->GetPage();
1300 if ( pModel )
1302 ScDocument* pDoc = pModel->GetDocument();
1303 if ( pDoc )
1305 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1306 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1308 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
1310 SCTAB nTab = 0;
1311 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
1313 const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab );
1314 if( pCaptData )
1315 return static_cast< ::cppu::OWeakObject* >( new ScCellObj( pDocSh, pCaptData->maStart ) );
1322 return 0;
1325 void SAL_CALL ScShapeObj::setParent( const uno::Reference< uno::XInterface >& ) throw (lang::NoSupportException, uno::RuntimeException)
1327 throw lang::NoSupportException();
1330 // XTypeProvider
1332 uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes() throw(uno::RuntimeException)
1334 uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() );
1336 uno::Sequence< uno::Type > aTextTypes;
1337 if ( bIsTextShape )
1338 aTextTypes = ScShapeObj_TextBase::getTypes();
1340 uno::Reference<lang::XTypeProvider> xBaseProvider;
1341 if ( mxShapeAgg.is() )
1342 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<lang::XTypeProvider>*) 0) ) >>= xBaseProvider;
1343 OSL_ENSURE( xBaseProvider.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" );
1345 uno::Sequence< uno::Type > aAggTypes;
1346 if( xBaseProvider.is() )
1347 aAggTypes = xBaseProvider->getTypes();
1349 return ::comphelper::concatSequences( aBaseTypes, aTextTypes, aAggTypes );
1352 uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId()
1353 throw(uno::RuntimeException)
1355 SolarMutexGuard aGuard;
1356 // do we need to compute the implementation id for this instance?
1357 if( !pImplementationId && mxShapeAgg.is())
1359 uno::Reference< drawing::XShape > xAggShape;
1360 mxShapeAgg->queryAggregation( ::getCppuType((uno::Reference< drawing::XShape >*)0) ) >>= xAggShape;
1362 if( xAggShape.is() )
1364 const OUString aShapeType( xAggShape->getShapeType() );
1365 // did we already compute an implementation id for the agregated shape type?
1366 ScShapeImplementationIdMap::iterator aIter( aImplementationIdMap.find(aShapeType ) );
1367 if( aIter == aImplementationIdMap.end() )
1369 // we need to create a new implementation id for this
1370 // note: this memory is not free'd until application exits
1371 // but since we have a fixed set of shapetypes and the
1372 // memory will be reused this is ok.
1373 pImplementationId = new uno::Sequence< sal_Int8 >( 16 );
1374 rtl_createUuid( (sal_uInt8 *) pImplementationId->getArray(), 0, sal_True );
1375 aImplementationIdMap[ aShapeType ] = pImplementationId;
1377 else
1379 // use the already computed implementation id
1380 pImplementationId = (*aIter).second;
1384 if( NULL == pImplementationId )
1386 OSL_FAIL( "Could not create an implementation id for a ScXShape!" );
1387 return uno::Sequence< sal_Int8 > ();
1389 else
1391 return *pImplementationId;
1395 SdrObject* ScShapeObj::GetSdrObject() const throw()
1397 if(mxShapeAgg.is())
1399 SvxShape* pShape = SvxShape::getImplementation( mxShapeAgg );
1400 if(pShape)
1401 return pShape->GetSdrObject();
1404 return NULL;
1407 #define SC_EVENTACC_ONCLICK OUString( "OnClick" )
1408 #define SC_EVENTACC_SCRIPT OUString( "Script" )
1409 #define SC_EVENTACC_EVENTTYPE OUString( "EventType" )
1411 typedef ::cppu::WeakImplHelper1< container::XNameReplace > ShapeUnoEventAcess_BASE;
1412 class ShapeUnoEventAccessImpl : public ShapeUnoEventAcess_BASE
1414 private:
1415 ScShapeObj* mpShape;
1417 ScMacroInfo* getInfo( sal_Bool bCreate = false )
1419 return ScShapeObj_getShapeHyperMacroInfo( mpShape, bCreate );
1422 public:
1423 ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
1427 // XNameReplace
1428 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
1430 if ( !hasByName( aName ) )
1431 throw container::NoSuchElementException();
1432 uno::Sequence< beans::PropertyValue > aProperties;
1433 aElement >>= aProperties;
1434 const beans::PropertyValue* pProperties = aProperties.getConstArray();
1435 const sal_Int32 nCount = aProperties.getLength();
1436 sal_Int32 nIndex;
1437 bool isEventType = false;
1438 for( nIndex = 0; nIndex < nCount; nIndex++, pProperties++ )
1440 if ( pProperties->Name.equals( SC_EVENTACC_EVENTTYPE ) )
1442 isEventType = true;
1443 continue;
1445 if ( isEventType && (pProperties->Name == SC_EVENTACC_SCRIPT) )
1447 OUString sValue;
1448 if ( pProperties->Value >>= sValue )
1450 ScMacroInfo* pInfo = getInfo( sal_True );
1451 OSL_ENSURE( pInfo, "shape macro info could not be created!" );
1452 if ( !pInfo )
1453 break;
1454 if ( pProperties->Name == SC_EVENTACC_SCRIPT )
1455 pInfo->SetMacro( sValue );
1456 else
1457 pInfo->SetHlink( sValue );
1463 // XNameAccess
1464 virtual uno::Any SAL_CALL getByName( const OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
1466 uno::Sequence< beans::PropertyValue > aProperties;
1467 ScMacroInfo* pInfo = getInfo();
1469 if ( aName == SC_EVENTACC_ONCLICK )
1471 if ( pInfo && !pInfo->GetMacro().isEmpty() )
1473 aProperties.realloc( 2 );
1474 aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
1475 aProperties[ 0 ].Value <<= SC_EVENTACC_SCRIPT;
1476 aProperties[ 1 ].Name = SC_EVENTACC_SCRIPT;
1477 aProperties[ 1 ].Value <<= pInfo->GetMacro();
1480 else
1482 throw container::NoSuchElementException();
1485 return uno::Any( aProperties );
1488 virtual uno::Sequence< OUString > SAL_CALL getElementNames() throw(uno::RuntimeException)
1490 uno::Sequence< OUString > aSeq( 1 );
1491 aSeq[ 0 ] = SC_EVENTACC_ONCLICK;
1492 return aSeq;
1495 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) throw(uno::RuntimeException)
1497 return aName == SC_EVENTACC_ONCLICK;
1500 // XElementAccess
1501 virtual uno::Type SAL_CALL getElementType() throw(uno::RuntimeException)
1503 return *SEQTYPE(::getCppuType((const uno::Sequence< beans::PropertyValue >*)0));
1506 virtual sal_Bool SAL_CALL hasElements() throw(uno::RuntimeException)
1508 // elements are always present (but contained property sequences may be empty)
1509 return sal_True;
1513 ::uno::Reference< container::XNameReplace > SAL_CALL
1514 ScShapeObj::getEvents( ) throw(uno::RuntimeException)
1516 return new ShapeUnoEventAccessImpl( this );
1519 OUString SAL_CALL ScShapeObj::getImplementationName( ) throw (uno::RuntimeException)
1521 return OUString( "com.sun.star.comp.sc.ScShapeObj" );
1524 ::sal_Bool SAL_CALL ScShapeObj::supportsService( const OUString& _ServiceName ) throw (uno::RuntimeException)
1526 uno::Sequence< OUString > aSupported( getSupportedServiceNames() );
1527 for ( const OUString* pSupported = aSupported.getConstArray();
1528 pSupported != aSupported.getConstArray() + aSupported.getLength();
1529 ++pSupported
1531 if ( _ServiceName == *pSupported )
1532 return sal_True;
1533 return false;
1536 uno::Sequence< OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( ) throw (uno::RuntimeException)
1538 uno::Reference<lang::XServiceInfo> xSI;
1539 if ( mxShapeAgg.is() )
1540 mxShapeAgg->queryAggregation( lang::XServiceInfo::static_type() ) >>= xSI;
1542 uno::Sequence< OUString > aSupported;
1543 if ( xSI.is() )
1544 aSupported = xSI->getSupportedServiceNames();
1546 aSupported.realloc( aSupported.getLength() + 1 );
1547 aSupported[ aSupported.getLength() - 1 ] = "com.sun.star.sheet.Shape";
1549 if( bIsNoteCaption )
1551 aSupported.realloc( aSupported.getLength() + 1 );
1552 aSupported[ aSupported.getLength() - 1 ] = "com.sun.star.sheet.CellAnnotationShape";
1555 return aSupported;
1558 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */