summaryrefslogtreecommitdiff
path: root/sc/source/ui/unoobj/shapeuno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/unoobj/shapeuno.cxx')
-rw-r--r--sc/source/ui/unoobj/shapeuno.cxx1521
1 files changed, 1521 insertions, 0 deletions
diff --git a/sc/source/ui/unoobj/shapeuno.cxx b/sc/source/ui/unoobj/shapeuno.cxx
new file mode 100644
index 000000000000..1ed384ed2ebd
--- /dev/null
+++ b/sc/source/ui/unoobj/shapeuno.cxx
@@ -0,0 +1,1521 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <tools/debug.hxx>
+#include <comphelper/uno3.hxx>
+#include <comphelper/stl_types.hxx>
+#include <svtools/unoevent.hxx>
+#include <svtools/unoimap.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/unoshape.hxx>
+#include <editeng/unofield.hxx>
+#include <svx/shapepropertynotifier.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include "shapeuno.hxx"
+#include "miscuno.hxx"
+#include "cellsuno.hxx"
+#include "textuno.hxx"
+#include "fielduno.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "unonames.hxx"
+#include "unoguard.hxx"
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence< sal_Int8 > *, ScShapeImplementationIdMap );
+
+static ScShapeImplementationIdMap aImplementationIdMap;
+
+const SfxItemPropertyMapEntry* lcl_GetShapeMap()
+{
+ static SfxItemPropertyMapEntry aShapeMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_ANCHOR), 0, &getCppuType((uno::Reference<uno::XInterface>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_HORIPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_IMAGEMAP), 0, &getCppuType((uno::Reference<container::XIndexContainer>*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNONAME_VERTPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aShapeMap_Impl;
+}
+
+// static
+const SvEventDescription* ScShapeObj::GetSupportedMacroItems()
+{
+ static const SvEventDescription aMacroDescriptionsImpl[] =
+ {
+ { 0, NULL }
+ };
+ return aMacroDescriptionsImpl;
+}
+
+//------------------------------------------------------------------------
+
+namespace
+{
+ void lcl_initializeNotifier( SdrObject& _rSdrObj, ::cppu::OWeakObject& _rShape )
+ {
+ ::svx::PPropertyValueProvider pProvider( new ::svx::PropertyValueProvider( _rShape, "Anchor" ) );
+ _rSdrObj.getShapePropertyChangeNotifier().registerProvider( ::svx::eSpreadsheetAnchor, pProvider );
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) :
+ pShapePropertySet(NULL),
+ pShapePropertyState(NULL),
+ pImplementationId(NULL),
+ bIsTextShape(FALSE),
+ bInitializedNotifier(false)
+{
+ comphelper::increment( m_refCount );
+
+ {
+ mxShapeAgg = uno::Reference<uno::XAggregation>( xShape, uno::UNO_QUERY );
+ // extra block to force deletion of the temporary before setDelegator
+ }
+
+ if (mxShapeAgg.is())
+ {
+ xShape = NULL; // during setDelegator, mxShapeAgg must be the only ref
+
+ mxShapeAgg->setDelegator( (cppu::OWeakObject*)this );
+
+ xShape.set(uno::Reference<drawing::XShape>( mxShapeAgg, uno::UNO_QUERY ));
+
+ bIsTextShape = ( SvxUnoTextBase::getImplementation( mxShapeAgg ) != NULL );
+ }
+
+ {
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ lcl_initializeNotifier( *pObj, *this );
+ bInitializedNotifier = true;
+ }
+ }
+
+ comphelper::decrement( m_refCount );
+}
+
+ScShapeObj::~ScShapeObj()
+{
+// if (mxShapeAgg.is())
+// mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>());
+}
+
+// XInterface
+
+uno::Any SAL_CALL ScShapeObj::queryInterface( const uno::Type& rType )
+ throw(uno::RuntimeException)
+{
+ uno::Any aRet = ScShapeObj_Base::queryInterface( rType );
+
+ if ( !aRet.hasValue() && bIsTextShape )
+ aRet = ScShapeObj_TextBase::queryInterface( rType );
+
+ if ( !aRet.hasValue() && mxShapeAgg.is() )
+ aRet = mxShapeAgg->queryAggregation( rType );
+
+ return aRet;
+}
+
+void SAL_CALL ScShapeObj::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ScShapeObj::release() throw()
+{
+ OWeakObject::release();
+}
+
+void ScShapeObj::GetShapePropertySet()
+{
+ // #i61908# Store the result of queryAggregation in a member.
+ // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
+
+ if (!pShapePropertySet)
+ {
+ uno::Reference<beans::XPropertySet> xProp;
+ if ( mxShapeAgg.is() )
+ mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertySet>*) 0) ) >>= xProp;
+ pShapePropertySet = xProp.get();
+ }
+}
+
+void ScShapeObj::GetShapePropertyState()
+{
+ // #i61908# Store the result of queryAggregation in a member.
+ // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
+
+ if (!pShapePropertyState)
+ {
+ uno::Reference<beans::XPropertyState> xState;
+ if ( mxShapeAgg.is() )
+ mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertyState>*) 0) ) >>= xState;
+ pShapePropertyState = xState.get();
+ }
+}
+
+uno::Reference<lang::XComponent> lcl_GetComponent( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<lang::XComponent> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<lang::XComponent>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+uno::Reference<text::XText> lcl_GetText( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<text::XText> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<text::XText>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+uno::Reference<text::XSimpleText> lcl_GetSimpleText( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<text::XSimpleText> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<text::XSimpleText>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+uno::Reference<text::XTextRange> lcl_GetTextRange( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<text::XTextRange> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<text::XTextRange>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+// XPropertySet
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScShapeObj::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // #i61527# cache property set info for this object
+ if ( !mxPropSetInfo.is() )
+ {
+ // mix own and aggregated properties:
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ {
+ uno::Reference<beans::XPropertySetInfo> xAggInfo(pShapePropertySet->getPropertySetInfo());
+ const uno::Sequence<beans::Property> aPropSeq(xAggInfo->getProperties());
+ mxPropSetInfo.set(new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), aPropSeq ));
+ }
+ }
+ return mxPropSetInfo;
+}
+
+BOOL lcl_GetPageNum( SdrPage* pPage, SdrModel& rModel, SCTAB& rNum )
+{
+ USHORT nCount = rModel.GetPageCount();
+ for (USHORT i=0; i<nCount; i++)
+ if ( rModel.GetPage(i) == pPage )
+ {
+ rNum = static_cast<SCTAB>(i);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL lcl_GetCaptionPoint( uno::Reference< drawing::XShape >& xShape, awt::Point& rCaptionPoint )
+{
+ BOOL bReturn = FALSE;
+ rtl::OUString sType(xShape->getShapeType());
+ sal_Bool bCaptionShape(sType.equalsAscii("com.sun.star.drawing.CaptionShape"));
+ if (bCaptionShape)
+ {
+ uno::Reference < beans::XPropertySet > xShapeProp (xShape, uno::UNO_QUERY);
+ if (xShapeProp.is())
+ {
+ xShapeProp->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )) ) >>= rCaptionPoint;
+ bReturn = TRUE;
+ }
+ }
+ return bReturn;
+}
+
+ScRange lcl_GetAnchorCell( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab,
+ awt::Point& rUnoPoint, awt::Size& rUnoSize, awt::Point& rCaptionPoint )
+{
+ ScRange aReturn;
+ rUnoPoint = xShape->getPosition();
+ rtl::OUString sType(xShape->getShapeType());
+ sal_Bool bCaptionShape(lcl_GetCaptionPoint(xShape, rCaptionPoint));
+ if (pDoc->IsNegativePage(nTab))
+ {
+ rUnoSize = xShape->getSize();
+ rUnoPoint.X += rUnoSize.Width; // the right top point is base
+ if (bCaptionShape)
+ {
+ if (rCaptionPoint.X > 0 && rCaptionPoint.X > rUnoSize.Width)
+ rUnoPoint.X += rCaptionPoint.X - rUnoSize.Width;
+ if (rCaptionPoint.Y < 0)
+ rUnoPoint.Y += rCaptionPoint.Y;
+ }
+ aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
+ }
+ else
+ {
+ if (bCaptionShape)
+ {
+ if (rCaptionPoint.X < 0)
+ rUnoPoint.X += rCaptionPoint.X;
+ if (rCaptionPoint.Y < 0)
+ rUnoPoint.Y += rCaptionPoint.Y;
+ }
+ aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
+ }
+
+ return aReturn;
+}
+
+awt::Point lcl_GetRelativePos( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab, ScRange& rRange,
+ awt::Size& rUnoSize, awt::Point& rCaptionPoint)
+{
+ awt::Point aUnoPoint;
+ rRange = lcl_GetAnchorCell(xShape, pDoc, nTab, aUnoPoint, rUnoSize, rCaptionPoint);
+ if (pDoc->IsNegativePage(nTab))
+ {
+ Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
+ Point aPoint(aRect.TopRight());
+ aUnoPoint.X -= aPoint.X();
+ aUnoPoint.Y -= aPoint.Y();
+ }
+ else
+ {
+ ScRange aRange = pDoc->GetRange( nTab, Rectangle( VCLPoint(aUnoPoint), VCLPoint(aUnoPoint) ));
+ Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
+ Point aPoint(aRect.TopLeft());
+ aUnoPoint.X -= aPoint.X();
+ aUnoPoint.Y -= aPoint.Y();
+ }
+
+ return aUnoPoint;
+}
+
+void SAL_CALL ScShapeObj::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
+ {
+ uno::Reference<sheet::XCellRangeAddressable> xRangeAdd(aValue, uno::UNO_QUERY);
+ if (xRangeAdd.is())
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ table::CellRangeAddress aAddress = xRangeAdd->getRangeAddress();
+ if (nTab == aAddress.Sheet)
+ {
+ if (aAddress.StartRow != aAddress.EndRow) //should be a Spreadsheet
+ {
+ DBG_ASSERT(aAddress.StartRow == 0 && aAddress.EndRow == MAXROW &&
+ aAddress.StartColumn == 0 && aAddress.EndColumn == MAXCOL, "here should be a XSpreadsheet");
+ ScDrawLayer::SetAnchor(pObj, SCA_PAGE);
+ }
+ else
+ {
+ DBG_ASSERT(aAddress.StartRow == aAddress.EndRow &&
+ aAddress.StartColumn == aAddress.EndColumn, "here should be a XCell");
+ ScDrawLayer::SetAnchor(pObj, SCA_CELL);
+ }
+ Rectangle aRect(pDoc->GetMMRect( static_cast<SCCOL>(aAddress.StartColumn), static_cast<SCROW>(aAddress.StartRow),
+ static_cast<SCCOL>(aAddress.EndColumn), static_cast<SCROW>(aAddress.EndRow), aAddress.Sheet ));
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ Point aPoint;
+ Point aEndPoint;
+ if (pDoc->IsNegativePage(nTab))
+ {
+ aPoint = aRect.TopRight();
+ aEndPoint = aRect.BottomLeft();
+ }
+ else
+ {
+ aPoint = aRect.TopLeft();
+ aEndPoint = aRect.BottomRight();
+ }
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+
+ aUnoPoint.X += aPoint.X();
+ aUnoPoint.Y += aPoint.Y();
+
+ if ( aUnoPoint.Y > aEndPoint.Y() )
+ aUnoPoint.Y = aEndPoint.Y() - 2;
+ if (pDoc->IsNegativePage(nTab))
+ {
+ if ( aUnoPoint.X < aEndPoint.X() )
+ aUnoPoint.X = aEndPoint.X() + 2;
+ aUnoPoint.X -= aUnoSize.Width;
+ // remove difference to caption point
+ if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
+ aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
+ }
+ else
+ {
+ if ( aUnoPoint.X > aEndPoint.X() )
+ aUnoPoint.X = aEndPoint.X() - 2;
+ if (aCaptionPoint.X < 0)
+ aUnoPoint.X -= aCaptionPoint.X;
+ }
+ if (aCaptionPoint.Y < 0)
+ aUnoPoint.Y -= aCaptionPoint.Y;
+
+ xShape->setPosition(aUnoPoint);
+ pDocSh->SetModified();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("only XCell or XSpreadsheet objects allowed")), static_cast<cppu::OWeakObject*>(this), 0);
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ ImageMap aImageMap;
+ uno::Reference< uno::XInterface > xImageMapInt(aValue, uno::UNO_QUERY);
+
+ if( !xImageMapInt.is() || !SvUnoImageMap_fillImageMap( xImageMapInt, aImageMap ) )
+ throw lang::IllegalArgumentException();
+
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
+ if( pIMapInfo )
+ {
+ // replace existing image map
+ pIMapInfo->SetImageMap( aImageMap );
+ }
+ else
+ {
+ // insert new user data with image map
+ pObj->InsertUserData(new ScIMapInfo(aImageMap) );
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
+ {
+ sal_Int32 nPos = 0;
+ if (aValue >>= nPos)
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE)
+ {
+ awt::Point aPoint(xShape->getPosition());
+ awt::Size aSize(xShape->getSize());
+ awt::Point aCaptionPoint;
+ if (pDoc->IsNegativePage(nTab))
+ {
+ nPos *= -1;
+ nPos -= aSize.Width;
+ }
+ if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
+ {
+ if (pDoc->IsNegativePage(nTab))
+ {
+ if (aCaptionPoint.X > 0 && aCaptionPoint.X > aSize.Width)
+ nPos -= aCaptionPoint.X - aSize.Width;
+ }
+ else
+ {
+ if (aCaptionPoint.X < 0)
+ nPos -= aCaptionPoint.X;
+ }
+ }
+ aPoint.X = nPos;
+ xShape->setPosition(aPoint);
+ pDocSh->SetModified();
+ }
+ else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+ Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
+ if (pDoc->IsNegativePage(nTab))
+ {
+ aUnoPoint.X = -nPos;
+ Point aPoint(aRect.TopRight());
+ Point aEndPoint(aRect.BottomLeft());
+ aUnoPoint.X += aPoint.X();
+ if (aUnoPoint.X < aEndPoint.X())
+ aUnoPoint.X = aEndPoint.X() + 2;
+ aUnoPoint.X -= aUnoSize.Width;
+ if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
+ aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
+ }
+ else
+ {
+ aUnoPoint.X = nPos;
+ Point aPoint(aRect.TopLeft());
+ Point aEndPoint(aRect.BottomRight());
+ aUnoPoint.X += aPoint.X();
+ if (aUnoPoint.X > aEndPoint.X())
+ aUnoPoint.X = aEndPoint.X() - 2;
+ if (aCaptionPoint.X < 0)
+ aUnoPoint.X -= aCaptionPoint.X;
+ }
+ aUnoPoint.Y = xShape->getPosition().Y;
+ xShape->setPosition(aUnoPoint);
+ pDocSh->SetModified();
+ }
+ else
+ {
+ DBG_ERROR("unknown anchor type");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
+ {
+ sal_Int32 nPos = 0;
+ if (aValue >>= nPos)
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE)
+ {
+ awt::Point aPoint = xShape->getPosition();
+ awt::Point aCaptionPoint;
+ if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
+ {
+ if (aCaptionPoint.Y < 0)
+ nPos -= aCaptionPoint.Y;
+ }
+ aPoint.Y = nPos;
+ xShape->setPosition(aPoint);
+ pDocSh->SetModified();
+ }
+ else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+ Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
+ Point aPoint(aRect.TopRight());
+ Point aEndPoint(aRect.BottomLeft());
+ aUnoPoint.Y = nPos;
+ aUnoPoint.Y += aPoint.Y();
+ if (aUnoPoint.Y > aEndPoint.Y())
+ aUnoPoint.Y = aEndPoint.Y() - 2;
+ if (aCaptionPoint.Y < 0)
+ aUnoPoint.Y -= aCaptionPoint.Y;
+ aUnoPoint.X = xShape->getPosition().X;
+ xShape->setPosition(aUnoPoint);
+ pDocSh->SetModified();
+ }
+ else
+ {
+ DBG_ERROR("unknown anchor type");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->setPropertyValue( aPropertyName, aValue );
+ }
+}
+
+uno::Any SAL_CALL ScShapeObj::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString = aPropertyName;
+
+ uno::Any aAny;
+ if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+ uno::Reference< uno::XInterface > xAnchor;
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+
+ xAnchor.set(static_cast<cppu::OWeakObject*>(new ScCellObj( pDocSh, aRange.aStart )));
+ }
+ }
+ else
+ {
+ xAnchor.set(static_cast<cppu::OWeakObject*>(new ScTableSheetObj( pDocSh, nTab )));
+ }
+ aAny <<= xAnchor;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ uno::Reference< uno::XInterface > xImageMap;
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(GetSdrObject());
+ if( pIMapInfo )
+ {
+ const ImageMap& rIMap = pIMapInfo->GetImageMap();
+ xImageMap.set(SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() ));
+ }
+ else
+ xImageMap = SvUnoImageMap_createInstance( GetSupportedMacroItems() );
+ }
+ aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+ if (pDoc->IsNegativePage(nTab))
+ aUnoPoint.X *= -1;
+ aAny <<= aUnoPoint.X;
+ }
+ else
+ {
+ awt::Point aCaptionPoint;
+ awt::Point aUnoPoint(xShape->getPosition());
+ awt::Size aUnoSize(xShape->getSize());
+ if (pDoc->IsNegativePage(nTab))
+ {
+ aUnoPoint.X *= -1;
+ aUnoPoint.X -= aUnoSize.Width;
+ }
+ if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
+ {
+ if (pDoc->IsNegativePage(nTab))
+ {
+ if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
+ aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
+ }
+ else
+ {
+ if (aCaptionPoint.X < 0)
+ aUnoPoint.X += aCaptionPoint.X;
+ }
+ }
+ aAny <<= aUnoPoint.X;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
+ {
+ SdrObject *pObj = GetSdrObject();
+ if (pObj)
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel && pPage )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
+ if (xShape.is())
+ {
+ uno::Reference< uno::XInterface > xAnchor;
+ if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ awt::Size aUnoSize;
+ awt::Point aCaptionPoint;
+ ScRange aRange;
+ awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
+
+ aAny <<= aUnoPoint.Y;
+ }
+ else
+ {
+ awt::Point aUnoPoint(xShape->getPosition());
+ awt::Point aCaptionPoint;
+ if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
+ {
+ if (aCaptionPoint.Y < 0)
+ aUnoPoint.Y += aCaptionPoint.Y;
+ }
+ aAny <<= aUnoPoint.Y;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ aAny = pShapePropertySet->getPropertyValue( aPropertyName );
+ }
+
+ return aAny;
+}
+
+void SAL_CALL ScShapeObj::addPropertyChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XPropertyChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->addPropertyChangeListener( aPropertyName, aListener );
+
+ if ( !bInitializedNotifier )
+ {
+ // here's the latest chance to initialize the property notification at the SdrObject
+ // (in the ctor, where we also attempt to do this, we do not necessarily have
+ // and SdrObject, yet)
+ SdrObject* pObj = GetSdrObject();
+ OSL_ENSURE( pObj, "ScShapeObj::addPropertyChangeListener: no SdrObject -> no property change notification!" );
+ if ( pObj )
+ lcl_initializeNotifier( *pObj, *this );
+ bInitializedNotifier = true;
+ }
+}
+
+void SAL_CALL ScShapeObj::removePropertyChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XPropertyChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->removePropertyChangeListener( aPropertyName, aListener );
+}
+
+void SAL_CALL ScShapeObj::addVetoableChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XVetoableChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->addVetoableChangeListener( aPropertyName, aListener );
+}
+
+void SAL_CALL ScShapeObj::removeVetoableChangeListener( const rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XVetoableChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ GetShapePropertySet();
+ if (pShapePropertySet)
+ pShapePropertySet->removeVetoableChangeListener( aPropertyName, aListener );
+}
+
+// XPropertyState
+
+beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+
+ beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
+ if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ // ImageMap is always "direct"
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
+ {
+ // Anchor is always "direct"
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
+ {
+ // HoriPos is always "direct"
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
+ {
+ // VertPos is always "direct"
+ }
+ else
+ {
+ GetShapePropertyState();
+ if (pShapePropertyState)
+ eRet = pShapePropertyState->getPropertyState( aPropertyName );
+ }
+
+ return eRet;
+}
+
+uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates(
+ const uno::Sequence<rtl::OUString>& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // simple loop to get own and aggregated states
+
+ const rtl::OUString* pNames = aPropertyNames.getConstArray();
+ uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
+ pStates[i] = getPropertyState(pNames[i]);
+ return aRet;
+}
+
+void SAL_CALL ScShapeObj::setPropertyToDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString(aPropertyName);
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
+ if( pIMapInfo )
+ {
+ ImageMap aEmpty;
+ pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map
+ }
+ else
+ {
+ // nothing to do (no need to insert user data for an empty map)
+ }
+ }
+ }
+ else
+ {
+ GetShapePropertyState();
+ if (pShapePropertyState)
+ pShapePropertyState->setPropertyToDefault( aPropertyName );
+ }
+}
+
+uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ String aNameString = aPropertyName;
+
+ uno::Any aAny;
+ if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ // default: empty ImageMap
+ uno::Reference< uno::XInterface > xImageMap(SvUnoImageMap_createInstance( GetSupportedMacroItems() ));
+ aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
+ }
+ else
+ {
+ GetShapePropertyState();
+ if (pShapePropertyState)
+ aAny = pShapePropertyState->getPropertyDefault( aPropertyName );
+ }
+
+ return aAny;
+}
+
+// XTextContent
+
+void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& /* xTextRange */ )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ throw lang::IllegalArgumentException(); // anchor cannot be changed
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xRet;
+
+ SdrObject* pObj = GetSdrObject();
+ if( pObj )
+ {
+ ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
+ SdrPage* pPage = pObj->GetPage();
+ if ( pModel )
+ {
+ ScDocument* pDoc = pModel->GetDocument();
+ if ( pDoc )
+ {
+ SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
+ if ( pObjSh && pObjSh->ISA(ScDocShell) )
+ {
+ ScDocShell* pDocSh = (ScDocShell*)pObjSh;
+
+ SCTAB nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ Point aPos(pObj->GetCurrentBoundRect().TopLeft());
+ ScRange aRange(pDoc->GetRange( nTab, Rectangle( aPos, aPos ) ));
+
+ // anchor is always the cell
+
+ xRet.set(new ScCellObj( pDocSh, aRange.aStart ));
+ }
+ }
+ }
+ }
+ }
+
+ return xRet;
+}
+
+// XComponent
+
+void SAL_CALL ScShapeObj::dispose() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
+ if ( xAggComp.is() )
+ xAggComp->dispose();
+}
+
+void SAL_CALL ScShapeObj::addEventListener(
+ const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
+ if ( xAggComp.is() )
+ xAggComp->addEventListener(xListener);
+}
+
+void SAL_CALL ScShapeObj::removeEventListener(
+ const uno::Reference<lang::XEventListener>& xListener )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
+ if ( xAggComp.is() )
+ xAggComp->removeEventListener(xListener);
+}
+
+// XText
+// (special handling for ScCellFieldObj)
+
+void lcl_CopyOneProperty( beans::XPropertySet& rDest, beans::XPropertySet& rSource, const sal_Char* pName )
+{
+ rtl::OUString aNameStr(rtl::OUString::createFromAscii(pName));
+ try
+ {
+ rDest.setPropertyValue( aNameStr, rSource.getPropertyValue( aNameStr ) );
+ }
+ catch (uno::Exception&)
+ {
+ DBG_ERROR("Exception in text field");
+ }
+}
+
+void SAL_CALL ScShapeObj::insertTextContent( const uno::Reference<text::XTextRange>& xRange,
+ const uno::Reference<text::XTextContent>& xContent,
+ sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextContent> xEffContent;
+
+ ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent );
+ if ( pCellField )
+ {
+ // #105585# createInstance("TextField.URL") from the document creates a ScCellFieldObj.
+ // To insert it into drawing text, a SvxUnoTextField is needed instead.
+ // The ScCellFieldObj object is left in non-inserted state.
+
+ SvxUnoTextField* pDrawField = new SvxUnoTextField( ID_URLFIELD );
+ xEffContent.set(pDrawField);
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL );
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR );
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET );
+ }
+ else
+ xEffContent.set(xContent);
+
+ uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
+ if ( xAggText.is() )
+ xAggText->insertTextContent( xRange, xEffContent, bAbsorb );
+}
+
+void SAL_CALL ScShapeObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
+ throw(container::NoSuchElementException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ // ScCellFieldObj can't be used here.
+
+ uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
+ if ( xAggText.is() )
+ xAggText->removeTextContent( xContent );
+}
+
+// XSimpleText (parent of XText)
+// Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object
+
+uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursor()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( mxShapeAgg.is() )
+ {
+ // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
+
+ SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
+ if (pText)
+ return new ScDrawTextCursor( this, *pText );
+ }
+
+ return uno::Reference<text::XTextCursor>();
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursorByRange(
+ const uno::Reference<text::XTextRange>& aTextPosition )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ if ( mxShapeAgg.is() && aTextPosition.is() )
+ {
+ // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
+
+ SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
+ if ( pText && pRange )
+ {
+ SvxUnoTextCursor* pCursor = new ScDrawTextCursor( this, *pText );
+ uno::Reference<text::XTextCursor> xCursor( pCursor );
+ pCursor->SetSelection( pRange->GetSelection() );
+ return xCursor;
+ }
+ }
+
+ return uno::Reference<text::XTextCursor>();
+}
+
+void SAL_CALL ScShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange,
+ const rtl::OUString& aString, sal_Bool bAbsorb )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
+ if ( xAggSimpleText.is() )
+ xAggSimpleText->insertString( xRange, aString, bAbsorb );
+ else
+ throw uno::RuntimeException();
+}
+
+void SAL_CALL ScShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
+ if ( xAggSimpleText.is() )
+ xAggSimpleText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
+ else
+ throw uno::RuntimeException();
+}
+
+// XTextRange
+// (parent of XSimpleText)
+
+uno::Reference<text::XText> SAL_CALL ScShapeObj::getText() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ return this;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
+ if ( xAggTextRange.is() )
+ return xAggTextRange->getStart();
+ else
+ throw uno::RuntimeException();
+
+// return uno::Reference<text::XTextRange>();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getEnd() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
+ if ( xAggTextRange.is() )
+ return xAggTextRange->getEnd();
+ else
+ throw uno::RuntimeException();
+
+// return uno::Reference<text::XTextRange>();
+}
+
+rtl::OUString SAL_CALL ScShapeObj::getString() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
+ if ( xAggTextRange.is() )
+ return xAggTextRange->getString();
+ else
+ throw uno::RuntimeException();
+
+// return rtl::OUString();
+}
+
+void SAL_CALL ScShapeObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
+ if ( xAggTextRange.is() )
+ xAggTextRange->setString( aText );
+ else
+ throw uno::RuntimeException();
+}
+
+// XTypeProvider
+
+uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes() throw(uno::RuntimeException)
+{
+ uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() );
+
+ uno::Sequence< uno::Type > aTextTypes;
+ if ( bIsTextShape )
+ aTextTypes = ScShapeObj_TextBase::getTypes();
+
+ uno::Reference<lang::XTypeProvider> xBaseProvider;
+ if ( mxShapeAgg.is() )
+ mxShapeAgg->queryAggregation( getCppuType((uno::Reference<lang::XTypeProvider>*) 0) ) >>= xBaseProvider;
+ DBG_ASSERT( xBaseProvider.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" );
+
+ uno::Sequence< uno::Type > aAggTypes;
+ if( xBaseProvider.is() )
+ aAggTypes = xBaseProvider->getTypes();
+
+ return ::comphelper::concatSequences( aBaseTypes, aTextTypes, aAggTypes );
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ // do we need to compute the implementation id for this instance?
+ if( !pImplementationId && mxShapeAgg.is())
+ {
+ uno::Reference< drawing::XShape > xAggShape;
+ mxShapeAgg->queryAggregation( ::getCppuType((uno::Reference< drawing::XShape >*)0) ) >>= xAggShape;
+
+ if( xAggShape.is() )
+ {
+ const rtl::OUString aShapeType( xAggShape->getShapeType() );
+ // did we already compute an implementation id for the agregated shape type?
+ ScShapeImplementationIdMap::iterator aIter( aImplementationIdMap.find(aShapeType ) );
+ if( aIter == aImplementationIdMap.end() )
+ {
+ // we need to create a new implementation id for this
+ // note: this memory is not free'd until application exists
+ // but since we have a fixed set of shapetypes and the
+ // memory will be reused this is ok.
+ pImplementationId = new uno::Sequence< sal_Int8 >( 16 );
+ rtl_createUuid( (sal_uInt8 *) pImplementationId->getArray(), 0, sal_True );
+ aImplementationIdMap[ aShapeType ] = pImplementationId;
+ }
+ else
+ {
+ // use the already computed implementation id
+ pImplementationId = (*aIter).second;
+ }
+ }
+ }
+ if( NULL == pImplementationId )
+ {
+ DBG_ERROR( "Could not create an implementation id for a ScXShape!" );
+ return uno::Sequence< sal_Int8 > ();
+ }
+ else
+ {
+ return *pImplementationId;
+ }
+}
+
+SdrObject* ScShapeObj::GetSdrObject() const throw()
+{
+ if(mxShapeAgg.is())
+ {
+ SvxShape* pShape = SvxShape::getImplementation( mxShapeAgg );
+ if(pShape)
+ return pShape->GetSdrObject();
+ }
+
+ return NULL;
+}
+
+#define SC_EVENTACC_ONCLICK ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) )
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+#define SC_EVENTACC_ONACTION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAction" ) )
+#define SC_EVENTACC_URL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) )
+#define SC_EVENTACC_ACTION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Action" ) )
+#endif
+#define SC_EVENTACC_SCRIPT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Script" ) )
+#define SC_EVENTACC_EVENTTYPE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) )
+
+typedef ::cppu::WeakImplHelper1< container::XNameReplace > ShapeUnoEventAcess_BASE;
+class ShapeUnoEventAccessImpl : public ShapeUnoEventAcess_BASE
+{
+private:
+ ScShapeObj* mpShape;
+
+ ScMacroInfo* getInfo( BOOL bCreate = FALSE )
+ {
+ if( mpShape )
+ if( SdrObject* pObj = mpShape->GetSdrObject() )
+ return ScDrawLayer::GetMacroInfo( pObj, bCreate );
+ return 0;
+ }
+
+public:
+ ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
+ {
+ }
+
+ // XNameReplace
+ virtual void SAL_CALL replaceByName( const rtl::OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+ uno::Sequence< beans::PropertyValue > aProperties;
+ aElement >>= aProperties;
+ const beans::PropertyValue* pProperties = aProperties.getConstArray();
+ const sal_Int32 nCount = aProperties.getLength();
+ sal_Int32 nIndex;
+ bool isEventType = false;
+ for( nIndex = 0; nIndex < nCount; nIndex++, pProperties++ )
+ {
+ if ( pProperties->Name.equals( SC_EVENTACC_EVENTTYPE ) )
+ {
+ isEventType = true;
+ continue;
+ }
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ if ( isEventType && ((pProperties->Name == SC_EVENTACC_SCRIPT) || (pProperties->Name == SC_EVENTACC_URL)) )
+#else
+ if ( isEventType && (pProperties->Name == SC_EVENTACC_SCRIPT) )
+#endif
+ {
+ rtl::OUString sValue;
+ if ( pProperties->Value >>= sValue )
+ {
+ ScMacroInfo* pInfo = getInfo( TRUE );
+ DBG_ASSERT( pInfo, "shape macro info could not be created!" );
+ if ( !pInfo )
+ break;
+ if ( pProperties->Name == SC_EVENTACC_SCRIPT )
+ pInfo->SetMacro( sValue );
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ else
+ pInfo->SetHlink( sValue );
+#endif
+ }
+ }
+ }
+ }
+
+ // XNameAccess
+ virtual uno::Any SAL_CALL getByName( const rtl::OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ uno::Sequence< beans::PropertyValue > aProperties;
+ ScMacroInfo* pInfo = getInfo();
+
+ if ( aName == SC_EVENTACC_ONCLICK )
+ {
+ if ( pInfo && (pInfo->GetMacro().getLength() > 0) )
+ {
+ aProperties.realloc( 2 );
+ aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
+ aProperties[ 0 ].Value <<= SC_EVENTACC_SCRIPT;
+ aProperties[ 1 ].Name = SC_EVENTACC_SCRIPT;
+ aProperties[ 1 ].Value <<= pInfo->GetMacro();
+ }
+ }
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ else if( aName == SC_EVENTACC_ONACTION )
+ {
+ if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
+ {
+ aProperties.realloc( 2 );
+ aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
+ aProperties[ 0 ].Value <<= SC_EVENTACC_ACTION;
+ aProperties[ 1 ].Name = SC_EVENTACC_URL;
+ aProperties[ 1 ].Value <<= pInfo->GetHlink();
+ }
+ }
+#endif
+ else
+ {
+ throw container::NoSuchElementException();
+ }
+
+ return uno::Any( aProperties );
+ }
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL getElementNames() throw(uno::RuntimeException)
+ {
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ uno::Sequence< rtl::OUString > aSeq( 2 );
+#else
+ uno::Sequence< rtl::OUString > aSeq( 1 );
+#endif
+ aSeq[ 0 ] = SC_EVENTACC_ONCLICK;
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ aSeq[ 1 ] = SC_EVENTACC_ONACTION;
+#endif
+ return aSeq;
+ }
+
+ virtual sal_Bool SAL_CALL hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+ {
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ return (aName == SC_EVENTACC_ONCLICK) || (aName == SC_EVENTACC_ONACTION);
+#else
+ return aName == SC_EVENTACC_ONCLICK;
+#endif
+ }
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() throw(uno::RuntimeException)
+ {
+ return *SEQTYPE(::getCppuType((const uno::Sequence< beans::PropertyValue >*)0));
+ }
+
+ virtual sal_Bool SAL_CALL hasElements() throw(uno::RuntimeException)
+ {
+ // elements are always present (but contained property sequences may be empty)
+ return sal_True;
+ }
+};
+
+::uno::Reference< container::XNameReplace > SAL_CALL
+ScShapeObj::getEvents( ) throw(uno::RuntimeException)
+{
+ return new ShapeUnoEventAccessImpl( this );
+}
+
+::rtl::OUString SAL_CALL ScShapeObj::getImplementationName( ) throw (uno::RuntimeException)
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sc.ScShapeObj" ) );
+}
+
+::sal_Bool SAL_CALL ScShapeObj::supportsService( const ::rtl::OUString& _ServiceName ) throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
+ for ( const ::rtl::OUString* pSupported = aSupported.getConstArray();
+ pSupported != aSupported.getConstArray() + aSupported.getLength();
+ ++pSupported
+ )
+ if ( _ServiceName == *pSupported )
+ return sal_True;
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( ) throw (uno::RuntimeException)
+{
+ uno::Reference<lang::XServiceInfo> xSI;
+ if ( mxShapeAgg.is() )
+ mxShapeAgg->queryAggregation( lang::XServiceInfo::static_type() ) >>= xSI;
+
+ uno::Sequence< ::rtl::OUString > aSupported;
+ if ( xSI.is() )
+ aSupported = xSI->getSupportedServiceNames();
+
+ aSupported.realloc( aSupported.getLength() + 1 );
+ aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) );
+ return aSupported;
+}