blob: 4e471838d78775fd147ff96b8d7271b933df789f [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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),
bIsNoteCaption(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 )
{
bIsNoteCaption = ScDrawLayer::IsNoteCaption( 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() && bIsNoteCaption )
aRet = ScShapeObj_ChildBase::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;
}
sal_Bool lcl_GetPageNum( SdrPage* pPage, SdrModel& rModel, SCTAB& rNum )
{
sal_uInt16 nCount = rModel.GetPageCount();
for (sal_uInt16 i=0; i<nCount; i++)
if ( rModel.GetPage(i) == pPage )
{
rNum = static_cast<SCTAB>(i);
return sal_True;
}
return sal_False;
}
sal_Bool lcl_GetCaptionPoint( uno::Reference< drawing::XShape >& xShape, awt::Point& rCaptionPoint )
{
sal_Bool bReturn = sal_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 = sal_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
{
if(!pShapePropertySet) GetShapePropertySet(); //performance consideration
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();
}
// XChild
uno::Reference< uno::XInterface > SAL_CALL ScShapeObj::getParent() throw (uno::RuntimeException)
{
ScUnoGuard aGuard;
// receive cell position from caption object (parent of a note caption is the note cell)
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 ) )
{
const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab );
if( pCaptData )
return static_cast< ::cppu::OWeakObject* >( new ScCellObj( pDocSh, pCaptData->maStart ) );
}
}
}
}
}
return 0;
}
void SAL_CALL ScShapeObj::setParent( const uno::Reference< uno::XInterface >& ) throw (lang::NoSupportException, uno::RuntimeException)
{
throw lang::NoSupportException();
}
// 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( sal_Bool bCreate = sal_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( sal_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" ) );
if( bIsNoteCaption )
{
aSupported.realloc( aSupported.getLength() + 1 );
aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.CellAnnotationShape" ) );
}
return aSupported;
}