| /************************************************************** |
| * |
| * 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; |
| } |