update dev300-m58
[ooovba.git] / sc / source / ui / unoobj / shapeuno.cxx
blob34318bc674dba9db39c2a2d4f6f038cb4f8d0bb8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: shapeuno.cxx,v $
10 * $Revision: 1.21.32.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include <tools/debug.hxx>
35 #include <comphelper/uno3.hxx>
36 #include <comphelper/stl_types.hxx>
37 #include <svtools/unoevent.hxx>
38 #include <svtools/unoimap.hxx>
39 #include <svx/svdobj.hxx>
40 #include <svx/unoshape.hxx>
41 #include <svx/unofield.hxx>
42 #include <svx/shapepropertynotifier.hxx>
43 #include <toolkit/helper/convert.hxx>
44 #include <cppuhelper/implbase2.hxx>
46 #include <com/sun/star/drawing/XShape.hpp>
47 #include <com/sun/star/beans/PropertyAttribute.hpp>
49 #include "shapeuno.hxx"
50 #include "miscuno.hxx"
51 #include "cellsuno.hxx"
52 #include "textuno.hxx"
53 #include "fielduno.hxx"
54 #include "docsh.hxx"
55 #include "drwlayer.hxx"
56 #include "userdat.hxx"
57 #include "unonames.hxx"
58 #include "unoguard.hxx"
60 using namespace ::com::sun::star;
62 //------------------------------------------------------------------------
64 DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence< sal_Int8 > *, ScShapeImplementationIdMap );
66 static ScShapeImplementationIdMap aImplementationIdMap;
68 const SfxItemPropertyMapEntry* lcl_GetShapeMap()
70 static SfxItemPropertyMapEntry aShapeMap_Impl[] =
72 {MAP_CHAR_LEN(SC_UNONAME_ANCHOR), 0, &getCppuType((uno::Reference<uno::XInterface>*)0), 0, 0 },
73 {MAP_CHAR_LEN(SC_UNONAME_HORIPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
74 {MAP_CHAR_LEN(SC_UNONAME_IMAGEMAP), 0, &getCppuType((uno::Reference<container::XIndexContainer>*)0), 0, 0 },
75 {MAP_CHAR_LEN(SC_UNONAME_VERTPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
76 // #i66550 HLINK_FOR_SHAPES
77 {MAP_CHAR_LEN(SC_UNONAME_HYPERLINK), 0, &getCppuType((rtl::OUString*)0), 0, 0 },
78 {0,0,0,0,0,0}
80 return aShapeMap_Impl;
83 // static
84 const SvEventDescription* ScShapeObj::GetSupportedMacroItems()
86 static const SvEventDescription aMacroDescriptionsImpl[] =
88 { 0, NULL }
90 return aMacroDescriptionsImpl;
92 // #i66550 HLINK_FOR_SHAPES
93 ScMacroInfo* lcl_getShapeHyperMacroInfo( ScShapeObj* pShape, BOOL bCreate = FALSE )
95 if( pShape )
96 if( SdrObject* pObj = pShape->GetSdrObject() )
97 return ScDrawLayer::GetMacroInfo( pObj, bCreate );
98 return 0;
101 //------------------------------------------------------------------------
103 namespace
105 void lcl_initializeNotifier( SdrObject& _rSdrObj, ::cppu::OWeakObject& _rShape )
107 ::svx::PPropertyValueProvider pProvider( new ::svx::PropertyValueProvider( _rShape, "Anchor" ) );
108 _rSdrObj.getShapePropertyChangeNotifier().registerProvider( ::svx::eSpreadsheetAnchor, pProvider );
112 //------------------------------------------------------------------------
114 ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) :
115 pShapePropertySet(NULL),
116 pShapePropertyState(NULL),
117 pImplementationId(NULL),
118 bIsTextShape(FALSE),
119 bInitializedNotifier(false)
121 comphelper::increment( m_refCount );
124 mxShapeAgg = uno::Reference<uno::XAggregation>( xShape, uno::UNO_QUERY );
125 // extra block to force deletion of the temporary before setDelegator
128 if (mxShapeAgg.is())
130 xShape = NULL; // during setDelegator, mxShapeAgg must be the only ref
132 mxShapeAgg->setDelegator( (cppu::OWeakObject*)this );
134 xShape.set(uno::Reference<drawing::XShape>( mxShapeAgg, uno::UNO_QUERY ));
136 bIsTextShape = ( SvxUnoTextBase::getImplementation( mxShapeAgg ) != NULL );
140 SdrObject* pObj = GetSdrObject();
141 if ( pObj )
143 lcl_initializeNotifier( *pObj, *this );
144 bInitializedNotifier = true;
148 comphelper::decrement( m_refCount );
151 ScShapeObj::~ScShapeObj()
153 // if (mxShapeAgg.is())
154 // mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>());
157 // XInterface
159 uno::Any SAL_CALL ScShapeObj::queryInterface( const uno::Type& rType )
160 throw(uno::RuntimeException)
162 uno::Any aRet = ScShapeObj_Base::queryInterface( rType );
164 if ( !aRet.hasValue() && bIsTextShape )
165 aRet = ScShapeObj_TextBase::queryInterface( rType );
167 if ( !aRet.hasValue() && mxShapeAgg.is() )
168 aRet = mxShapeAgg->queryAggregation( rType );
170 return aRet;
173 void SAL_CALL ScShapeObj::acquire() throw()
175 OWeakObject::acquire();
178 void SAL_CALL ScShapeObj::release() throw()
180 OWeakObject::release();
183 void ScShapeObj::GetShapePropertySet()
185 // #i61908# Store the result of queryAggregation in a member.
186 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
188 if (!pShapePropertySet)
190 uno::Reference<beans::XPropertySet> xProp;
191 if ( mxShapeAgg.is() )
192 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertySet>*) 0) ) >>= xProp;
193 pShapePropertySet = xProp.get();
197 void ScShapeObj::GetShapePropertyState()
199 // #i61908# Store the result of queryAggregation in a member.
200 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
202 if (!pShapePropertyState)
204 uno::Reference<beans::XPropertyState> xState;
205 if ( mxShapeAgg.is() )
206 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertyState>*) 0) ) >>= xState;
207 pShapePropertyState = xState.get();
211 uno::Reference<lang::XComponent> lcl_GetComponent( const uno::Reference<uno::XAggregation>& xAgg )
213 uno::Reference<lang::XComponent> xRet;
214 if ( xAgg.is() )
215 xAgg->queryAggregation( getCppuType((uno::Reference<lang::XComponent>*) 0) ) >>= xRet;
216 return xRet;
219 uno::Reference<text::XText> lcl_GetText( const uno::Reference<uno::XAggregation>& xAgg )
221 uno::Reference<text::XText> xRet;
222 if ( xAgg.is() )
223 xAgg->queryAggregation( getCppuType((uno::Reference<text::XText>*) 0) ) >>= xRet;
224 return xRet;
227 uno::Reference<text::XSimpleText> lcl_GetSimpleText( const uno::Reference<uno::XAggregation>& xAgg )
229 uno::Reference<text::XSimpleText> xRet;
230 if ( xAgg.is() )
231 xAgg->queryAggregation( getCppuType((uno::Reference<text::XSimpleText>*) 0) ) >>= xRet;
232 return xRet;
235 uno::Reference<text::XTextRange> lcl_GetTextRange( const uno::Reference<uno::XAggregation>& xAgg )
237 uno::Reference<text::XTextRange> xRet;
238 if ( xAgg.is() )
239 xAgg->queryAggregation( getCppuType((uno::Reference<text::XTextRange>*) 0) ) >>= xRet;
240 return xRet;
243 // XPropertySet
245 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScShapeObj::getPropertySetInfo()
246 throw(uno::RuntimeException)
248 ScUnoGuard aGuard;
250 // #i61527# cache property set info for this object
251 if ( !mxPropSetInfo.is() )
253 // mix own and aggregated properties:
254 GetShapePropertySet();
255 if (pShapePropertySet)
257 uno::Reference<beans::XPropertySetInfo> xAggInfo(pShapePropertySet->getPropertySetInfo());
258 const uno::Sequence<beans::Property> aPropSeq(xAggInfo->getProperties());
259 mxPropSetInfo.set(new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), aPropSeq ));
262 return mxPropSetInfo;
265 BOOL lcl_GetPageNum( SdrPage* pPage, SdrModel& rModel, SCTAB& rNum )
267 USHORT nCount = rModel.GetPageCount();
268 for (USHORT i=0; i<nCount; i++)
269 if ( rModel.GetPage(i) == pPage )
271 rNum = static_cast<SCTAB>(i);
272 return TRUE;
275 return FALSE;
278 BOOL lcl_GetCaptionPoint( uno::Reference< drawing::XShape >& xShape, awt::Point& rCaptionPoint )
280 BOOL bReturn = FALSE;
281 rtl::OUString sType(xShape->getShapeType());
282 sal_Bool bCaptionShape(sType.equalsAscii("com.sun.star.drawing.CaptionShape"));
283 if (bCaptionShape)
285 uno::Reference < beans::XPropertySet > xShapeProp (xShape, uno::UNO_QUERY);
286 if (xShapeProp.is())
288 xShapeProp->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )) ) >>= rCaptionPoint;
289 bReturn = TRUE;
292 return bReturn;
295 ScRange lcl_GetAnchorCell( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab,
296 awt::Point& rUnoPoint, awt::Size& rUnoSize, awt::Point& rCaptionPoint )
298 ScRange aReturn;
299 rUnoPoint = xShape->getPosition();
300 rtl::OUString sType(xShape->getShapeType());
301 sal_Bool bCaptionShape(lcl_GetCaptionPoint(xShape, rCaptionPoint));
302 if (pDoc->IsNegativePage(nTab))
304 rUnoSize = xShape->getSize();
305 rUnoPoint.X += rUnoSize.Width; // the right top point is base
306 if (bCaptionShape)
308 if (rCaptionPoint.X > 0 && rCaptionPoint.X > rUnoSize.Width)
309 rUnoPoint.X += rCaptionPoint.X - rUnoSize.Width;
310 if (rCaptionPoint.Y < 0)
311 rUnoPoint.Y += rCaptionPoint.Y;
313 aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
315 else
317 if (bCaptionShape)
319 if (rCaptionPoint.X < 0)
320 rUnoPoint.X += rCaptionPoint.X;
321 if (rCaptionPoint.Y < 0)
322 rUnoPoint.Y += rCaptionPoint.Y;
324 aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
327 return aReturn;
330 awt::Point lcl_GetRelativePos( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab, ScRange& rRange,
331 awt::Size& rUnoSize, awt::Point& rCaptionPoint)
333 awt::Point aUnoPoint;
334 rRange = lcl_GetAnchorCell(xShape, pDoc, nTab, aUnoPoint, rUnoSize, rCaptionPoint);
335 if (pDoc->IsNegativePage(nTab))
337 Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
338 Point aPoint(aRect.TopRight());
339 aUnoPoint.X -= aPoint.X();
340 aUnoPoint.Y -= aPoint.Y();
342 else
344 ScRange aRange = pDoc->GetRange( nTab, Rectangle( VCLPoint(aUnoPoint), VCLPoint(aUnoPoint) ));
345 Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
346 Point aPoint(aRect.TopLeft());
347 aUnoPoint.X -= aPoint.X();
348 aUnoPoint.Y -= aPoint.Y();
351 return aUnoPoint;
354 void SAL_CALL ScShapeObj::setPropertyValue(
355 const rtl::OUString& aPropertyName, const uno::Any& aValue )
356 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
357 lang::IllegalArgumentException, lang::WrappedTargetException,
358 uno::RuntimeException)
360 ScUnoGuard aGuard;
361 String aNameString(aPropertyName);
363 if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
365 uno::Reference<sheet::XCellRangeAddressable> xRangeAdd(aValue, uno::UNO_QUERY);
366 if (xRangeAdd.is())
368 SdrObject *pObj = GetSdrObject();
369 if (pObj)
371 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
372 SdrPage* pPage = pObj->GetPage();
373 if ( pModel && pPage )
375 ScDocument* pDoc = pModel->GetDocument();
376 if ( pDoc )
378 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
379 if ( pObjSh && pObjSh->ISA(ScDocShell) )
381 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
383 SCTAB nTab = 0;
384 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
386 table::CellRangeAddress aAddress = xRangeAdd->getRangeAddress();
387 if (nTab == aAddress.Sheet)
389 if (aAddress.StartRow != aAddress.EndRow) //should be a Spreadsheet
391 DBG_ASSERT(aAddress.StartRow == 0 && aAddress.EndRow == MAXROW &&
392 aAddress.StartColumn == 0 && aAddress.EndColumn == MAXCOL, "here should be a XSpreadsheet");
393 ScDrawLayer::SetAnchor(pObj, SCA_PAGE);
395 else
397 DBG_ASSERT(aAddress.StartRow == aAddress.EndRow &&
398 aAddress.StartColumn == aAddress.EndColumn, "here should be a XCell");
399 ScDrawLayer::SetAnchor(pObj, SCA_CELL);
401 Rectangle aRect(pDoc->GetMMRect( static_cast<SCCOL>(aAddress.StartColumn), static_cast<SCROW>(aAddress.StartRow),
402 static_cast<SCCOL>(aAddress.EndColumn), static_cast<SCROW>(aAddress.EndRow), aAddress.Sheet ));
403 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
404 if (xShape.is())
406 Point aPoint;
407 Point aEndPoint;
408 if (pDoc->IsNegativePage(nTab))
410 aPoint = aRect.TopRight();
411 aEndPoint = aRect.BottomLeft();
413 else
415 aPoint = aRect.TopLeft();
416 aEndPoint = aRect.BottomRight();
418 awt::Size aUnoSize;
419 awt::Point aCaptionPoint;
420 ScRange aRange;
421 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
423 aUnoPoint.X += aPoint.X();
424 aUnoPoint.Y += aPoint.Y();
426 if ( aUnoPoint.Y > aEndPoint.Y() )
427 aUnoPoint.Y = aEndPoint.Y() - 2;
428 if (pDoc->IsNegativePage(nTab))
430 if ( aUnoPoint.X < aEndPoint.X() )
431 aUnoPoint.X = aEndPoint.X() + 2;
432 aUnoPoint.X -= aUnoSize.Width;
433 // remove difference to caption point
434 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
435 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
437 else
439 if ( aUnoPoint.X > aEndPoint.X() )
440 aUnoPoint.X = aEndPoint.X() - 2;
441 if (aCaptionPoint.X < 0)
442 aUnoPoint.X -= aCaptionPoint.X;
444 if (aCaptionPoint.Y < 0)
445 aUnoPoint.Y -= aCaptionPoint.Y;
447 xShape->setPosition(aUnoPoint);
448 pDocSh->SetModified();
457 else
458 throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("only XCell or XSpreadsheet objects allowed")), static_cast<cppu::OWeakObject*>(this), 0);
460 else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
462 SdrObject* pObj = GetSdrObject();
463 if ( pObj )
465 ImageMap aImageMap;
466 uno::Reference< uno::XInterface > xImageMapInt(aValue, uno::UNO_QUERY);
468 if( !xImageMapInt.is() || !SvUnoImageMap_fillImageMap( xImageMapInt, aImageMap ) )
469 throw lang::IllegalArgumentException();
471 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
472 if( pIMapInfo )
474 // replace existing image map
475 pIMapInfo->SetImageMap( aImageMap );
477 else
479 // insert new user data with image map
480 pObj->InsertUserData(new ScIMapInfo(aImageMap) );
484 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
486 sal_Int32 nPos = 0;
487 if (aValue >>= nPos)
489 SdrObject *pObj = GetSdrObject();
490 if (pObj)
492 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
493 SdrPage* pPage = pObj->GetPage();
494 if ( pModel && pPage )
496 SCTAB nTab = 0;
497 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
499 ScDocument* pDoc = pModel->GetDocument();
500 if ( pDoc )
502 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
503 if ( pObjSh && pObjSh->ISA(ScDocShell) )
505 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
506 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
507 if (xShape.is())
509 if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE)
511 awt::Point aPoint(xShape->getPosition());
512 awt::Size aSize(xShape->getSize());
513 awt::Point aCaptionPoint;
514 if (pDoc->IsNegativePage(nTab))
516 nPos *= -1;
517 nPos -= aSize.Width;
519 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
521 if (pDoc->IsNegativePage(nTab))
523 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aSize.Width)
524 nPos -= aCaptionPoint.X - aSize.Width;
526 else
528 if (aCaptionPoint.X < 0)
529 nPos -= aCaptionPoint.X;
532 aPoint.X = nPos;
533 xShape->setPosition(aPoint);
534 pDocSh->SetModified();
536 else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
538 awt::Size aUnoSize;
539 awt::Point aCaptionPoint;
540 ScRange aRange;
541 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
542 Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
543 if (pDoc->IsNegativePage(nTab))
545 aUnoPoint.X = -nPos;
546 Point aPoint(aRect.TopRight());
547 Point aEndPoint(aRect.BottomLeft());
548 aUnoPoint.X += aPoint.X();
549 if (aUnoPoint.X < aEndPoint.X())
550 aUnoPoint.X = aEndPoint.X() + 2;
551 aUnoPoint.X -= aUnoSize.Width;
552 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
553 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
555 else
557 aUnoPoint.X = nPos;
558 Point aPoint(aRect.TopLeft());
559 Point aEndPoint(aRect.BottomRight());
560 aUnoPoint.X += aPoint.X();
561 if (aUnoPoint.X > aEndPoint.X())
562 aUnoPoint.X = aEndPoint.X() - 2;
563 if (aCaptionPoint.X < 0)
564 aUnoPoint.X -= aCaptionPoint.X;
566 aUnoPoint.Y = xShape->getPosition().Y;
567 xShape->setPosition(aUnoPoint);
568 pDocSh->SetModified();
570 else
572 DBG_ERROR("unknown anchor type");
582 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
584 sal_Int32 nPos = 0;
585 if (aValue >>= nPos)
587 SdrObject *pObj = GetSdrObject();
588 if (pObj)
590 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
591 SdrPage* pPage = pObj->GetPage();
592 if ( pModel && pPage )
594 SCTAB nTab = 0;
595 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
597 ScDocument* pDoc = pModel->GetDocument();
598 if ( pDoc )
600 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
601 if ( pObjSh && pObjSh->ISA(ScDocShell) )
603 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
604 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
605 if (xShape.is())
607 if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE)
609 awt::Point aPoint = xShape->getPosition();
610 awt::Point aCaptionPoint;
611 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
613 if (aCaptionPoint.Y < 0)
614 nPos -= aCaptionPoint.Y;
616 aPoint.Y = nPos;
617 xShape->setPosition(aPoint);
618 pDocSh->SetModified();
620 else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
622 awt::Size aUnoSize;
623 awt::Point aCaptionPoint;
624 ScRange aRange;
625 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
626 Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
627 Point aPoint(aRect.TopRight());
628 Point aEndPoint(aRect.BottomLeft());
629 aUnoPoint.Y = nPos;
630 aUnoPoint.Y += aPoint.Y();
631 if (aUnoPoint.Y > aEndPoint.Y())
632 aUnoPoint.Y = aEndPoint.Y() - 2;
633 if (aCaptionPoint.Y < 0)
634 aUnoPoint.Y -= aCaptionPoint.Y;
635 aUnoPoint.X = xShape->getPosition().X;
636 xShape->setPosition(aUnoPoint);
637 pDocSh->SetModified();
639 else
641 DBG_ERROR("unknown anchor type");
651 else if ( aNameString.EqualsAscii( SC_UNONAME_HYPERLINK ) )
653 rtl::OUString sHlink;
654 ScMacroInfo* pInfo = lcl_getShapeHyperMacroInfo(this, TRUE);
655 if ( ( aValue >>= sHlink ) && pInfo )
656 pInfo->SetHlink( sHlink );
658 else
660 GetShapePropertySet();
661 if (pShapePropertySet)
662 pShapePropertySet->setPropertyValue( aPropertyName, aValue );
666 uno::Any SAL_CALL ScShapeObj::getPropertyValue( const rtl::OUString& aPropertyName )
667 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
668 uno::RuntimeException)
670 ScUnoGuard aGuard;
671 String aNameString = aPropertyName;
673 uno::Any aAny;
674 if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
676 SdrObject *pObj = GetSdrObject();
677 if (pObj)
679 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
680 SdrPage* pPage = pObj->GetPage();
681 if ( pModel && pPage )
683 ScDocument* pDoc = pModel->GetDocument();
684 if ( pDoc )
686 SCTAB nTab = 0;
687 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
689 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
690 if ( pObjSh && pObjSh->ISA(ScDocShell) )
692 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
693 uno::Reference< uno::XInterface > xAnchor;
694 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
696 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
697 if (xShape.is())
699 awt::Size aUnoSize;
700 awt::Point aCaptionPoint;
701 ScRange aRange;
702 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
704 xAnchor.set(static_cast<cppu::OWeakObject*>(new ScCellObj( pDocSh, aRange.aStart )));
707 else
709 xAnchor.set(static_cast<cppu::OWeakObject*>(new ScTableSheetObj( pDocSh, nTab )));
711 aAny <<= xAnchor;
718 else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
720 uno::Reference< uno::XInterface > xImageMap;
721 SdrObject* pObj = GetSdrObject();
722 if ( pObj )
724 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(GetSdrObject());
725 if( pIMapInfo )
727 const ImageMap& rIMap = pIMapInfo->GetImageMap();
728 xImageMap.set(SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() ));
730 else
731 xImageMap = SvUnoImageMap_createInstance( GetSupportedMacroItems() );
733 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
735 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
737 SdrObject *pObj = GetSdrObject();
738 if (pObj)
740 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
741 SdrPage* pPage = pObj->GetPage();
742 if ( pModel && pPage )
744 ScDocument* pDoc = pModel->GetDocument();
745 if ( pDoc )
747 SCTAB nTab = 0;
748 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
750 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
751 if (xShape.is())
753 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
755 awt::Size aUnoSize;
756 awt::Point aCaptionPoint;
757 ScRange aRange;
758 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
759 if (pDoc->IsNegativePage(nTab))
760 aUnoPoint.X *= -1;
761 aAny <<= aUnoPoint.X;
763 else
765 awt::Point aCaptionPoint;
766 awt::Point aUnoPoint(xShape->getPosition());
767 awt::Size aUnoSize(xShape->getSize());
768 if (pDoc->IsNegativePage(nTab))
770 aUnoPoint.X *= -1;
771 aUnoPoint.X -= aUnoSize.Width;
773 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
775 if (pDoc->IsNegativePage(nTab))
777 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
778 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
780 else
782 if (aCaptionPoint.X < 0)
783 aUnoPoint.X += aCaptionPoint.X;
786 aAny <<= aUnoPoint.X;
794 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
796 SdrObject *pObj = GetSdrObject();
797 if (pObj)
799 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
800 SdrPage* pPage = pObj->GetPage();
801 if ( pModel && pPage )
803 ScDocument* pDoc = pModel->GetDocument();
804 if ( pDoc )
806 SCTAB nTab = 0;
807 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
809 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
810 if (xShape.is())
812 uno::Reference< uno::XInterface > xAnchor;
813 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
815 awt::Size aUnoSize;
816 awt::Point aCaptionPoint;
817 ScRange aRange;
818 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
820 aAny <<= aUnoPoint.Y;
822 else
824 awt::Point aUnoPoint(xShape->getPosition());
825 awt::Point aCaptionPoint;
826 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
828 if (aCaptionPoint.Y < 0)
829 aUnoPoint.Y += aCaptionPoint.Y;
831 aAny <<= aUnoPoint.Y;
839 else if ( aNameString.EqualsAscii( SC_UNONAME_HYPERLINK ) )
841 rtl::OUString sHlink;
842 if ( ScMacroInfo* pInfo = lcl_getShapeHyperMacroInfo(this) )
843 sHlink = pInfo->GetHlink();
844 aAny <<= sHlink;
846 else
848 GetShapePropertySet();
849 if (pShapePropertySet)
850 aAny = pShapePropertySet->getPropertyValue( aPropertyName );
853 return aAny;
856 void SAL_CALL ScShapeObj::addPropertyChangeListener( const rtl::OUString& aPropertyName,
857 const uno::Reference<beans::XPropertyChangeListener>& aListener)
858 throw(beans::UnknownPropertyException,
859 lang::WrappedTargetException, uno::RuntimeException)
861 ScUnoGuard aGuard;
863 GetShapePropertySet();
864 if (pShapePropertySet)
865 pShapePropertySet->addPropertyChangeListener( aPropertyName, aListener );
867 if ( !bInitializedNotifier )
869 // here's the latest chance to initialize the property notification at the SdrObject
870 // (in the ctor, where we also attempt to do this, we do not necessarily have
871 // and SdrObject, yet)
872 SdrObject* pObj = GetSdrObject();
873 OSL_ENSURE( pObj, "ScShapeObj::addPropertyChangeListener: no SdrObject -> no property change notification!" );
874 if ( pObj )
875 lcl_initializeNotifier( *pObj, *this );
876 bInitializedNotifier = true;
880 void SAL_CALL ScShapeObj::removePropertyChangeListener( const rtl::OUString& aPropertyName,
881 const uno::Reference<beans::XPropertyChangeListener>& aListener)
882 throw(beans::UnknownPropertyException,
883 lang::WrappedTargetException, uno::RuntimeException)
885 ScUnoGuard aGuard;
887 GetShapePropertySet();
888 if (pShapePropertySet)
889 pShapePropertySet->removePropertyChangeListener( aPropertyName, aListener );
892 void SAL_CALL ScShapeObj::addVetoableChangeListener( const rtl::OUString& aPropertyName,
893 const uno::Reference<beans::XVetoableChangeListener>& aListener)
894 throw(beans::UnknownPropertyException,
895 lang::WrappedTargetException, uno::RuntimeException)
897 ScUnoGuard aGuard;
899 GetShapePropertySet();
900 if (pShapePropertySet)
901 pShapePropertySet->addVetoableChangeListener( aPropertyName, aListener );
904 void SAL_CALL ScShapeObj::removeVetoableChangeListener( const rtl::OUString& aPropertyName,
905 const uno::Reference<beans::XVetoableChangeListener>& aListener)
906 throw(beans::UnknownPropertyException,
907 lang::WrappedTargetException, uno::RuntimeException)
909 ScUnoGuard aGuard;
911 GetShapePropertySet();
912 if (pShapePropertySet)
913 pShapePropertySet->removeVetoableChangeListener( aPropertyName, aListener );
916 // XPropertyState
918 beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const rtl::OUString& aPropertyName )
919 throw(beans::UnknownPropertyException, uno::RuntimeException)
921 ScUnoGuard aGuard;
922 String aNameString(aPropertyName);
924 beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
925 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
927 // ImageMap is always "direct"
929 else if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
931 // Anchor is always "direct"
933 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
935 // HoriPos is always "direct"
937 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
939 // VertPos is always "direct"
941 else
943 GetShapePropertyState();
944 if (pShapePropertyState)
945 eRet = pShapePropertyState->getPropertyState( aPropertyName );
948 return eRet;
951 uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates(
952 const uno::Sequence<rtl::OUString>& aPropertyNames )
953 throw(beans::UnknownPropertyException, uno::RuntimeException)
955 ScUnoGuard aGuard;
957 // simple loop to get own and aggregated states
959 const rtl::OUString* pNames = aPropertyNames.getConstArray();
960 uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
961 beans::PropertyState* pStates = aRet.getArray();
962 for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
963 pStates[i] = getPropertyState(pNames[i]);
964 return aRet;
967 void SAL_CALL ScShapeObj::setPropertyToDefault( const rtl::OUString& aPropertyName )
968 throw(beans::UnknownPropertyException, uno::RuntimeException)
970 ScUnoGuard aGuard;
971 String aNameString(aPropertyName);
973 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
975 SdrObject* pObj = GetSdrObject();
976 if ( pObj )
978 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
979 if( pIMapInfo )
981 ImageMap aEmpty;
982 pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map
984 else
986 // nothing to do (no need to insert user data for an empty map)
990 else
992 GetShapePropertyState();
993 if (pShapePropertyState)
994 pShapePropertyState->setPropertyToDefault( aPropertyName );
998 uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const rtl::OUString& aPropertyName )
999 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
1000 uno::RuntimeException)
1002 ScUnoGuard aGuard;
1003 String aNameString = aPropertyName;
1005 uno::Any aAny;
1006 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
1008 // default: empty ImageMap
1009 uno::Reference< uno::XInterface > xImageMap(SvUnoImageMap_createInstance( GetSupportedMacroItems() ));
1010 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
1012 else
1014 GetShapePropertyState();
1015 if (pShapePropertyState)
1016 aAny = pShapePropertyState->getPropertyDefault( aPropertyName );
1019 return aAny;
1022 // XTextContent
1024 void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& /* xTextRange */ )
1025 throw(lang::IllegalArgumentException, uno::RuntimeException)
1027 ScUnoGuard aGuard;
1029 throw lang::IllegalArgumentException(); // anchor cannot be changed
1032 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor() throw(uno::RuntimeException)
1034 ScUnoGuard aGuard;
1036 uno::Reference<text::XTextRange> xRet;
1038 SdrObject* pObj = GetSdrObject();
1039 if( pObj )
1041 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
1042 SdrPage* pPage = pObj->GetPage();
1043 if ( pModel )
1045 ScDocument* pDoc = pModel->GetDocument();
1046 if ( pDoc )
1048 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1049 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1051 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
1053 SCTAB nTab = 0;
1054 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
1056 Point aPos(pObj->GetCurrentBoundRect().TopLeft());
1057 ScRange aRange(pDoc->GetRange( nTab, Rectangle( aPos, aPos ) ));
1059 // anchor is always the cell
1061 xRet.set(new ScCellObj( pDocSh, aRange.aStart ));
1068 return xRet;
1071 // XComponent
1073 void SAL_CALL ScShapeObj::dispose() throw(uno::RuntimeException)
1075 ScUnoGuard aGuard;
1077 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1078 if ( xAggComp.is() )
1079 xAggComp->dispose();
1082 void SAL_CALL ScShapeObj::addEventListener(
1083 const uno::Reference<lang::XEventListener>& xListener )
1084 throw(uno::RuntimeException)
1086 ScUnoGuard aGuard;
1088 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1089 if ( xAggComp.is() )
1090 xAggComp->addEventListener(xListener);
1093 void SAL_CALL ScShapeObj::removeEventListener(
1094 const uno::Reference<lang::XEventListener>& xListener )
1095 throw(uno::RuntimeException)
1097 ScUnoGuard aGuard;
1099 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1100 if ( xAggComp.is() )
1101 xAggComp->removeEventListener(xListener);
1104 // XText
1105 // (special handling for ScCellFieldObj)
1107 void lcl_CopyOneProperty( beans::XPropertySet& rDest, beans::XPropertySet& rSource, const sal_Char* pName )
1109 rtl::OUString aNameStr(rtl::OUString::createFromAscii(pName));
1112 rDest.setPropertyValue( aNameStr, rSource.getPropertyValue( aNameStr ) );
1114 catch (uno::Exception&)
1116 DBG_ERROR("Exception in text field");
1120 void SAL_CALL ScShapeObj::insertTextContent( const uno::Reference<text::XTextRange>& xRange,
1121 const uno::Reference<text::XTextContent>& xContent,
1122 sal_Bool bAbsorb )
1123 throw(lang::IllegalArgumentException, uno::RuntimeException)
1125 ScUnoGuard aGuard;
1127 uno::Reference<text::XTextContent> xEffContent;
1129 ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent );
1130 if ( pCellField )
1132 // #105585# createInstance("TextField.URL") from the document creates a ScCellFieldObj.
1133 // To insert it into drawing text, a SvxUnoTextField is needed instead.
1134 // The ScCellFieldObj object is left in non-inserted state.
1136 SvxUnoTextField* pDrawField = new SvxUnoTextField( ID_URLFIELD );
1137 xEffContent.set(pDrawField);
1138 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL );
1139 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR );
1140 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET );
1142 else
1143 xEffContent.set(xContent);
1145 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1146 if ( xAggText.is() )
1147 xAggText->insertTextContent( xRange, xEffContent, bAbsorb );
1150 void SAL_CALL ScShapeObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
1151 throw(container::NoSuchElementException, uno::RuntimeException)
1153 ScUnoGuard aGuard;
1155 // ScCellFieldObj can't be used here.
1157 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1158 if ( xAggText.is() )
1159 xAggText->removeTextContent( xContent );
1162 // XSimpleText (parent of XText)
1163 // Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object
1165 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursor()
1166 throw(uno::RuntimeException)
1168 ScUnoGuard aGuard;
1170 if ( mxShapeAgg.is() )
1172 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1174 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
1175 if (pText)
1176 return new ScDrawTextCursor( this, *pText );
1179 return uno::Reference<text::XTextCursor>();
1182 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursorByRange(
1183 const uno::Reference<text::XTextRange>& aTextPosition )
1184 throw(uno::RuntimeException)
1186 ScUnoGuard aGuard;
1188 if ( mxShapeAgg.is() && aTextPosition.is() )
1190 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1192 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
1193 SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
1194 if ( pText && pRange )
1196 SvxUnoTextCursor* pCursor = new ScDrawTextCursor( this, *pText );
1197 uno::Reference<text::XTextCursor> xCursor( pCursor );
1198 pCursor->SetSelection( pRange->GetSelection() );
1199 return xCursor;
1203 return uno::Reference<text::XTextCursor>();
1206 void SAL_CALL ScShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange,
1207 const rtl::OUString& aString, sal_Bool bAbsorb )
1208 throw(uno::RuntimeException)
1210 ScUnoGuard aGuard;
1212 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1213 if ( xAggSimpleText.is() )
1214 xAggSimpleText->insertString( xRange, aString, bAbsorb );
1215 else
1216 throw uno::RuntimeException();
1219 void SAL_CALL ScShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
1220 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
1221 throw(lang::IllegalArgumentException, uno::RuntimeException)
1223 ScUnoGuard aGuard;
1225 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1226 if ( xAggSimpleText.is() )
1227 xAggSimpleText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
1228 else
1229 throw uno::RuntimeException();
1232 // XTextRange
1233 // (parent of XSimpleText)
1235 uno::Reference<text::XText> SAL_CALL ScShapeObj::getText() throw(uno::RuntimeException)
1237 ScUnoGuard aGuard;
1238 return this;
1241 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart() throw(uno::RuntimeException)
1243 ScUnoGuard aGuard;
1245 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1246 if ( xAggTextRange.is() )
1247 return xAggTextRange->getStart();
1248 else
1249 throw uno::RuntimeException();
1251 // return uno::Reference<text::XTextRange>();
1254 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getEnd() throw(uno::RuntimeException)
1256 ScUnoGuard aGuard;
1258 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1259 if ( xAggTextRange.is() )
1260 return xAggTextRange->getEnd();
1261 else
1262 throw uno::RuntimeException();
1264 // return uno::Reference<text::XTextRange>();
1267 rtl::OUString SAL_CALL ScShapeObj::getString() throw(uno::RuntimeException)
1269 ScUnoGuard aGuard;
1271 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1272 if ( xAggTextRange.is() )
1273 return xAggTextRange->getString();
1274 else
1275 throw uno::RuntimeException();
1277 // return rtl::OUString();
1280 void SAL_CALL ScShapeObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
1282 ScUnoGuard aGuard;
1284 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1285 if ( xAggTextRange.is() )
1286 xAggTextRange->setString( aText );
1287 else
1288 throw uno::RuntimeException();
1291 // XTypeProvider
1293 uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes() throw(uno::RuntimeException)
1295 uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() );
1297 uno::Sequence< uno::Type > aTextTypes;
1298 if ( bIsTextShape )
1299 aTextTypes = ScShapeObj_TextBase::getTypes();
1301 uno::Reference<lang::XTypeProvider> xBaseProvider;
1302 if ( mxShapeAgg.is() )
1303 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<lang::XTypeProvider>*) 0) ) >>= xBaseProvider;
1304 DBG_ASSERT( xBaseProvider.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" );
1306 uno::Sequence< uno::Type > aAggTypes;
1307 if( xBaseProvider.is() )
1308 aAggTypes = xBaseProvider->getTypes();
1310 return ::comphelper::concatSequences( aBaseTypes, aTextTypes, aAggTypes );
1313 uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId()
1314 throw(uno::RuntimeException)
1316 ScUnoGuard aGuard;
1317 // do we need to compute the implementation id for this instance?
1318 if( !pImplementationId && mxShapeAgg.is())
1320 uno::Reference< drawing::XShape > xAggShape;
1321 mxShapeAgg->queryAggregation( ::getCppuType((uno::Reference< drawing::XShape >*)0) ) >>= xAggShape;
1323 if( xAggShape.is() )
1325 const rtl::OUString aShapeType( xAggShape->getShapeType() );
1326 // did we already compute an implementation id for the agregated shape type?
1327 ScShapeImplementationIdMap::iterator aIter( aImplementationIdMap.find(aShapeType ) );
1328 if( aIter == aImplementationIdMap.end() )
1330 // we need to create a new implementation id for this
1331 // note: this memory is not free'd until application exists
1332 // but since we have a fixed set of shapetypes and the
1333 // memory will be reused this is ok.
1334 pImplementationId = new uno::Sequence< sal_Int8 >( 16 );
1335 rtl_createUuid( (sal_uInt8 *) pImplementationId->getArray(), 0, sal_True );
1336 aImplementationIdMap[ aShapeType ] = pImplementationId;
1338 else
1340 // use the already computed implementation id
1341 pImplementationId = (*aIter).second;
1345 if( NULL == pImplementationId )
1347 DBG_ERROR( "Could not create an implementation id for a ScXShape!" );
1348 return uno::Sequence< sal_Int8 > ();
1350 else
1352 return *pImplementationId;
1356 SdrObject* ScShapeObj::GetSdrObject() const throw()
1358 if(mxShapeAgg.is())
1360 SvxShape* pShape = SvxShape::getImplementation( mxShapeAgg );
1361 if(pShape)
1362 return pShape->GetSdrObject();
1365 return NULL;
1368 #define SC_EVENTACC_ONCLICK ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) )
1369 #define SC_EVENTACC_SCRIPT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Script" ) )
1370 #define SC_EVENTACC_EVENTTYPE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) )
1372 typedef ::cppu::WeakImplHelper1< container::XNameReplace > ShapeUnoEventAcess_BASE;
1373 class ShapeUnoEventAccessImpl : public ShapeUnoEventAcess_BASE
1375 private:
1376 ScShapeObj* mpShape;
1378 ScMacroInfo* getInfo( BOOL bCreate = FALSE )
1380 return lcl_getShapeHyperMacroInfo( mpShape, bCreate );
1383 public:
1384 ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
1388 // XNameReplace
1389 virtual void SAL_CALL replaceByName( const rtl::OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
1391 if ( !hasByName( aName ) )
1392 throw container::NoSuchElementException();
1393 uno::Sequence< beans::PropertyValue > aProperties;
1394 aElement >>= aProperties;
1395 const beans::PropertyValue* pProperties = aProperties.getConstArray();
1396 const sal_Int32 nCount = aProperties.getLength();
1397 sal_Int32 nIndex;
1398 bool isEventType = false;
1399 for( nIndex = 0; nIndex < nCount; nIndex++, pProperties++ )
1401 if ( pProperties->Name.equals( SC_EVENTACC_EVENTTYPE ) )
1403 isEventType = true;
1404 continue;
1406 if ( isEventType && (pProperties->Name == SC_EVENTACC_SCRIPT) )
1408 rtl::OUString sValue;
1409 if ( pProperties->Value >>= sValue )
1411 ScMacroInfo* pInfo = getInfo( TRUE );
1412 DBG_ASSERT( pInfo, "shape macro info could not be created!" );
1413 if ( !pInfo )
1414 break;
1415 if ( pProperties->Name == SC_EVENTACC_SCRIPT )
1416 pInfo->SetMacro( sValue );
1417 else
1418 pInfo->SetHlink( sValue );
1424 // XNameAccess
1425 virtual uno::Any SAL_CALL getByName( const rtl::OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
1427 uno::Sequence< beans::PropertyValue > aProperties;
1428 ScMacroInfo* pInfo = getInfo();
1430 if ( aName == SC_EVENTACC_ONCLICK )
1432 if ( pInfo && (pInfo->GetMacro().getLength() > 0) )
1434 aProperties.realloc( 2 );
1435 aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
1436 aProperties[ 0 ].Value <<= SC_EVENTACC_SCRIPT;
1437 aProperties[ 1 ].Name = SC_EVENTACC_SCRIPT;
1438 aProperties[ 1 ].Value <<= pInfo->GetMacro();
1441 else
1443 throw container::NoSuchElementException();
1446 return uno::Any( aProperties );
1449 virtual uno::Sequence< rtl::OUString > SAL_CALL getElementNames() throw(uno::RuntimeException)
1451 uno::Sequence< rtl::OUString > aSeq( 1 );
1452 aSeq[ 0 ] = SC_EVENTACC_ONCLICK;
1453 return aSeq;
1456 virtual sal_Bool SAL_CALL hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
1458 return aName == SC_EVENTACC_ONCLICK;
1461 // XElementAccess
1462 virtual uno::Type SAL_CALL getElementType() throw(uno::RuntimeException)
1464 return *SEQTYPE(::getCppuType((const uno::Sequence< beans::PropertyValue >*)0));
1467 virtual sal_Bool SAL_CALL hasElements() throw(uno::RuntimeException)
1469 // elements are always present (but contained property sequences may be empty)
1470 return sal_True;
1474 ::uno::Reference< container::XNameReplace > SAL_CALL
1475 ScShapeObj::getEvents( ) throw(uno::RuntimeException)
1477 return new ShapeUnoEventAccessImpl( this );
1480 ::rtl::OUString SAL_CALL ScShapeObj::getImplementationName( ) throw (uno::RuntimeException)
1482 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sc.ScShapeObj" ) );
1485 ::sal_Bool SAL_CALL ScShapeObj::supportsService( const ::rtl::OUString& _ServiceName ) throw (uno::RuntimeException)
1487 uno::Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
1488 for ( const ::rtl::OUString* pSupported = aSupported.getConstArray();
1489 pSupported != aSupported.getConstArray() + aSupported.getLength();
1490 ++pSupported
1492 if ( _ServiceName == *pSupported )
1493 return sal_True;
1494 return sal_False;
1497 uno::Sequence< ::rtl::OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( ) throw (uno::RuntimeException)
1499 uno::Reference<lang::XServiceInfo> xSI;
1500 if ( mxShapeAgg.is() )
1501 mxShapeAgg->queryAggregation( lang::XServiceInfo::static_type() ) >>= xSI;
1503 uno::Sequence< ::rtl::OUString > aSupported;
1504 if ( xSI.is() )
1505 aSupported = xSI->getSupportedServiceNames();
1507 aSupported.realloc( aSupported.getLength() + 1 );
1508 aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) );
1509 return aSupported;