bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / unoobj / shapeuno.cxx
blobc5ec413e1b578e20caf1af1f364a549ecb64ea8f
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 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( OUString( "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 String 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(OUString("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 String 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 GetShapePropertySet();
845 if (pShapePropertySet)
846 aAny = pShapePropertySet->getPropertyValue( aPropertyName );
849 return aAny;
852 void SAL_CALL ScShapeObj::addPropertyChangeListener( const OUString& aPropertyName,
853 const uno::Reference<beans::XPropertyChangeListener>& aListener)
854 throw(beans::UnknownPropertyException,
855 lang::WrappedTargetException, uno::RuntimeException)
857 SolarMutexGuard aGuard;
859 GetShapePropertySet();
860 if (pShapePropertySet)
861 pShapePropertySet->addPropertyChangeListener( aPropertyName, aListener );
863 if ( !bInitializedNotifier )
865 // here's the latest chance to initialize the property notification at the SdrObject
866 // (in the ctor, where we also attempt to do this, we do not necessarily have
867 // and SdrObject, yet)
868 SdrObject* pObj = GetSdrObject();
869 OSL_ENSURE( pObj, "ScShapeObj::addPropertyChangeListener: no SdrObject -> no property change notification!" );
870 if ( pObj )
871 lcl_initializeNotifier( *pObj, *this );
872 bInitializedNotifier = true;
876 void SAL_CALL ScShapeObj::removePropertyChangeListener( const OUString& aPropertyName,
877 const uno::Reference<beans::XPropertyChangeListener>& aListener)
878 throw(beans::UnknownPropertyException,
879 lang::WrappedTargetException, uno::RuntimeException)
881 SolarMutexGuard aGuard;
883 GetShapePropertySet();
884 if (pShapePropertySet)
885 pShapePropertySet->removePropertyChangeListener( aPropertyName, aListener );
888 void SAL_CALL ScShapeObj::addVetoableChangeListener( const OUString& aPropertyName,
889 const uno::Reference<beans::XVetoableChangeListener>& aListener)
890 throw(beans::UnknownPropertyException,
891 lang::WrappedTargetException, uno::RuntimeException)
893 SolarMutexGuard aGuard;
895 GetShapePropertySet();
896 if (pShapePropertySet)
897 pShapePropertySet->addVetoableChangeListener( aPropertyName, aListener );
900 void SAL_CALL ScShapeObj::removeVetoableChangeListener( const OUString& aPropertyName,
901 const uno::Reference<beans::XVetoableChangeListener>& aListener)
902 throw(beans::UnknownPropertyException,
903 lang::WrappedTargetException, uno::RuntimeException)
905 SolarMutexGuard aGuard;
907 GetShapePropertySet();
908 if (pShapePropertySet)
909 pShapePropertySet->removeVetoableChangeListener( aPropertyName, aListener );
912 // XPropertyState
914 beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const OUString& aPropertyName )
915 throw(beans::UnknownPropertyException, uno::RuntimeException)
917 SolarMutexGuard aGuard;
918 String aNameString(aPropertyName);
920 beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
921 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
923 // ImageMap is always "direct"
925 else if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
927 // Anchor is always "direct"
929 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
931 // HoriPos is always "direct"
933 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
935 // VertPos is always "direct"
937 else
939 GetShapePropertyState();
940 if (pShapePropertyState)
941 eRet = pShapePropertyState->getPropertyState( aPropertyName );
944 return eRet;
947 uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates(
948 const uno::Sequence<OUString>& aPropertyNames )
949 throw(beans::UnknownPropertyException, uno::RuntimeException)
951 SolarMutexGuard aGuard;
953 // simple loop to get own and aggregated states
955 const OUString* pNames = aPropertyNames.getConstArray();
956 uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
957 beans::PropertyState* pStates = aRet.getArray();
958 for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
959 pStates[i] = getPropertyState(pNames[i]);
960 return aRet;
963 void SAL_CALL ScShapeObj::setPropertyToDefault( const OUString& aPropertyName )
964 throw(beans::UnknownPropertyException, uno::RuntimeException)
966 SolarMutexGuard aGuard;
967 String aNameString(aPropertyName);
969 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
971 SdrObject* pObj = GetSdrObject();
972 if ( pObj )
974 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
975 if( pIMapInfo )
977 ImageMap aEmpty;
978 pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map
980 else
982 // nothing to do (no need to insert user data for an empty map)
986 else
988 GetShapePropertyState();
989 if (pShapePropertyState)
990 pShapePropertyState->setPropertyToDefault( aPropertyName );
994 uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const OUString& aPropertyName )
995 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
996 uno::RuntimeException)
998 SolarMutexGuard aGuard;
999 String aNameString = aPropertyName;
1001 uno::Any aAny;
1002 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
1004 // default: empty ImageMap
1005 uno::Reference< uno::XInterface > xImageMap(SvUnoImageMap_createInstance( GetSupportedMacroItems() ));
1006 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
1008 else
1010 GetShapePropertyState();
1011 if (pShapePropertyState)
1012 aAny = pShapePropertyState->getPropertyDefault( aPropertyName );
1015 return aAny;
1018 // XTextContent
1020 void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& /* xTextRange */ )
1021 throw(lang::IllegalArgumentException, uno::RuntimeException)
1023 SolarMutexGuard aGuard;
1025 throw lang::IllegalArgumentException(); // anchor cannot be changed
1028 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor() throw(uno::RuntimeException)
1030 SolarMutexGuard aGuard;
1032 uno::Reference<text::XTextRange> xRet;
1034 SdrObject* pObj = GetSdrObject();
1035 if( pObj )
1037 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
1038 SdrPage* pPage = pObj->GetPage();
1039 if ( pModel )
1041 ScDocument* pDoc = pModel->GetDocument();
1042 if ( pDoc )
1044 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1045 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1047 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
1049 SCTAB nTab = 0;
1050 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
1052 Point aPos(pObj->GetCurrentBoundRect().TopLeft());
1053 ScRange aRange(pDoc->GetRange( nTab, Rectangle( aPos, aPos ) ));
1055 // anchor is always the cell
1057 xRet.set(new ScCellObj( pDocSh, aRange.aStart ));
1064 return xRet;
1067 // XComponent
1069 void SAL_CALL ScShapeObj::dispose() throw(uno::RuntimeException)
1071 SolarMutexGuard aGuard;
1073 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1074 if ( xAggComp.is() )
1075 xAggComp->dispose();
1078 void SAL_CALL ScShapeObj::addEventListener(
1079 const uno::Reference<lang::XEventListener>& xListener )
1080 throw(uno::RuntimeException)
1082 SolarMutexGuard aGuard;
1084 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1085 if ( xAggComp.is() )
1086 xAggComp->addEventListener(xListener);
1089 void SAL_CALL ScShapeObj::removeEventListener(
1090 const uno::Reference<lang::XEventListener>& xListener )
1091 throw(uno::RuntimeException)
1093 SolarMutexGuard aGuard;
1095 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1096 if ( xAggComp.is() )
1097 xAggComp->removeEventListener(xListener);
1100 // XText
1101 // (special handling for ScCellFieldObj)
1103 static void lcl_CopyOneProperty( beans::XPropertySet& rDest, beans::XPropertySet& rSource, const sal_Char* pName )
1105 OUString aNameStr(OUString::createFromAscii(pName));
1108 rDest.setPropertyValue( aNameStr, rSource.getPropertyValue( aNameStr ) );
1110 catch (uno::Exception&)
1112 OSL_FAIL("Exception in text field");
1116 void SAL_CALL ScShapeObj::insertTextContent( const uno::Reference<text::XTextRange>& xRange,
1117 const uno::Reference<text::XTextContent>& xContent,
1118 sal_Bool bAbsorb )
1119 throw(lang::IllegalArgumentException, uno::RuntimeException)
1121 SolarMutexGuard aGuard;
1123 uno::Reference<text::XTextContent> xEffContent;
1125 ScEditFieldObj* pCellField = ScEditFieldObj::getImplementation( xContent );
1126 if ( pCellField )
1128 // createInstance("TextField.URL") from the document creates a ScCellFieldObj.
1129 // To insert it into drawing text, a SvxUnoTextField is needed instead.
1130 // The ScCellFieldObj object is left in non-inserted state.
1132 SvxUnoTextField* pDrawField = new SvxUnoTextField( text::textfield::Type::URL );
1133 xEffContent.set(pDrawField);
1134 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL );
1135 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR );
1136 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET );
1138 else
1139 xEffContent.set(xContent);
1141 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1142 if ( xAggText.is() )
1143 xAggText->insertTextContent( xRange, xEffContent, bAbsorb );
1146 void SAL_CALL ScShapeObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
1147 throw(container::NoSuchElementException, uno::RuntimeException)
1149 SolarMutexGuard aGuard;
1151 // ScCellFieldObj can't be used here.
1153 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1154 if ( xAggText.is() )
1155 xAggText->removeTextContent( xContent );
1158 // XSimpleText (parent of XText)
1159 // Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object
1161 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursor()
1162 throw(uno::RuntimeException)
1164 SolarMutexGuard aGuard;
1166 if ( mxShapeAgg.is() )
1168 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1170 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
1171 if (pText)
1172 return new ScDrawTextCursor( this, *pText );
1175 return uno::Reference<text::XTextCursor>();
1178 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursorByRange(
1179 const uno::Reference<text::XTextRange>& aTextPosition )
1180 throw(uno::RuntimeException)
1182 SolarMutexGuard aGuard;
1184 if ( mxShapeAgg.is() && aTextPosition.is() )
1186 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1188 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
1189 SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
1190 if ( pText && pRange )
1192 SvxUnoTextCursor* pCursor = new ScDrawTextCursor( this, *pText );
1193 uno::Reference<text::XTextCursor> xCursor( pCursor );
1194 pCursor->SetSelection( pRange->GetSelection() );
1195 return xCursor;
1199 return uno::Reference<text::XTextCursor>();
1202 void SAL_CALL ScShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange,
1203 const OUString& aString, sal_Bool bAbsorb )
1204 throw(uno::RuntimeException)
1206 SolarMutexGuard aGuard;
1208 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1209 if ( xAggSimpleText.is() )
1210 xAggSimpleText->insertString( xRange, aString, bAbsorb );
1211 else
1212 throw uno::RuntimeException();
1215 void SAL_CALL ScShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
1216 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
1217 throw(lang::IllegalArgumentException, uno::RuntimeException)
1219 SolarMutexGuard aGuard;
1221 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1222 if ( xAggSimpleText.is() )
1223 xAggSimpleText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
1224 else
1225 throw uno::RuntimeException();
1228 // XTextRange
1229 // (parent of XSimpleText)
1231 uno::Reference<text::XText> SAL_CALL ScShapeObj::getText() throw(uno::RuntimeException)
1233 SolarMutexGuard aGuard;
1234 return this;
1237 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart() throw(uno::RuntimeException)
1239 SolarMutexGuard aGuard;
1241 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1242 if ( xAggTextRange.is() )
1243 return xAggTextRange->getStart();
1244 else
1245 throw uno::RuntimeException();
1247 // return uno::Reference<text::XTextRange>();
1250 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getEnd() throw(uno::RuntimeException)
1252 SolarMutexGuard aGuard;
1254 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1255 if ( xAggTextRange.is() )
1256 return xAggTextRange->getEnd();
1257 else
1258 throw uno::RuntimeException();
1260 // return uno::Reference<text::XTextRange>();
1263 OUString SAL_CALL ScShapeObj::getString() throw(uno::RuntimeException)
1265 SolarMutexGuard aGuard;
1267 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1268 if ( xAggTextRange.is() )
1269 return xAggTextRange->getString();
1270 else
1271 throw uno::RuntimeException();
1273 // return OUString();
1276 void SAL_CALL ScShapeObj::setString( const OUString& aText ) throw(uno::RuntimeException)
1278 SolarMutexGuard aGuard;
1280 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1281 if ( xAggTextRange.is() )
1282 xAggTextRange->setString( aText );
1283 else
1284 throw uno::RuntimeException();
1287 // XChild
1289 uno::Reference< uno::XInterface > SAL_CALL ScShapeObj::getParent() throw (uno::RuntimeException)
1291 SolarMutexGuard aGuard;
1293 // receive cell position from caption object (parent of a note caption is the note cell)
1294 SdrObject* pObj = GetSdrObject();
1295 if( pObj )
1297 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
1298 SdrPage* pPage = pObj->GetPage();
1299 if ( pModel )
1301 ScDocument* pDoc = pModel->GetDocument();
1302 if ( pDoc )
1304 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1305 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1307 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
1309 SCTAB nTab = 0;
1310 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
1312 const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab );
1313 if( pCaptData )
1314 return static_cast< ::cppu::OWeakObject* >( new ScCellObj( pDocSh, pCaptData->maStart ) );
1321 return 0;
1324 void SAL_CALL ScShapeObj::setParent( const uno::Reference< uno::XInterface >& ) throw (lang::NoSupportException, uno::RuntimeException)
1326 throw lang::NoSupportException();
1329 // XTypeProvider
1331 uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes() throw(uno::RuntimeException)
1333 uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() );
1335 uno::Sequence< uno::Type > aTextTypes;
1336 if ( bIsTextShape )
1337 aTextTypes = ScShapeObj_TextBase::getTypes();
1339 uno::Reference<lang::XTypeProvider> xBaseProvider;
1340 if ( mxShapeAgg.is() )
1341 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<lang::XTypeProvider>*) 0) ) >>= xBaseProvider;
1342 OSL_ENSURE( xBaseProvider.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" );
1344 uno::Sequence< uno::Type > aAggTypes;
1345 if( xBaseProvider.is() )
1346 aAggTypes = xBaseProvider->getTypes();
1348 return ::comphelper::concatSequences( aBaseTypes, aTextTypes, aAggTypes );
1351 uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId()
1352 throw(uno::RuntimeException)
1354 SolarMutexGuard aGuard;
1355 // do we need to compute the implementation id for this instance?
1356 if( !pImplementationId && mxShapeAgg.is())
1358 uno::Reference< drawing::XShape > xAggShape;
1359 mxShapeAgg->queryAggregation( ::getCppuType((uno::Reference< drawing::XShape >*)0) ) >>= xAggShape;
1361 if( xAggShape.is() )
1363 const OUString aShapeType( xAggShape->getShapeType() );
1364 // did we already compute an implementation id for the agregated shape type?
1365 ScShapeImplementationIdMap::iterator aIter( aImplementationIdMap.find(aShapeType ) );
1366 if( aIter == aImplementationIdMap.end() )
1368 // we need to create a new implementation id for this
1369 // note: this memory is not free'd until application exits
1370 // but since we have a fixed set of shapetypes and the
1371 // memory will be reused this is ok.
1372 pImplementationId = new uno::Sequence< sal_Int8 >( 16 );
1373 rtl_createUuid( (sal_uInt8 *) pImplementationId->getArray(), 0, sal_True );
1374 aImplementationIdMap[ aShapeType ] = pImplementationId;
1376 else
1378 // use the already computed implementation id
1379 pImplementationId = (*aIter).second;
1383 if( NULL == pImplementationId )
1385 OSL_FAIL( "Could not create an implementation id for a ScXShape!" );
1386 return uno::Sequence< sal_Int8 > ();
1388 else
1390 return *pImplementationId;
1394 SdrObject* ScShapeObj::GetSdrObject() const throw()
1396 if(mxShapeAgg.is())
1398 SvxShape* pShape = SvxShape::getImplementation( mxShapeAgg );
1399 if(pShape)
1400 return pShape->GetSdrObject();
1403 return NULL;
1406 #define SC_EVENTACC_ONCLICK OUString( "OnClick" )
1407 #define SC_EVENTACC_SCRIPT OUString( "Script" )
1408 #define SC_EVENTACC_EVENTTYPE OUString( "EventType" )
1410 typedef ::cppu::WeakImplHelper1< container::XNameReplace > ShapeUnoEventAcess_BASE;
1411 class ShapeUnoEventAccessImpl : public ShapeUnoEventAcess_BASE
1413 private:
1414 ScShapeObj* mpShape;
1416 ScMacroInfo* getInfo( sal_Bool bCreate = false )
1418 return ScShapeObj_getShapeHyperMacroInfo( mpShape, bCreate );
1421 public:
1422 ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
1426 // XNameReplace
1427 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
1429 if ( !hasByName( aName ) )
1430 throw container::NoSuchElementException();
1431 uno::Sequence< beans::PropertyValue > aProperties;
1432 aElement >>= aProperties;
1433 const beans::PropertyValue* pProperties = aProperties.getConstArray();
1434 const sal_Int32 nCount = aProperties.getLength();
1435 sal_Int32 nIndex;
1436 bool isEventType = false;
1437 for( nIndex = 0; nIndex < nCount; nIndex++, pProperties++ )
1439 if ( pProperties->Name.equals( SC_EVENTACC_EVENTTYPE ) )
1441 isEventType = true;
1442 continue;
1444 if ( isEventType && (pProperties->Name == SC_EVENTACC_SCRIPT) )
1446 OUString sValue;
1447 if ( pProperties->Value >>= sValue )
1449 ScMacroInfo* pInfo = getInfo( sal_True );
1450 OSL_ENSURE( pInfo, "shape macro info could not be created!" );
1451 if ( !pInfo )
1452 break;
1453 if ( pProperties->Name == SC_EVENTACC_SCRIPT )
1454 pInfo->SetMacro( sValue );
1455 else
1456 pInfo->SetHlink( sValue );
1462 // XNameAccess
1463 virtual uno::Any SAL_CALL getByName( const OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
1465 uno::Sequence< beans::PropertyValue > aProperties;
1466 ScMacroInfo* pInfo = getInfo();
1468 if ( aName == SC_EVENTACC_ONCLICK )
1470 if ( pInfo && !pInfo->GetMacro().isEmpty() )
1472 aProperties.realloc( 2 );
1473 aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
1474 aProperties[ 0 ].Value <<= SC_EVENTACC_SCRIPT;
1475 aProperties[ 1 ].Name = SC_EVENTACC_SCRIPT;
1476 aProperties[ 1 ].Value <<= pInfo->GetMacro();
1479 else
1481 throw container::NoSuchElementException();
1484 return uno::Any( aProperties );
1487 virtual uno::Sequence< OUString > SAL_CALL getElementNames() throw(uno::RuntimeException)
1489 uno::Sequence< OUString > aSeq( 1 );
1490 aSeq[ 0 ] = SC_EVENTACC_ONCLICK;
1491 return aSeq;
1494 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) throw(uno::RuntimeException)
1496 return aName == SC_EVENTACC_ONCLICK;
1499 // XElementAccess
1500 virtual uno::Type SAL_CALL getElementType() throw(uno::RuntimeException)
1502 return *SEQTYPE(::getCppuType((const uno::Sequence< beans::PropertyValue >*)0));
1505 virtual sal_Bool SAL_CALL hasElements() throw(uno::RuntimeException)
1507 // elements are always present (but contained property sequences may be empty)
1508 return sal_True;
1512 ::uno::Reference< container::XNameReplace > SAL_CALL
1513 ScShapeObj::getEvents( ) throw(uno::RuntimeException)
1515 return new ShapeUnoEventAccessImpl( this );
1518 OUString SAL_CALL ScShapeObj::getImplementationName( ) throw (uno::RuntimeException)
1520 return OUString( "com.sun.star.comp.sc.ScShapeObj" );
1523 ::sal_Bool SAL_CALL ScShapeObj::supportsService( const OUString& _ServiceName ) throw (uno::RuntimeException)
1525 uno::Sequence< OUString > aSupported( getSupportedServiceNames() );
1526 for ( const OUString* pSupported = aSupported.getConstArray();
1527 pSupported != aSupported.getConstArray() + aSupported.getLength();
1528 ++pSupported
1530 if ( _ServiceName == *pSupported )
1531 return sal_True;
1532 return false;
1535 uno::Sequence< OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( ) throw (uno::RuntimeException)
1537 uno::Reference<lang::XServiceInfo> xSI;
1538 if ( mxShapeAgg.is() )
1539 mxShapeAgg->queryAggregation( lang::XServiceInfo::static_type() ) >>= xSI;
1541 uno::Sequence< OUString > aSupported;
1542 if ( xSI.is() )
1543 aSupported = xSI->getSupportedServiceNames();
1545 aSupported.realloc( aSupported.getLength() + 1 );
1546 aSupported[ aSupported.getLength() - 1 ] = OUString( "com.sun.star.sheet.Shape" );
1548 if( bIsNoteCaption )
1550 aSupported.realloc( aSupported.getLength() + 1 );
1551 aSupported[ aSupported.getLength() - 1 ] = OUString( "com.sun.star.sheet.CellAnnotationShape" );
1554 return aSupported;
1557 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */