summaryrefslogtreecommitdiff
path: root/binfilter/bf_sc/source/ui/unoobj/sc_shapeuno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sc/source/ui/unoobj/sc_shapeuno.cxx')
-rw-r--r--binfilter/bf_sc/source/ui/unoobj/sc_shapeuno.cxx800
1 files changed, 800 insertions, 0 deletions
diff --git a/binfilter/bf_sc/source/ui/unoobj/sc_shapeuno.cxx b/binfilter/bf_sc/source/ui/unoobj/sc_shapeuno.cxx
new file mode 100644
index 000000000000..80d3d11113aa
--- /dev/null
+++ b/binfilter/bf_sc/source/ui/unoobj/sc_shapeuno.cxx
@@ -0,0 +1,800 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#include <comphelper/uno3.hxx>
+#include <bf_svtools/unoevent.hxx>
+#include <bf_svtools/unoimap.hxx>
+#include <bf_svx/unoshape.hxx>
+#include <bf_svx/unofield.hxx>
+
+
+#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 <vcl/svapp.hxx>
+
+#include <comphelper/stl_types.hxx>
+namespace binfilter {
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence< sal_Int8 > *, ScShapeImplementationIdMap );
+
+static ScShapeImplementationIdMap aImplementationIdMap;
+
+const SfxItemPropertyMap* lcl_GetShapeMap()
+{
+ static SfxItemPropertyMap aShapeMap_Impl[] =
+ {
+ {MAP_CHAR_LEN(SC_UNONAME_IMAGEMAP), 0, &getCppuType((uno::Reference<container::XIndexContainer>*)0), 0, 0 },
+ {0,0,0,0}
+ };
+ return aShapeMap_Impl;
+}
+
+// static
+const SvEventDescription* ScShapeObj::GetSupportedMacroItems()
+{
+ static const SvEventDescription aMacroDescriptionsImpl[] =
+ {
+ { 0, NULL }
+ };
+ return aMacroDescriptionsImpl;
+}
+
+//------------------------------------------------------------------------
+
+ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape )
+ : pImplementationId(NULL),
+ bIsTextShape(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 = uno::Reference<drawing::XShape>( mxShapeAgg, uno::UNO_QUERY );
+
+ bIsTextShape = ( SvxUnoTextBase::getImplementation( mxShapeAgg ) != NULL );
+ }
+
+ ::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)
+{
+ SC_QUERYINTERFACE( beans::XPropertySet )
+ SC_QUERYINTERFACE( beans::XPropertyState )
+ SC_QUERYINTERFACE( text::XTextContent )
+ SC_QUERYINTERFACE( lang::XComponent )
+ if ( bIsTextShape )
+ {
+ // #105585# for text shapes, XText (and parent interfaces) must
+ // be handled here, too (for ScCellFieldObj handling):
+ SC_QUERYINTERFACE( text::XText )
+ SC_QUERYINTERFACE( text::XSimpleText )
+ SC_QUERYINTERFACE( text::XTextRange )
+ }
+ SC_QUERYINTERFACE( lang::XTypeProvider )
+
+ uno::Any aRet = OWeakObject::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();
+}
+
+uno::Reference<beans::XPropertySet> lcl_GetPropertySet( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<beans::XPropertySet> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertySet>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+uno::Reference<beans::XPropertyState> lcl_GetPropertyState( const uno::Reference<uno::XAggregation>& xAgg )
+{
+ uno::Reference<beans::XPropertyState> xRet;
+ if ( xAgg.is() )
+ xAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertyState>*) 0) ) >>= xRet;
+ return xRet;
+}
+
+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)
+{
+ SolarMutexGuard aGuard;
+
+ // mix own and aggregated properties:
+ uno::Reference<beans::XPropertySetInfo> xRet;
+ uno::Reference<beans::XPropertySet> xAggProp = lcl_GetPropertySet(mxShapeAgg);
+ if ( xAggProp.is() )
+ {
+ uno::Reference<beans::XPropertySetInfo> xAggInfo = xAggProp->getPropertySetInfo();
+ const uno::Sequence<beans::Property> aPropSeq = xAggInfo->getProperties();
+ xRet = new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), aPropSeq );
+ }
+ return xRet;
+}
+
+void SAL_CALL ScShapeObj::setPropertyValue(
+ const ::rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ String aNameString = aPropertyName;
+
+ if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ SdrObject* pObj = GetSdrObject();
+ if ( pObj )
+ {
+ ImageMap aImageMap;
+ uno::Reference< uno::XInterface > xImageMapInt;
+ aValue >>= xImageMapInt;
+
+ 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
+ {
+ uno::Reference<beans::XPropertySet> xAggProp = lcl_GetPropertySet(mxShapeAgg);
+ if ( xAggProp.is() )
+ xAggProp->setPropertyValue( aPropertyName, aValue );
+ }
+}
+
+uno::Any SAL_CALL ScShapeObj::getPropertyValue( const ::rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ String aNameString = aPropertyName;
+
+ uno::Any aAny;
+ 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 = SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() );
+ }
+ else
+ xImageMap = SvUnoImageMap_createInstance( GetSupportedMacroItems() );
+ }
+ aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
+ }
+ else
+ {
+ uno::Reference<beans::XPropertySet> xAggProp = lcl_GetPropertySet(mxShapeAgg);
+ if ( xAggProp.is() )
+ aAny = xAggProp->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)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference<beans::XPropertySet> xAggProp = lcl_GetPropertySet(mxShapeAgg);
+ if ( xAggProp.is() )
+ xAggProp->addPropertyChangeListener( aPropertyName, aListener );
+}
+
+void SAL_CALL ScShapeObj::removePropertyChangeListener( const ::rtl::OUString& aPropertyName,
+ const uno::Reference<beans::XPropertyChangeListener>& aListener)
+ throw(beans::UnknownPropertyException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference<beans::XPropertySet> xAggProp = lcl_GetPropertySet(mxShapeAgg);
+ if ( xAggProp.is() )
+ xAggProp->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)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference<beans::XPropertySet> xAggProp = lcl_GetPropertySet(mxShapeAgg);
+ if ( xAggProp.is() )
+ xAggProp->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)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference<beans::XPropertySet> xAggProp = lcl_GetPropertySet(mxShapeAgg);
+ if ( xAggProp.is() )
+ xAggProp->removeVetoableChangeListener( aPropertyName, aListener );
+}
+
+// XPropertyState
+
+beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const ::rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ String aNameString = aPropertyName;
+
+ beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
+ if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
+ {
+ // ImageMap is always "direct"
+ }
+ else
+ {
+ uno::Reference<beans::XPropertyState> xAggState = lcl_GetPropertyState(mxShapeAgg);
+ if ( xAggState.is() )
+ eRet = xAggState->getPropertyState( aPropertyName );
+ }
+
+ return eRet;
+}
+
+uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates(
+ const uno::Sequence< ::rtl::OUString>& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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
+ {
+ uno::Reference<beans::XPropertyState> xAggState = lcl_GetPropertyState(mxShapeAgg);
+ if ( xAggState.is() )
+ xAggState->setPropertyToDefault( aPropertyName );
+ }
+}
+
+uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const ::rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ SolarMutexGuard 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
+ {
+ uno::Reference<beans::XPropertyState> xAggState = lcl_GetPropertyState(mxShapeAgg);
+ if ( xAggState.is() )
+ aAny = xAggState->getPropertyDefault( aPropertyName );
+ }
+
+ return aAny;
+}
+
+// XTextContent
+
+void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& xTextRange )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ throw lang::IllegalArgumentException(); // anchor cannot be changed
+}
+
+BOOL lcl_GetPageNum( SdrPage* pPage, SdrModel& rModel, USHORT& rNum )
+{
+ USHORT nCount = rModel.GetPageCount();
+ for (USHORT i=0; i<nCount; i++)
+ if ( rModel.GetPage(i) == pPage )
+ {
+ rNum = i;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor() throw(uno::RuntimeException)
+{
+ SolarMutexGuard 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;
+
+ USHORT nTab = 0;
+ if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
+ {
+ Point aPos = pObj->GetBoundRect().TopLeft();
+ ScRange aRange = pDoc->GetRange( nTab, Rectangle( aPos, aPos ) );
+
+ // anchor is always the cell
+
+ xRet = new ScCellObj( pDocSh, aRange.aStart );
+ }
+ }
+ }
+ }
+ }
+
+ return xRet;
+}
+
+// XComponent
+
+void SAL_CALL ScShapeObj::dispose() throw(uno::RuntimeException)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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
+ {
+ uno::Any aValue = rSource.getPropertyValue( aNameStr );
+ rDest.setPropertyValue( aNameStr, aValue );
+ }
+ 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)
+{
+ SolarMutexGuard 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 = pDrawField;
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL );
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR );
+ lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET );
+ }
+ else
+ xEffContent = 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)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard aGuard;
+ return this;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart() throw(uno::RuntimeException)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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)
+{
+ SolarMutexGuard 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 > aTypeSequence;
+
+ 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!" );
+ if( xBaseProvider.is() )
+ {
+ aTypeSequence = xBaseProvider->getTypes();
+ long nBaseLen = aTypeSequence.getLength();
+
+ aTypeSequence.realloc( nBaseLen + 1 );
+ uno::Type* pPtr = aTypeSequence.getArray();
+ pPtr[nBaseLen + 0] = getCppuType((const uno::Reference<text::XTextContent>*)0);
+ }
+ return aTypeSequence;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard 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;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */