1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <comphelper/propertyvalue.hxx>
23 #include <comphelper/sequence.hxx>
24 #include <svtools/unoevent.hxx>
25 #include <svtools/unoimap.hxx>
26 #include <svx/svdobj.hxx>
27 #include <svx/ImageMapInfo.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/unohelp.hxx>
30 #include <sfx2/event.hxx>
31 #include <editeng/unofield.hxx>
32 #include <toolkit/helper/vclunohelper.hxx>
33 #include <cppuhelper/implbase.hxx>
34 #include <cppuhelper/supportsservice.hxx>
35 #include <comphelper/diagnose_ex.hxx>
37 #include <com/sun/star/beans/PropertyAttribute.hpp>
38 #include <com/sun/star/drawing/XShape.hpp>
39 #include <com/sun/star/lang/NoSupportException.hpp>
41 #include <shapeuno.hxx>
42 #include <cellsuno.hxx>
43 #include <textuno.hxx>
44 #include <fielduno.hxx>
46 #include <drwlayer.hxx>
47 #include <userdat.hxx>
48 #include <unonames.hxx>
49 #include <styleuno.hxx>
51 using namespace ::com::sun::star
;
53 static std::span
<const SfxItemPropertyMapEntry
> lcl_GetShapeMap()
55 static const SfxItemPropertyMapEntry aShapeMap_Impl
[] =
57 { SC_UNONAME_ANCHOR
, 0, cppu::UnoType
<uno::XInterface
>::get(), 0, 0 },
58 { SC_UNONAME_RESIZE_WITH_CELL
, 0, cppu::UnoType
<sal_Bool
>::get(), 0, 0 },
59 { SC_UNONAME_HORIPOS
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0 },
60 { SC_UNONAME_IMAGEMAP
, 0, cppu::UnoType
<container::XIndexContainer
>::get(), 0, 0 },
61 { SC_UNONAME_VERTPOS
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0 },
62 { SC_UNONAME_MOVEPROTECT
, 0, cppu::UnoType
<sal_Bool
>::get(), 0, 0 },
63 { SC_UNONAME_HYPERLINK
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
64 { SC_UNONAME_URL
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
65 { SC_UNONAME_STYLE
, 0, cppu::UnoType
<style::XStyle
>::get(), css::beans::PropertyAttribute::MAYBEVOID
, 0 },
67 return aShapeMap_Impl
;
70 const SvEventDescription
* ScShapeObj::GetSupportedMacroItems()
72 static const SvEventDescription aMacroDescriptionsImpl
[] =
74 { SvMacroItemId::NONE
, nullptr }
76 return aMacroDescriptionsImpl
;
78 ScMacroInfo
* ScShapeObj_getShapeHyperMacroInfo( const ScShapeObj
* pShape
, bool bCreate
= false )
81 if( SdrObject
* pObj
= pShape
->GetSdrObject() )
82 return ScDrawLayer::GetMacroInfo( pObj
, bCreate
);
86 ScShapeObj::ScShapeObj( uno::Reference
<drawing::XShape
>& xShape
) :
87 pShapePropertySet(nullptr),
88 pShapePropertyState(nullptr),
92 osl_atomic_increment( &m_refCount
);
95 mxShapeAgg
.set( xShape
, uno::UNO_QUERY
);
96 // extra block to force deletion of the temporary before setDelegator
101 xShape
= nullptr; // during setDelegator, mxShapeAgg must be the only ref
103 mxShapeAgg
->setDelegator( getXWeak() );
105 xShape
.set(uno::Reference
<drawing::XShape
>( mxShapeAgg
, uno::UNO_QUERY
));
107 bIsTextShape
= ( comphelper::getFromUnoTunnel
<SvxUnoTextBase
>( mxShapeAgg
) != nullptr );
111 SdrObject
* pObj
= GetSdrObject();
114 bIsNoteCaption
= ScDrawLayer::IsNoteCaption( pObj
);
118 osl_atomic_decrement( &m_refCount
);
121 ScShapeObj::~ScShapeObj()
123 // if (mxShapeAgg.is())
124 // mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>());
129 uno::Any SAL_CALL
ScShapeObj::queryInterface( const uno::Type
& rType
)
131 uno::Any aRet
= ScShapeObj_Base::queryInterface( rType
);
133 if ( !aRet
.hasValue() && bIsTextShape
)
134 aRet
= ScShapeObj_TextBase::queryInterface( rType
);
136 if ( !aRet
.hasValue() && bIsNoteCaption
)
137 aRet
= ScShapeObj_ChildBase::queryInterface( rType
);
139 if ( !aRet
.hasValue() && mxShapeAgg
.is() )
140 aRet
= mxShapeAgg
->queryAggregation( rType
);
145 void SAL_CALL
ScShapeObj::acquire() noexcept
147 OWeakObject::acquire();
150 void SAL_CALL
ScShapeObj::release() noexcept
152 OWeakObject::release();
155 void ScShapeObj::GetShapePropertySet()
157 // #i61908# Store the result of queryAggregation in a member.
158 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
160 if (!pShapePropertySet
)
162 uno::Reference
<beans::XPropertySet
> xProp
;
163 if ( mxShapeAgg
.is() )
164 mxShapeAgg
->queryAggregation( cppu::UnoType
<beans::XPropertySet
>::get()) >>= xProp
;
165 pShapePropertySet
= xProp
.get();
169 void ScShapeObj::GetShapePropertyState()
171 // #i61908# Store the result of queryAggregation in a member.
172 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
174 if (!pShapePropertyState
)
176 uno::Reference
<beans::XPropertyState
> xState
;
177 if ( mxShapeAgg
.is() )
178 mxShapeAgg
->queryAggregation( cppu::UnoType
<beans::XPropertyState
>::get()) >>= xState
;
179 pShapePropertyState
= xState
.get();
183 static uno::Reference
<lang::XComponent
> lcl_GetComponent( const uno::Reference
<uno::XAggregation
>& xAgg
)
185 uno::Reference
<lang::XComponent
> xRet
;
187 xAgg
->queryAggregation( cppu::UnoType
<lang::XComponent
>::get()) >>= xRet
;
191 static uno::Reference
<text::XText
> lcl_GetText( const uno::Reference
<uno::XAggregation
>& xAgg
)
193 uno::Reference
<text::XText
> xRet
;
195 xAgg
->queryAggregation( cppu::UnoType
<text::XText
>::get()) >>= xRet
;
199 static uno::Reference
<text::XSimpleText
> lcl_GetSimpleText( const uno::Reference
<uno::XAggregation
>& xAgg
)
201 uno::Reference
<text::XSimpleText
> xRet
;
203 xAgg
->queryAggregation( cppu::UnoType
<text::XSimpleText
>::get()) >>= xRet
;
207 static uno::Reference
<text::XTextRange
> lcl_GetTextRange( const uno::Reference
<uno::XAggregation
>& xAgg
)
209 uno::Reference
<text::XTextRange
> xRet
;
211 xAgg
->queryAggregation( cppu::UnoType
<text::XTextRange
>::get()) >>= xRet
;
216 * If there are lots of shapes, the cost of allocating the XPropertySetInfo structures adds up.
217 * But we have a static set of properties, and most of the underlying types have one static
218 * set per class. So we can cache the combination of them, which dramatically reduces the number
219 * of these we need to allocate.
221 static uno::Reference
<beans::XPropertySetInfo
> getPropertySetInfoFromCache(const uno::Reference
<beans::XPropertySetInfo
>& rxPropSetInfo
)
223 static std::mutex gCacheMutex
;
224 static std::unordered_map
<uno::Reference
<beans::XPropertySetInfo
>, uno::Reference
<beans::XPropertySetInfo
>> gCacheMap
;
226 std::unique_lock
l(gCacheMutex
);
227 // prevent memory leaks, possibly we could use an LRU map here.
228 if (gCacheMap
.size() > 100)
230 auto it
= gCacheMap
.find(rxPropSetInfo
);
231 if (it
!= gCacheMap
.end())
233 uno::Reference
<beans::XPropertySetInfo
> xCombined
= new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), rxPropSetInfo
->getProperties() );
234 gCacheMap
.emplace(rxPropSetInfo
, xCombined
);
240 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScShapeObj::getPropertySetInfo()
242 SolarMutexGuard aGuard
;
244 // #i61527# cache property set info for this object
245 if ( !mxPropSetInfo
.is() )
247 // mix own and aggregated properties:
248 GetShapePropertySet();
249 if (pShapePropertySet
)
251 uno::Reference
<beans::XPropertySetInfo
> xAggInfo(pShapePropertySet
->getPropertySetInfo());
252 mxPropSetInfo
= getPropertySetInfoFromCache(xAggInfo
);
255 return mxPropSetInfo
;
258 static bool lcl_GetPageNum( const SdrPage
* pPage
, SdrModel
& rModel
, SCTAB
& rNum
)
260 sal_uInt16 nCount
= rModel
.GetPageCount();
261 for (sal_uInt16 i
=0; i
<nCount
; i
++)
262 if ( rModel
.GetPage(i
) == pPage
)
264 rNum
= static_cast<SCTAB
>(i
);
271 static bool lcl_GetCaptionPoint( const uno::Reference
< drawing::XShape
>& xShape
, awt::Point
& rCaptionPoint
)
273 bool bReturn
= false;
274 OUString
sType(xShape
->getShapeType());
275 bool bCaptionShape( sType
== "com.sun.star.drawing.CaptionShape" );
278 uno::Reference
< beans::XPropertySet
> xShapeProp (xShape
, uno::UNO_QUERY
);
281 xShapeProp
->getPropertyValue(u
"CaptionPoint"_ustr
) >>= rCaptionPoint
;
288 static ScRange
lcl_GetAnchorCell( const uno::Reference
< drawing::XShape
>& xShape
, const ScDocument
* pDoc
, SCTAB nTab
,
289 awt::Point
& rUnoPoint
, awt::Size
& rUnoSize
, awt::Point
& rCaptionPoint
)
292 rUnoPoint
= xShape
->getPosition();
293 bool bCaptionShape(lcl_GetCaptionPoint(xShape
, rCaptionPoint
));
294 if (pDoc
->IsNegativePage(nTab
))
296 rUnoSize
= xShape
->getSize();
297 rUnoPoint
.X
+= rUnoSize
.Width
; // the right top point is base
300 if (rCaptionPoint
.X
> 0 && rCaptionPoint
.X
> rUnoSize
.Width
)
301 rUnoPoint
.X
+= rCaptionPoint
.X
- rUnoSize
.Width
;
302 if (rCaptionPoint
.Y
< 0)
303 rUnoPoint
.Y
+= rCaptionPoint
.Y
;
306 = pDoc
->GetRange(nTab
, tools::Rectangle(vcl::unohelper::ConvertToVCLPoint(rUnoPoint
),
307 vcl::unohelper::ConvertToVCLPoint(rUnoPoint
)));
313 if (rCaptionPoint
.X
< 0)
314 rUnoPoint
.X
+= rCaptionPoint
.X
;
315 if (rCaptionPoint
.Y
< 0)
316 rUnoPoint
.Y
+= rCaptionPoint
.Y
;
319 = pDoc
->GetRange(nTab
, tools::Rectangle(vcl::unohelper::ConvertToVCLPoint(rUnoPoint
),
320 vcl::unohelper::ConvertToVCLPoint(rUnoPoint
)));
326 static awt::Point
lcl_GetRelativePos( const uno::Reference
< drawing::XShape
>& xShape
, const ScDocument
* pDoc
, SCTAB nTab
, ScRange
& rRange
,
327 awt::Size
& rUnoSize
, awt::Point
& rCaptionPoint
)
329 awt::Point aUnoPoint
;
330 rRange
= lcl_GetAnchorCell(xShape
, pDoc
, nTab
, aUnoPoint
, rUnoSize
, rCaptionPoint
);
331 tools::Rectangle
aRect(pDoc
->GetMMRect( rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aStart
.Tab() ));
332 Point aPoint
= pDoc
->IsNegativePage(nTab
) ? aRect
.TopRight() : aRect
.TopLeft();
333 aUnoPoint
.X
-= aPoint
.X();
334 aUnoPoint
.Y
-= aPoint
.Y();
338 void SAL_CALL
ScShapeObj::setPropertyValue(const OUString
& aPropertyName
, const uno::Any
& aValue
)
340 SolarMutexGuard aGuard
;
342 if ( aPropertyName
== SC_UNONAME_ANCHOR
)
344 uno::Reference
<sheet::XCellRangeAddressable
> xRangeAdd(aValue
, uno::UNO_QUERY
);
346 throw lang::IllegalArgumentException(u
"only XCell or XSpreadsheet objects allowed"_ustr
, getXWeak(), 0);
348 SdrObject
*pObj
= GetSdrObject();
351 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
352 SdrPage
* pPage(pObj
->getSdrPageFromSdrObject());
356 ScDocument
* pDoc(rModel
.GetDocument());
360 if ( ScDocShell
* pDocSh
= pDoc
->GetDocumentShell() )
363 if ( lcl_GetPageNum( pPage
, rModel
, nTab
) )
365 table::CellRangeAddress aAddress
= xRangeAdd
->getRangeAddress();
366 if (nTab
== aAddress
.Sheet
)
368 tools::Rectangle
aRect(pDoc
->GetMMRect( static_cast<SCCOL
>(aAddress
.StartColumn
), static_cast<SCROW
>(aAddress
.StartRow
),
369 static_cast<SCCOL
>(aAddress
.EndColumn
), static_cast<SCROW
>(aAddress
.EndRow
), aAddress
.Sheet
));
370 awt::Point aRelPoint
;
371 uno::Reference
<drawing::XShape
> xShape( mxShapeAgg
, uno::UNO_QUERY
);
376 if (pDoc
->IsNegativePage(nTab
))
378 aPoint
= aRect
.TopRight();
379 aEndPoint
= aRect
.BottomLeft();
383 aPoint
= aRect
.TopLeft();
384 aEndPoint
= aRect
.BottomRight();
387 awt::Point aCaptionPoint
;
389 aRelPoint
= lcl_GetRelativePos( xShape
, pDoc
, nTab
, aRange
, aUnoSize
, aCaptionPoint
);
390 awt::Point
aUnoPoint(aRelPoint
);
392 aUnoPoint
.X
+= aPoint
.X();
393 aUnoPoint
.Y
+= aPoint
.Y();
395 if ( aUnoPoint
.Y
> aEndPoint
.Y() )
396 aUnoPoint
.Y
= aEndPoint
.Y() - 2;
397 if (pDoc
->IsNegativePage(nTab
))
399 if ( aUnoPoint
.X
< aEndPoint
.X() )
400 aUnoPoint
.X
= aEndPoint
.X() + 2;
401 aUnoPoint
.X
-= aUnoSize
.Width
;
402 // remove difference to caption point
403 if (aCaptionPoint
.X
> 0 && aCaptionPoint
.X
> aUnoSize
.Width
)
404 aUnoPoint
.X
-= aCaptionPoint
.X
- aUnoSize
.Width
;
408 if ( aUnoPoint
.X
> aEndPoint
.X() )
409 aUnoPoint
.X
= aEndPoint
.X() - 2;
410 if (aCaptionPoint
.X
< 0)
411 aUnoPoint
.X
-= aCaptionPoint
.X
;
413 if (aCaptionPoint
.Y
< 0)
414 aUnoPoint
.Y
-= aCaptionPoint
.Y
;
416 xShape
->setPosition(aUnoPoint
);
417 pDocSh
->SetModified();
420 if (aAddress
.StartRow
!= aAddress
.EndRow
) //should be a Spreadsheet
422 OSL_ENSURE(aAddress
.StartRow
== 0 && aAddress
.EndRow
== pDoc
->MaxRow() &&
423 aAddress
.StartColumn
== 0 && aAddress
.EndColumn
== pDoc
->MaxCol(), "here should be a XSpreadsheet");
424 ScDrawLayer::SetPageAnchored(*pObj
);
428 OSL_ENSURE(aAddress
.StartRow
== aAddress
.EndRow
&&
429 aAddress
.StartColumn
== aAddress
.EndColumn
, "here should be a XCell");
430 ScDrawObjData aAnchor
;
431 aAnchor
.maStart
= ScAddress(aAddress
.StartColumn
, aAddress
.StartRow
, aAddress
.Sheet
);
432 aAnchor
.maStartOffset
= Point(aRelPoint
.X
, aRelPoint
.Y
);
433 ScDrawObjData
* pDrawObjData
= ScDrawLayer::GetObjData(pObj
);
435 aAnchor
.mbResizeWithCell
= pDrawObjData
->mbResizeWithCell
;
436 //Uno sets the Anchor in terms of the unrotated shape, not much we can do
437 //about that since uno also displays the shape geometry in terms of the unrotated
438 //shape. #TODO think about changing the anchoring behaviour here too
439 //Currently we've only got a start anchor, not an end-anchor, so generate that now
440 ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj
, aAnchor
, *pDoc
, aAddress
.Sheet
);
441 ScDrawLayer::SetCellAnchored(*pObj
, aAnchor
);
451 else if ( aPropertyName
== SC_UNONAME_RESIZE_WITH_CELL
)
453 SdrObject
* pObj
= GetSdrObject();
456 ScAnchorType aAnchorType
= ScDrawLayer::GetAnchorType(*pObj
);
458 // Nothing to do if anchored to page
459 if (aAnchorType
== SCA_PAGE
)
462 ScDrawObjData
* pDrawObjData
= ScDrawLayer::GetObjData(pObj
);
466 aValue
>>= pDrawObjData
->mbResizeWithCell
;
467 ScDrawLayer::SetCellAnchored(*pObj
, *pDrawObjData
);
469 else if ( aPropertyName
== SC_UNONAME_IMAGEMAP
)
471 SdrObject
* pObj
= GetSdrObject();
475 uno::Reference
< uno::XInterface
> xImageMapInt(aValue
, uno::UNO_QUERY
);
477 if( !xImageMapInt
.is() || !SvUnoImageMap_fillImageMap( xImageMapInt
, aImageMap
) )
478 throw lang::IllegalArgumentException();
480 SvxIMapInfo
* pIMapInfo
= SvxIMapInfo::GetIMapInfo(pObj
);
483 // replace existing image map
484 pIMapInfo
->SetImageMap( aImageMap
);
488 // insert new user data with image map
489 pObj
->AppendUserData(std::unique_ptr
<SdrObjUserData
>(new SvxIMapInfo(aImageMap
) ));
493 else if ( aPropertyName
== SC_UNONAME_HORIPOS
)
498 SdrObject
*pObj
= GetSdrObject();
501 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
502 SdrPage
* pPage(pObj
->getSdrPageFromSdrObject());
507 if ( lcl_GetPageNum( pPage
, rModel
, nTab
) )
509 ScDocument
* pDoc
= rModel
.GetDocument();
512 if ( ScDocShell
* pDocSh
= pDoc
->GetDocumentShell() )
514 uno::Reference
<drawing::XShape
> xShape( mxShapeAgg
, uno::UNO_QUERY
);
517 if (ScDrawLayer::GetAnchorType(*pObj
) == SCA_PAGE
)
519 awt::Point
aPoint(xShape
->getPosition());
520 awt::Size
aSize(xShape
->getSize());
521 awt::Point aCaptionPoint
;
522 if (pDoc
->IsNegativePage(nTab
))
527 if (lcl_GetCaptionPoint(xShape
, aCaptionPoint
))
529 if (pDoc
->IsNegativePage(nTab
))
531 if (aCaptionPoint
.X
> 0 && aCaptionPoint
.X
> aSize
.Width
)
532 nPos
-= aCaptionPoint
.X
- aSize
.Width
;
536 if (aCaptionPoint
.X
< 0)
537 nPos
-= aCaptionPoint
.X
;
541 xShape
->setPosition(aPoint
);
542 pDocSh
->SetModified();
544 else if (ScDrawLayer::GetAnchorType(*pObj
) == SCA_CELL
545 || ScDrawLayer::GetAnchorType(*pObj
)
549 awt::Point aCaptionPoint
;
551 awt::Point
aUnoPoint(lcl_GetRelativePos( xShape
, pDoc
, nTab
, aRange
, aUnoSize
, aCaptionPoint
));
552 tools::Rectangle
aRect(pDoc
->GetMMRect( aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aRange
.aStart
.Tab() ));
553 if (pDoc
->IsNegativePage(nTab
))
556 Point
aPoint(aRect
.TopRight());
557 Point
aEndPoint(aRect
.BottomLeft());
558 aUnoPoint
.X
+= aPoint
.X();
559 if (aUnoPoint
.X
< aEndPoint
.X())
560 aUnoPoint
.X
= aEndPoint
.X() + 2;
561 aUnoPoint
.X
-= aUnoSize
.Width
;
562 if (aCaptionPoint
.X
> 0 && aCaptionPoint
.X
> aUnoSize
.Width
)
563 aUnoPoint
.X
-= aCaptionPoint
.X
- aUnoSize
.Width
;
568 Point
aPoint(aRect
.TopLeft());
569 Point
aEndPoint(aRect
.BottomRight());
570 aUnoPoint
.X
+= aPoint
.X();
571 if (aUnoPoint
.X
> aEndPoint
.X())
572 aUnoPoint
.X
= aEndPoint
.X() - 2;
573 if (aCaptionPoint
.X
< 0)
574 aUnoPoint
.X
-= aCaptionPoint
.X
;
576 aUnoPoint
.Y
= xShape
->getPosition().Y
;
577 xShape
->setPosition(aUnoPoint
);
578 pDocSh
->SetModified();
582 OSL_FAIL("unknown anchor type");
592 else if ( aPropertyName
== SC_UNONAME_VERTPOS
)
597 SdrObject
*pObj
= GetSdrObject();
600 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
601 SdrPage
* pPage(pObj
->getSdrPageFromSdrObject());
606 if ( lcl_GetPageNum( pPage
, rModel
, nTab
) )
608 ScDocument
* pDoc
= rModel
.GetDocument();
611 if ( ScDocShell
* pDocSh
= pDoc
->GetDocumentShell() )
613 uno::Reference
<drawing::XShape
> xShape( mxShapeAgg
, uno::UNO_QUERY
);
616 if (ScDrawLayer::GetAnchorType(*pObj
) == SCA_PAGE
)
618 awt::Point aPoint
= xShape
->getPosition();
619 awt::Point aCaptionPoint
;
620 if (lcl_GetCaptionPoint(xShape
, aCaptionPoint
))
622 if (aCaptionPoint
.Y
< 0)
623 nPos
-= aCaptionPoint
.Y
;
626 xShape
->setPosition(aPoint
);
627 pDocSh
->SetModified();
629 else if (ScDrawLayer::GetAnchorType(*pObj
) == SCA_CELL
630 || ScDrawLayer::GetAnchorType(*pObj
)
634 awt::Point aCaptionPoint
;
636 awt::Point
aUnoPoint(lcl_GetRelativePos( xShape
, pDoc
, nTab
, aRange
, aUnoSize
, aCaptionPoint
));
637 tools::Rectangle
aRect(pDoc
->GetMMRect( aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aRange
.aStart
.Tab() ));
638 Point
aPoint(aRect
.TopRight());
639 Point
aEndPoint(aRect
.BottomLeft());
641 aUnoPoint
.Y
+= aPoint
.Y();
642 if (aUnoPoint
.Y
> aEndPoint
.Y())
643 aUnoPoint
.Y
= aEndPoint
.Y() - 2;
644 if (aCaptionPoint
.Y
< 0)
645 aUnoPoint
.Y
-= aCaptionPoint
.Y
;
646 aUnoPoint
.X
= xShape
->getPosition().X
;
647 xShape
->setPosition(aUnoPoint
);
648 pDocSh
->SetModified();
652 OSL_FAIL("unknown anchor type");
662 else if ( aPropertyName
== SC_UNONAME_HYPERLINK
||
663 aPropertyName
== SC_UNONAME_URL
)
666 SdrObject
* pObj
= GetSdrObject();
667 if (pObj
&& (aValue
>>= sHyperlink
))
668 pObj
->setHyperlink(sHyperlink
);
670 else if ( aPropertyName
== SC_UNONAME_MOVEPROTECT
)
672 if( SdrObject
* pObj
= GetSdrObject() )
675 if( aValue
>>= aProt
)
676 pObj
->SetMoveProtect( aProt
);
679 else if ( aPropertyName
== SC_UNONAME_STYLE
)
681 if (SdrObject
* pObj
= GetSdrObject())
683 uno::Reference
<style::XStyle
> xStyle(aValue
, uno::UNO_QUERY
);
684 auto pStyleSheetObj
= dynamic_cast<ScStyleObj
*>(xStyle
.get());
686 throw lang::IllegalArgumentException();
688 auto pStyleSheet
= pStyleSheetObj
->GetStyle_Impl();
689 auto pOldStyleSheet
= pObj
->GetStyleSheet();
691 if (pStyleSheet
!= pOldStyleSheet
)
692 pObj
->SetStyleSheet(static_cast<SfxStyleSheet
*>(pStyleSheet
), false);
697 GetShapePropertySet();
698 if (pShapePropertySet
)
699 pShapePropertySet
->setPropertyValue( aPropertyName
, aValue
);
703 uno::Any SAL_CALL
ScShapeObj::getPropertyValue( const OUString
& aPropertyName
)
705 SolarMutexGuard aGuard
;
708 if ( aPropertyName
== SC_UNONAME_ANCHOR
)
710 SdrObject
*pObj
= GetSdrObject();
713 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
714 SdrPage
* pPage(pObj
->getSdrPageFromSdrObject());
718 ScDocument
* pDoc
= rModel
.GetDocument();
722 if ( lcl_GetPageNum( pPage
, rModel
, nTab
) )
724 if ( ScDocShell
* pDocSh
= pDoc
->GetDocumentShell() )
726 uno::Reference
< uno::XInterface
> xAnchor
;
727 if (ScDrawObjData
*pAnchor
= ScDrawLayer::GetObjDataTab(pObj
, nTab
))
728 xAnchor
.set(cppu::getXWeak(new ScCellObj( pDocSh
, pAnchor
->maStart
)));
730 xAnchor
.set(cppu::getXWeak(new ScTableSheetObj( pDocSh
, nTab
)));
738 else if (aPropertyName
== SC_UNONAME_RESIZE_WITH_CELL
)
740 bool bIsResizeWithCell
= false;
741 SdrObject
* pObj
= GetSdrObject();
744 ScAnchorType anchorType
= ScDrawLayer::GetAnchorType(*pObj
);
745 bIsResizeWithCell
= (anchorType
== SCA_CELL_RESIZE
);
747 aAny
<<= bIsResizeWithCell
;
749 else if ( aPropertyName
== SC_UNONAME_IMAGEMAP
)
751 uno::Reference
< uno::XInterface
> xImageMap
;
752 SdrObject
* pObj
= GetSdrObject();
755 SvxIMapInfo
* pIMapInfo
= SvxIMapInfo::GetIMapInfo(GetSdrObject());
758 const ImageMap
& rIMap
= pIMapInfo
->GetImageMap();
759 xImageMap
.set(SvUnoImageMap_createInstance( rIMap
, GetSupportedMacroItems() ));
762 xImageMap
= SvUnoImageMap_createInstance();
764 aAny
<<= uno::Reference
< container::XIndexContainer
>::query( xImageMap
);
766 else if ( aPropertyName
== SC_UNONAME_HORIPOS
)
768 SdrObject
*pObj
= GetSdrObject();
771 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
772 SdrPage
* pPage(pObj
->getSdrPageFromSdrObject());
776 ScDocument
* pDoc
= rModel
.GetDocument();
780 if ( lcl_GetPageNum( pPage
, rModel
, nTab
) )
782 uno::Reference
<drawing::XShape
> xShape( mxShapeAgg
, uno::UNO_QUERY
);
785 if (ScDrawLayer::GetAnchorType(*pObj
) == SCA_CELL
786 || ScDrawLayer::GetAnchorType(*pObj
) == SCA_CELL_RESIZE
)
789 awt::Point aCaptionPoint
;
791 awt::Point
aUnoPoint(lcl_GetRelativePos( xShape
, pDoc
, nTab
, aRange
, aUnoSize
, aCaptionPoint
));
792 if (pDoc
->IsNegativePage(nTab
))
794 aAny
<<= aUnoPoint
.X
;
798 awt::Point aCaptionPoint
;
799 awt::Point
aUnoPoint(xShape
->getPosition());
800 awt::Size
aUnoSize(xShape
->getSize());
801 if (pDoc
->IsNegativePage(nTab
))
804 aUnoPoint
.X
-= aUnoSize
.Width
;
806 if (lcl_GetCaptionPoint(xShape
, aCaptionPoint
))
808 if (pDoc
->IsNegativePage(nTab
))
810 if (aCaptionPoint
.X
> 0 && aCaptionPoint
.X
> aUnoSize
.Width
)
811 aUnoPoint
.X
-= aCaptionPoint
.X
- aUnoSize
.Width
;
815 if (aCaptionPoint
.X
< 0)
816 aUnoPoint
.X
+= aCaptionPoint
.X
;
819 aAny
<<= aUnoPoint
.X
;
827 else if ( aPropertyName
== SC_UNONAME_VERTPOS
)
829 SdrObject
*pObj
= GetSdrObject();
832 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
833 SdrPage
* pPage(pObj
->getSdrPageFromSdrObject());
837 ScDocument
* pDoc
= rModel
.GetDocument();
841 if ( lcl_GetPageNum( pPage
, rModel
, nTab
) )
843 uno::Reference
<drawing::XShape
> xShape( mxShapeAgg
, uno::UNO_QUERY
);
846 if (ScDrawLayer::GetAnchorType(*pObj
) == SCA_CELL
847 || ScDrawLayer::GetAnchorType(*pObj
) == SCA_CELL_RESIZE
)
850 awt::Point aCaptionPoint
;
852 awt::Point
aUnoPoint(lcl_GetRelativePos( xShape
, pDoc
, nTab
, aRange
, aUnoSize
, aCaptionPoint
));
854 aAny
<<= aUnoPoint
.Y
;
858 awt::Point
aUnoPoint(xShape
->getPosition());
859 awt::Point aCaptionPoint
;
860 if (lcl_GetCaptionPoint(xShape
, aCaptionPoint
))
862 if (aCaptionPoint
.Y
< 0)
863 aUnoPoint
.Y
+= aCaptionPoint
.Y
;
865 aAny
<<= aUnoPoint
.Y
;
873 else if ( aPropertyName
== SC_UNONAME_HYPERLINK
||
874 aPropertyName
== SC_UNONAME_URL
)
877 if (SdrObject
* pObj
= GetSdrObject())
878 sHlink
= pObj
->getHyperlink();
881 else if ( aPropertyName
== SC_UNONAME_MOVEPROTECT
)
884 if ( SdrObject
* pObj
= GetSdrObject() )
885 aProt
= pObj
->IsMoveProtect();
888 else if ( aPropertyName
== SC_UNONAME_STYLE
)
890 if (SdrObject
* pObj
= GetSdrObject())
892 if (auto pStyleSheet
= pObj
->GetStyleSheet())
894 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
895 ScDocument
* pDoc
= rModel
.GetDocument();
896 aAny
<<= uno::Reference
<style::XStyle
>(new ScStyleObj(
897 pDoc
? pDoc
->GetDocumentShell() : nullptr,
898 SfxStyleFamily::Frame
, pStyleSheet
->GetName()));
904 if(!pShapePropertySet
) //performance consideration
905 GetShapePropertySet();
906 if (pShapePropertySet
)
907 aAny
= pShapePropertySet
->getPropertyValue( aPropertyName
);
913 void SAL_CALL
ScShapeObj::addPropertyChangeListener( const OUString
& aPropertyName
,
914 const uno::Reference
<beans::XPropertyChangeListener
>& aListener
)
916 SolarMutexGuard aGuard
;
918 GetShapePropertySet();
919 if (pShapePropertySet
)
920 pShapePropertySet
->addPropertyChangeListener( aPropertyName
, aListener
);
923 void SAL_CALL
ScShapeObj::removePropertyChangeListener( const OUString
& aPropertyName
,
924 const uno::Reference
<beans::XPropertyChangeListener
>& aListener
)
926 SolarMutexGuard aGuard
;
928 GetShapePropertySet();
929 if (pShapePropertySet
)
930 pShapePropertySet
->removePropertyChangeListener( aPropertyName
, aListener
);
933 void SAL_CALL
ScShapeObj::addVetoableChangeListener( const OUString
& aPropertyName
,
934 const uno::Reference
<beans::XVetoableChangeListener
>& aListener
)
936 SolarMutexGuard aGuard
;
938 GetShapePropertySet();
939 if (pShapePropertySet
)
940 pShapePropertySet
->addVetoableChangeListener( aPropertyName
, aListener
);
943 void SAL_CALL
ScShapeObj::removeVetoableChangeListener( const OUString
& aPropertyName
,
944 const uno::Reference
<beans::XVetoableChangeListener
>& aListener
)
946 SolarMutexGuard aGuard
;
948 GetShapePropertySet();
949 if (pShapePropertySet
)
950 pShapePropertySet
->removeVetoableChangeListener( aPropertyName
, aListener
);
955 beans::PropertyState SAL_CALL
ScShapeObj::getPropertyState( const OUString
& aPropertyName
)
957 SolarMutexGuard aGuard
;
959 beans::PropertyState eRet
= beans::PropertyState_DIRECT_VALUE
;
960 if ( aPropertyName
== SC_UNONAME_IMAGEMAP
)
962 // ImageMap is always "direct"
964 else if ( aPropertyName
== SC_UNONAME_ANCHOR
)
966 // Anchor is always "direct"
968 else if ( aPropertyName
== SC_UNONAME_HORIPOS
)
970 // HoriPos is always "direct"
972 else if ( aPropertyName
== SC_UNONAME_VERTPOS
)
974 // VertPos is always "direct"
978 GetShapePropertyState();
979 if (pShapePropertyState
)
980 eRet
= pShapePropertyState
->getPropertyState( aPropertyName
);
986 uno::Sequence
<beans::PropertyState
> SAL_CALL
ScShapeObj::getPropertyStates(
987 const uno::Sequence
<OUString
>& aPropertyNames
)
989 SolarMutexGuard aGuard
;
991 // simple loop to get own and aggregated states
993 uno::Sequence
<beans::PropertyState
> aRet(aPropertyNames
.getLength());
994 std::transform(aPropertyNames
.begin(), aPropertyNames
.end(), aRet
.getArray(),
995 [this](const OUString
& rName
) -> beans::PropertyState
{ return getPropertyState(rName
); });
999 void SAL_CALL
ScShapeObj::setPropertyToDefault( const OUString
& aPropertyName
)
1001 SolarMutexGuard aGuard
;
1003 if ( aPropertyName
== SC_UNONAME_IMAGEMAP
)
1005 SdrObject
* pObj
= GetSdrObject();
1008 SvxIMapInfo
* pIMapInfo
= SvxIMapInfo::GetIMapInfo(pObj
);
1012 pIMapInfo
->SetImageMap( aEmpty
); // replace with empty image map
1016 // nothing to do (no need to insert user data for an empty map)
1022 GetShapePropertyState();
1023 if (pShapePropertyState
)
1024 pShapePropertyState
->setPropertyToDefault( aPropertyName
);
1028 uno::Any SAL_CALL
ScShapeObj::getPropertyDefault( const OUString
& aPropertyName
)
1030 SolarMutexGuard aGuard
;
1033 if ( aPropertyName
== SC_UNONAME_IMAGEMAP
)
1035 // default: empty ImageMap
1036 uno::Reference
< uno::XInterface
> xImageMap(SvUnoImageMap_createInstance());
1037 aAny
<<= uno::Reference
< container::XIndexContainer
>::query( xImageMap
);
1041 GetShapePropertyState();
1042 if (pShapePropertyState
)
1043 aAny
= pShapePropertyState
->getPropertyDefault( aPropertyName
);
1051 void SAL_CALL
ScShapeObj::attach( const uno::Reference
<text::XTextRange
>& /* xTextRange */ )
1053 throw lang::IllegalArgumentException(); // anchor cannot be changed
1056 uno::Reference
<text::XTextRange
> SAL_CALL
ScShapeObj::getAnchor()
1058 SolarMutexGuard aGuard
;
1060 uno::Reference
<text::XTextRange
> xRet
;
1062 SdrObject
* pObj
= GetSdrObject();
1065 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
1066 SdrPage
* pPage(pObj
->getSdrPageFromSdrObject());
1067 ScDocument
* pDoc
= rModel
.GetDocument();
1069 if ( pPage
&& pDoc
)
1071 if ( ScDocShell
* pDocSh
= pDoc
->GetDocumentShell() )
1074 if ( lcl_GetPageNum( pPage
, rModel
, nTab
) )
1076 Point
aPos(pObj
->GetCurrentBoundRect().TopLeft());
1077 ScRange
aRange(pDoc
->GetRange( nTab
, tools::Rectangle( aPos
, aPos
) ));
1079 // anchor is always the cell
1081 xRet
.set(new ScCellObj( pDocSh
, aRange
.aStart
));
1092 void SAL_CALL
ScShapeObj::dispose()
1094 SolarMutexGuard aGuard
;
1096 uno::Reference
<lang::XComponent
> xAggComp(lcl_GetComponent(mxShapeAgg
));
1097 if ( xAggComp
.is() )
1098 xAggComp
->dispose();
1101 void SAL_CALL
ScShapeObj::addEventListener(
1102 const uno::Reference
<lang::XEventListener
>& xListener
)
1104 SolarMutexGuard aGuard
;
1106 uno::Reference
<lang::XComponent
> xAggComp(lcl_GetComponent(mxShapeAgg
));
1107 if ( xAggComp
.is() )
1108 xAggComp
->addEventListener(xListener
);
1111 void SAL_CALL
ScShapeObj::removeEventListener(
1112 const uno::Reference
<lang::XEventListener
>& xListener
)
1114 SolarMutexGuard aGuard
;
1116 uno::Reference
<lang::XComponent
> xAggComp(lcl_GetComponent(mxShapeAgg
));
1117 if ( xAggComp
.is() )
1118 xAggComp
->removeEventListener(xListener
);
1122 // (special handling for ScCellFieldObj)
1124 static void lcl_CopyOneProperty( beans::XPropertySet
& rDest
, beans::XPropertySet
& rSource
, const OUString
& aNameStr
)
1128 rDest
.setPropertyValue( aNameStr
, rSource
.getPropertyValue( aNameStr
) );
1130 catch (uno::Exception
&)
1132 TOOLS_WARN_EXCEPTION( "sc", "Exception in text field");
1136 void SAL_CALL
ScShapeObj::insertTextContent( const uno::Reference
<text::XTextRange
>& xRange
,
1137 const uno::Reference
<text::XTextContent
>& xContent
,
1140 SolarMutexGuard aGuard
;
1142 uno::Reference
<text::XTextContent
> xEffContent
;
1144 ScEditFieldObj
* pCellField
= dynamic_cast<ScEditFieldObj
*>( xContent
.get() );
1147 // createInstance("TextField.URL") from the document creates a ScCellFieldObj.
1148 // To insert it into drawing text, a SvxUnoTextField is needed instead.
1149 // The ScCellFieldObj object is left in non-inserted state.
1151 rtl::Reference
<SvxUnoTextField
> pDrawField
= new SvxUnoTextField( text::textfield::Type::URL
);
1152 xEffContent
.set(pDrawField
);
1153 lcl_CopyOneProperty( *pDrawField
, *pCellField
, SC_UNONAME_URL
);
1154 lcl_CopyOneProperty( *pDrawField
, *pCellField
, SC_UNONAME_REPR
);
1155 lcl_CopyOneProperty( *pDrawField
, *pCellField
, SC_UNONAME_TARGET
);
1158 xEffContent
.set(xContent
);
1160 uno::Reference
<text::XText
> xAggText(lcl_GetText(mxShapeAgg
));
1161 if ( xAggText
.is() )
1162 xAggText
->insertTextContent( xRange
, xEffContent
, bAbsorb
);
1165 void SAL_CALL
ScShapeObj::removeTextContent( const uno::Reference
<text::XTextContent
>& xContent
)
1167 SolarMutexGuard aGuard
;
1169 // ScCellFieldObj can't be used here.
1171 uno::Reference
<text::XText
> xAggText(lcl_GetText(mxShapeAgg
));
1172 if ( xAggText
.is() )
1173 xAggText
->removeTextContent( xContent
);
1176 // XSimpleText (parent of XText)
1177 // Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object
1179 uno::Reference
<text::XTextCursor
> SAL_CALL
ScShapeObj::createTextCursor()
1181 SolarMutexGuard aGuard
;
1183 if ( mxShapeAgg
.is() )
1185 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1187 SvxUnoTextBase
* pText
= comphelper::getFromUnoTunnel
<SvxUnoTextBase
>( mxShapeAgg
);
1189 return new ScDrawTextCursor( this, *pText
);
1192 return uno::Reference
<text::XTextCursor
>();
1195 uno::Reference
<text::XTextCursor
> SAL_CALL
ScShapeObj::createTextCursorByRange(
1196 const uno::Reference
<text::XTextRange
>& aTextPosition
)
1198 SolarMutexGuard aGuard
;
1200 if ( mxShapeAgg
.is() && aTextPosition
.is() )
1202 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1204 SvxUnoTextBase
* pText
= comphelper::getFromUnoTunnel
<SvxUnoTextBase
>( mxShapeAgg
);
1205 SvxUnoTextRangeBase
* pRange
= comphelper::getFromUnoTunnel
<SvxUnoTextRangeBase
>( aTextPosition
);
1206 if ( pText
&& pRange
)
1208 rtl::Reference
<SvxUnoTextCursor
> pCursor
= new ScDrawTextCursor( this, *pText
);
1209 pCursor
->SetSelection( pRange
->GetSelection() );
1214 return uno::Reference
<text::XTextCursor
>();
1217 void SAL_CALL
ScShapeObj::insertString( const uno::Reference
<text::XTextRange
>& xRange
,
1218 const OUString
& aString
, sal_Bool bAbsorb
)
1220 SolarMutexGuard aGuard
;
1222 uno::Reference
<text::XSimpleText
> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg
));
1223 if ( !xAggSimpleText
.is() )
1224 throw uno::RuntimeException();
1226 xAggSimpleText
->insertString( xRange
, aString
, bAbsorb
);
1229 void SAL_CALL
ScShapeObj::insertControlCharacter( const uno::Reference
<text::XTextRange
>& xRange
,
1230 sal_Int16 nControlCharacter
, sal_Bool bAbsorb
)
1232 SolarMutexGuard aGuard
;
1234 uno::Reference
<text::XSimpleText
> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg
));
1235 if ( !xAggSimpleText
.is() )
1236 throw uno::RuntimeException();
1238 xAggSimpleText
->insertControlCharacter( xRange
, nControlCharacter
, bAbsorb
);
1242 // (parent of XSimpleText)
1244 uno::Reference
<text::XText
> SAL_CALL
ScShapeObj::getText()
1249 uno::Reference
<text::XTextRange
> SAL_CALL
ScShapeObj::getStart()
1251 SolarMutexGuard aGuard
;
1253 uno::Reference
<text::XTextRange
> xAggTextRange(lcl_GetTextRange(mxShapeAgg
));
1254 if ( !xAggTextRange
.is() )
1255 throw uno::RuntimeException();
1257 return xAggTextRange
->getStart();
1260 uno::Reference
<text::XTextRange
> SAL_CALL
ScShapeObj::getEnd()
1262 SolarMutexGuard aGuard
;
1264 uno::Reference
<text::XTextRange
> xAggTextRange(lcl_GetTextRange(mxShapeAgg
));
1265 if ( !xAggTextRange
.is() )
1266 throw uno::RuntimeException();
1268 return xAggTextRange
->getEnd();
1271 OUString SAL_CALL
ScShapeObj::getString()
1273 SolarMutexGuard aGuard
;
1275 uno::Reference
<text::XTextRange
> xAggTextRange(lcl_GetTextRange(mxShapeAgg
));
1276 if ( !xAggTextRange
.is() )
1277 throw uno::RuntimeException();
1279 return xAggTextRange
->getString();
1282 void SAL_CALL
ScShapeObj::setString( const OUString
& aText
)
1284 SolarMutexGuard aGuard
;
1286 uno::Reference
<text::XTextRange
> xAggTextRange(lcl_GetTextRange(mxShapeAgg
));
1287 if ( !xAggTextRange
.is() )
1288 throw uno::RuntimeException();
1290 xAggTextRange
->setString( aText
);
1295 uno::Reference
< uno::XInterface
> SAL_CALL
ScShapeObj::getParent()
1297 SolarMutexGuard aGuard
;
1299 // receive cell position from caption object (parent of a note caption is the note cell)
1300 SdrObject
* pObj
= GetSdrObject();
1303 ScDrawLayer
& rModel(static_cast< ScDrawLayer
& >(pObj
->getSdrModelFromSdrObject()));
1304 SdrPage
* pPage(pObj
->getSdrPageFromSdrObject());
1305 ScDocument
* pDoc
= rModel
.GetDocument();
1307 if ( pPage
&& pDoc
)
1309 if ( ScDocShell
* pDocSh
= pDoc
->GetDocumentShell() )
1312 if ( lcl_GetPageNum( pPage
, rModel
, nTab
) )
1314 const ScDrawObjData
* pCaptData
= ScDrawLayer::GetNoteCaptionData( pObj
, nTab
);
1316 return cppu::getXWeak( new ScCellObj( pDocSh
, pCaptData
->maStart
) );
1325 void SAL_CALL
ScShapeObj::setParent( const uno::Reference
< uno::XInterface
>& )
1327 throw lang::NoSupportException();
1332 uno::Sequence
<uno::Type
> SAL_CALL
ScShapeObj::getTypes()
1334 uno::Sequence
< uno::Type
> aBaseTypes( ScShapeObj_Base::getTypes() );
1336 uno::Sequence
< uno::Type
> aTextTypes
;
1338 aTextTypes
= ScShapeObj_TextBase::getTypes();
1340 uno::Reference
<lang::XTypeProvider
> xBaseProvider
;
1341 if ( mxShapeAgg
.is() )
1342 mxShapeAgg
->queryAggregation( cppu::UnoType
<lang::XTypeProvider
>::get()) >>= xBaseProvider
;
1343 OSL_ENSURE( xBaseProvider
.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" );
1345 uno::Sequence
< uno::Type
> aAggTypes
;
1346 if( xBaseProvider
.is() )
1347 aAggTypes
= xBaseProvider
->getTypes();
1349 return ::comphelper::concatSequences( aBaseTypes
, aTextTypes
, aAggTypes
);
1352 uno::Sequence
<sal_Int8
> SAL_CALL
ScShapeObj::getImplementationId()
1354 return css::uno::Sequence
<sal_Int8
>();
1357 SdrObject
* ScShapeObj::GetSdrObject() const noexcept
1360 return SdrObject::getSdrObjectFromXShape( mxShapeAgg
);
1364 constexpr OUString SC_EVENTACC_ONCLICK
= u
"OnClick"_ustr
;
1365 constexpr OUString SC_EVENTACC_SCRIPT
= u
"Script"_ustr
;
1366 constexpr OUString SC_EVENTACC_EVENTTYPE
= u
"EventType"_ustr
;
1368 class ShapeUnoEventAccessImpl
: public ::cppu::WeakImplHelper
< container::XNameReplace
>
1371 ScShapeObj
* mpShape
;
1373 ScMacroInfo
* getInfo( bool bCreate
)
1375 return ScShapeObj_getShapeHyperMacroInfo( mpShape
, bCreate
);
1379 explicit ShapeUnoEventAccessImpl( ScShapeObj
* pShape
): mpShape( pShape
)
1384 virtual void SAL_CALL
replaceByName( const OUString
& aName
, const uno::Any
& aElement
) override
1386 if ( !hasByName( aName
) )
1387 throw container::NoSuchElementException();
1388 uno::Sequence
< beans::PropertyValue
> aProperties
;
1389 aElement
>>= aProperties
;
1390 bool isEventType
= false;
1391 for (const beans::PropertyValue
& rProperty
: aProperties
)
1393 if ( rProperty
.Name
== SC_EVENTACC_EVENTTYPE
)
1398 if ( isEventType
&& (rProperty
.Name
== SC_EVENTACC_SCRIPT
) )
1401 if ( rProperty
.Value
>>= sValue
)
1403 ScMacroInfo
* pInfo
= getInfo( true );
1404 OSL_ENSURE( pInfo
, "shape macro info could not be created!" );
1407 pInfo
->SetMacro( sValue
);
1414 virtual uno::Any SAL_CALL
getByName( const OUString
& aName
) override
1416 uno::Sequence
< beans::PropertyValue
> aProperties
;
1417 ScMacroInfo
* pInfo
= getInfo(false);
1419 if ( aName
!= SC_EVENTACC_ONCLICK
)
1421 throw container::NoSuchElementException();
1424 if ( pInfo
&& !pInfo
->GetMacro().isEmpty() )
1426 aProperties
= { comphelper::makePropertyValue(SC_EVENTACC_EVENTTYPE
,
1427 SC_EVENTACC_SCRIPT
),
1428 comphelper::makePropertyValue(SC_EVENTACC_SCRIPT
, pInfo
->GetMacro()) };
1431 return uno::Any( aProperties
);
1434 virtual uno::Sequence
< OUString
> SAL_CALL
getElementNames() override
1436 uno::Sequence
<OUString
> aSeq
{ SC_EVENTACC_ONCLICK
};
1440 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
1442 return aName
== SC_EVENTACC_ONCLICK
;
1446 virtual uno::Type SAL_CALL
getElementType() override
1448 return cppu::UnoType
<uno::Sequence
< beans::PropertyValue
>>::get();
1451 virtual sal_Bool SAL_CALL
hasElements() override
1453 // elements are always present (but contained property sequences may be empty)
1458 ::uno::Reference
< container::XNameReplace
> SAL_CALL
1459 ScShapeObj::getEvents( )
1461 return new ShapeUnoEventAccessImpl( this );
1464 OUString SAL_CALL
ScShapeObj::getImplementationName( )
1466 return u
"com.sun.star.comp.sc.ScShapeObj"_ustr
;
1469 sal_Bool SAL_CALL
ScShapeObj::supportsService( const OUString
& ServiceName
)
1471 return cppu::supportsService(this, ServiceName
);
1474 uno::Sequence
< OUString
> SAL_CALL
ScShapeObj::getSupportedServiceNames( )
1476 uno::Reference
<lang::XServiceInfo
> xSI
;
1477 if ( mxShapeAgg
.is() )
1478 mxShapeAgg
->queryAggregation( cppu::UnoType
<lang::XServiceInfo
>::get() ) >>= xSI
;
1480 uno::Sequence
< OUString
> aSupported
;
1482 aSupported
= xSI
->getSupportedServiceNames();
1484 aSupported
.realloc( aSupported
.getLength() + 1 );
1485 aSupported
.getArray()[ aSupported
.getLength() - 1 ] = "com.sun.star.sheet.Shape";
1487 if( bIsNoteCaption
)
1489 aSupported
.realloc( aSupported
.getLength() + 1 );
1490 aSupported
.getArray()[ aSupported
.getLength() - 1 ] = "com.sun.star.sheet.CellAnnotationShape";
1496 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */