tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / unoobj / shapeuno.cxx
blob4aabcf03ebe09fa84c047bd32d694517c88acb22
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
45 #include <docsh.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 )
80 if( pShape )
81 if( SdrObject* pObj = pShape->GetSdrObject() )
82 return ScDrawLayer::GetMacroInfo( pObj, bCreate );
83 return nullptr;
86 ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) :
87 pShapePropertySet(nullptr),
88 pShapePropertyState(nullptr),
89 bIsTextShape(false),
90 bIsNoteCaption(false)
92 osl_atomic_increment( &m_refCount );
95 mxShapeAgg.set( xShape, uno::UNO_QUERY );
96 // extra block to force deletion of the temporary before setDelegator
99 if (mxShapeAgg.is())
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();
112 if ( pObj )
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>());
127 // 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 );
142 return aRet;
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;
186 if ( xAgg.is() )
187 xAgg->queryAggregation( cppu::UnoType<lang::XComponent>::get()) >>= xRet;
188 return xRet;
191 static uno::Reference<text::XText> lcl_GetText( const uno::Reference<uno::XAggregation>& xAgg )
193 uno::Reference<text::XText> xRet;
194 if ( xAgg.is() )
195 xAgg->queryAggregation( cppu::UnoType<text::XText>::get()) >>= xRet;
196 return xRet;
199 static uno::Reference<text::XSimpleText> lcl_GetSimpleText( const uno::Reference<uno::XAggregation>& xAgg )
201 uno::Reference<text::XSimpleText> xRet;
202 if ( xAgg.is() )
203 xAgg->queryAggregation( cppu::UnoType<text::XSimpleText>::get()) >>= xRet;
204 return xRet;
207 static uno::Reference<text::XTextRange> lcl_GetTextRange( const uno::Reference<uno::XAggregation>& xAgg )
209 uno::Reference<text::XTextRange> xRet;
210 if ( xAgg.is() )
211 xAgg->queryAggregation( cppu::UnoType<text::XTextRange>::get()) >>= xRet;
212 return 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)
229 gCacheMap.clear();
230 auto it = gCacheMap.find(rxPropSetInfo);
231 if (it != gCacheMap.end())
232 return it->second;
233 uno::Reference<beans::XPropertySetInfo> xCombined = new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), rxPropSetInfo->getProperties() );
234 gCacheMap.emplace(rxPropSetInfo, xCombined);
235 return xCombined;
238 // XPropertySet
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);
265 return true;
268 return false;
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" );
276 if (bCaptionShape)
278 uno::Reference < beans::XPropertySet > xShapeProp (xShape, uno::UNO_QUERY);
279 if (xShapeProp.is())
281 xShapeProp->getPropertyValue(u"CaptionPoint"_ustr) >>= rCaptionPoint;
282 bReturn = true;
285 return bReturn;
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 )
291 ScRange aReturn;
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
298 if (bCaptionShape)
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;
305 aReturn
306 = pDoc->GetRange(nTab, tools::Rectangle(vcl::unohelper::ConvertToVCLPoint(rUnoPoint),
307 vcl::unohelper::ConvertToVCLPoint(rUnoPoint)));
309 else
311 if (bCaptionShape)
313 if (rCaptionPoint.X < 0)
314 rUnoPoint.X += rCaptionPoint.X;
315 if (rCaptionPoint.Y < 0)
316 rUnoPoint.Y += rCaptionPoint.Y;
318 aReturn
319 = pDoc->GetRange(nTab, tools::Rectangle(vcl::unohelper::ConvertToVCLPoint(rUnoPoint),
320 vcl::unohelper::ConvertToVCLPoint(rUnoPoint)));
323 return aReturn;
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();
335 return aUnoPoint;
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);
345 if (!xRangeAdd.is())
346 throw lang::IllegalArgumentException(u"only XCell or XSpreadsheet objects allowed"_ustr, getXWeak(), 0);
348 SdrObject *pObj = GetSdrObject();
349 if (pObj)
351 ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
352 SdrPage* pPage(pObj->getSdrPageFromSdrObject());
354 if ( pPage )
356 ScDocument* pDoc(rModel.GetDocument());
358 if ( pDoc )
360 if ( ScDocShell* pDocSh = pDoc->GetDocumentShell() )
362 SCTAB nTab = 0;
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 );
372 if (xShape.is())
374 Point aPoint;
375 Point aEndPoint;
376 if (pDoc->IsNegativePage(nTab))
378 aPoint = aRect.TopRight();
379 aEndPoint = aRect.BottomLeft();
381 else
383 aPoint = aRect.TopLeft();
384 aEndPoint = aRect.BottomRight();
386 awt::Size aUnoSize;
387 awt::Point aCaptionPoint;
388 ScRange aRange;
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;
406 else
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);
426 else
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);
434 if (pDrawObjData)
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();
454 if (!pObj)
455 return;
456 ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType(*pObj);
458 // Nothing to do if anchored to page
459 if (aAnchorType == SCA_PAGE)
460 return;
462 ScDrawObjData* pDrawObjData = ScDrawLayer::GetObjData(pObj);
463 if (!pDrawObjData)
464 return;
466 aValue >>= pDrawObjData->mbResizeWithCell;
467 ScDrawLayer::SetCellAnchored(*pObj, *pDrawObjData);
469 else if ( aPropertyName == SC_UNONAME_IMAGEMAP )
471 SdrObject* pObj = GetSdrObject();
472 if ( pObj )
474 ImageMap aImageMap;
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);
481 if( pIMapInfo )
483 // replace existing image map
484 pIMapInfo->SetImageMap( aImageMap );
486 else
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 )
495 sal_Int32 nPos = 0;
496 if (aValue >>= nPos)
498 SdrObject *pObj = GetSdrObject();
499 if (pObj)
501 ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
502 SdrPage* pPage(pObj->getSdrPageFromSdrObject());
504 if ( pPage )
506 SCTAB nTab = 0;
507 if ( lcl_GetPageNum( pPage, rModel, nTab ) )
509 ScDocument* pDoc = rModel.GetDocument();
510 if ( pDoc )
512 if ( ScDocShell* pDocSh = pDoc->GetDocumentShell() )
514 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
515 if (xShape.is())
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))
524 nPos *= -1;
525 nPos -= aSize.Width;
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;
534 else
536 if (aCaptionPoint.X < 0)
537 nPos -= aCaptionPoint.X;
540 aPoint.X = nPos;
541 xShape->setPosition(aPoint);
542 pDocSh->SetModified();
544 else if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL
545 || ScDrawLayer::GetAnchorType(*pObj)
546 == SCA_CELL_RESIZE)
548 awt::Size aUnoSize;
549 awt::Point aCaptionPoint;
550 ScRange aRange;
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))
555 aUnoPoint.X = -nPos;
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;
565 else
567 aUnoPoint.X = nPos;
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();
580 else
582 OSL_FAIL("unknown anchor type");
592 else if ( aPropertyName == SC_UNONAME_VERTPOS )
594 sal_Int32 nPos = 0;
595 if (aValue >>= nPos)
597 SdrObject *pObj = GetSdrObject();
598 if (pObj)
600 ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
601 SdrPage* pPage(pObj->getSdrPageFromSdrObject());
603 if ( pPage )
605 SCTAB nTab = 0;
606 if ( lcl_GetPageNum( pPage, rModel, nTab ) )
608 ScDocument* pDoc = rModel.GetDocument();
609 if ( pDoc )
611 if ( ScDocShell* pDocSh = pDoc->GetDocumentShell() )
613 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
614 if (xShape.is())
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;
625 aPoint.Y = nPos;
626 xShape->setPosition(aPoint);
627 pDocSh->SetModified();
629 else if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL
630 || ScDrawLayer::GetAnchorType(*pObj)
631 == SCA_CELL_RESIZE)
633 awt::Size aUnoSize;
634 awt::Point aCaptionPoint;
635 ScRange aRange;
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());
640 aUnoPoint.Y = nPos;
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();
650 else
652 OSL_FAIL("unknown anchor type");
662 else if ( aPropertyName == SC_UNONAME_HYPERLINK ||
663 aPropertyName == SC_UNONAME_URL )
665 OUString sHyperlink;
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() )
674 bool aProt = false;
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());
685 if (!pStyleSheetObj)
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);
695 else
697 GetShapePropertySet();
698 if (pShapePropertySet)
699 pShapePropertySet->setPropertyValue( aPropertyName, aValue );
703 uno::Any SAL_CALL ScShapeObj::getPropertyValue( const OUString& aPropertyName )
705 SolarMutexGuard aGuard;
707 uno::Any aAny;
708 if ( aPropertyName == SC_UNONAME_ANCHOR )
710 SdrObject *pObj = GetSdrObject();
711 if (pObj)
713 ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
714 SdrPage* pPage(pObj->getSdrPageFromSdrObject());
716 if ( pPage )
718 ScDocument* pDoc = rModel.GetDocument();
719 if ( pDoc )
721 SCTAB nTab = 0;
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)));
729 else
730 xAnchor.set(cppu::getXWeak(new ScTableSheetObj( pDocSh, nTab )));
731 aAny <<= xAnchor;
738 else if (aPropertyName == SC_UNONAME_RESIZE_WITH_CELL)
740 bool bIsResizeWithCell = false;
741 SdrObject* pObj = GetSdrObject();
742 if (pObj)
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();
753 if ( pObj )
755 SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo(GetSdrObject());
756 if( pIMapInfo )
758 const ImageMap& rIMap = pIMapInfo->GetImageMap();
759 xImageMap.set(SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() ));
761 else
762 xImageMap = SvUnoImageMap_createInstance();
764 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
766 else if ( aPropertyName == SC_UNONAME_HORIPOS )
768 SdrObject *pObj = GetSdrObject();
769 if (pObj)
771 ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
772 SdrPage* pPage(pObj->getSdrPageFromSdrObject());
774 if ( pPage )
776 ScDocument* pDoc = rModel.GetDocument();
777 if ( pDoc )
779 SCTAB nTab = 0;
780 if ( lcl_GetPageNum( pPage, rModel, nTab ) )
782 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
783 if (xShape.is())
785 if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL
786 || ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL_RESIZE)
788 awt::Size aUnoSize;
789 awt::Point aCaptionPoint;
790 ScRange aRange;
791 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
792 if (pDoc->IsNegativePage(nTab))
793 aUnoPoint.X *= -1;
794 aAny <<= aUnoPoint.X;
796 else
798 awt::Point aCaptionPoint;
799 awt::Point aUnoPoint(xShape->getPosition());
800 awt::Size aUnoSize(xShape->getSize());
801 if (pDoc->IsNegativePage(nTab))
803 aUnoPoint.X *= -1;
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;
813 else
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();
830 if (pObj)
832 ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
833 SdrPage* pPage(pObj->getSdrPageFromSdrObject());
835 if ( pPage )
837 ScDocument* pDoc = rModel.GetDocument();
838 if ( pDoc )
840 SCTAB nTab = 0;
841 if ( lcl_GetPageNum( pPage, rModel, nTab ) )
843 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
844 if (xShape.is())
846 if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL
847 || ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL_RESIZE)
849 awt::Size aUnoSize;
850 awt::Point aCaptionPoint;
851 ScRange aRange;
852 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
854 aAny <<= aUnoPoint.Y;
856 else
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 )
876 OUString sHlink;
877 if (SdrObject* pObj = GetSdrObject())
878 sHlink = pObj->getHyperlink();
879 aAny <<= sHlink;
881 else if ( aPropertyName == SC_UNONAME_MOVEPROTECT )
883 bool aProt = false;
884 if ( SdrObject* pObj = GetSdrObject() )
885 aProt = pObj->IsMoveProtect();
886 aAny <<= aProt;
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()));
902 else
904 if(!pShapePropertySet) //performance consideration
905 GetShapePropertySet();
906 if (pShapePropertySet)
907 aAny = pShapePropertySet->getPropertyValue( aPropertyName );
910 return aAny;
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 );
953 // XPropertyState
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"
976 else
978 GetShapePropertyState();
979 if (pShapePropertyState)
980 eRet = pShapePropertyState->getPropertyState( aPropertyName );
983 return eRet;
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); });
996 return aRet;
999 void SAL_CALL ScShapeObj::setPropertyToDefault( const OUString& aPropertyName )
1001 SolarMutexGuard aGuard;
1003 if ( aPropertyName == SC_UNONAME_IMAGEMAP )
1005 SdrObject* pObj = GetSdrObject();
1006 if ( pObj )
1008 SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo(pObj);
1009 if( pIMapInfo )
1011 ImageMap aEmpty;
1012 pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map
1014 else
1016 // nothing to do (no need to insert user data for an empty map)
1020 else
1022 GetShapePropertyState();
1023 if (pShapePropertyState)
1024 pShapePropertyState->setPropertyToDefault( aPropertyName );
1028 uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const OUString& aPropertyName )
1030 SolarMutexGuard aGuard;
1032 uno::Any aAny;
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 );
1039 else
1041 GetShapePropertyState();
1042 if (pShapePropertyState)
1043 aAny = pShapePropertyState->getPropertyDefault( aPropertyName );
1046 return aAny;
1049 // XTextContent
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();
1063 if( pObj )
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() )
1073 SCTAB nTab = 0;
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 ));
1087 return xRet;
1090 // XComponent
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);
1121 // XText
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,
1138 sal_Bool bAbsorb )
1140 SolarMutexGuard aGuard;
1142 uno::Reference<text::XTextContent> xEffContent;
1144 ScEditFieldObj* pCellField = dynamic_cast<ScEditFieldObj*>( xContent.get() );
1145 if ( pCellField )
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 );
1157 else
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 );
1188 if (pText)
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() );
1210 return pCursor;
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 );
1241 // XTextRange
1242 // (parent of XSimpleText)
1244 uno::Reference<text::XText> SAL_CALL ScShapeObj::getText()
1246 return this;
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 );
1293 // XChild
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();
1301 if( pObj )
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() )
1311 SCTAB nTab = 0;
1312 if ( lcl_GetPageNum( pPage, rModel, nTab ) )
1314 const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab );
1315 if( pCaptData )
1316 return cppu::getXWeak( new ScCellObj( pDocSh, pCaptData->maStart ) );
1322 return nullptr;
1325 void SAL_CALL ScShapeObj::setParent( const uno::Reference< uno::XInterface >& )
1327 throw lang::NoSupportException();
1330 // XTypeProvider
1332 uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes()
1334 uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() );
1336 uno::Sequence< uno::Type > aTextTypes;
1337 if ( bIsTextShape )
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
1359 if(mxShapeAgg.is())
1360 return SdrObject::getSdrObjectFromXShape( mxShapeAgg );
1361 return nullptr;
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 >
1370 private:
1371 ScShapeObj* mpShape;
1373 ScMacroInfo* getInfo( bool bCreate )
1375 return ScShapeObj_getShapeHyperMacroInfo( mpShape, bCreate );
1378 public:
1379 explicit ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
1383 // XNameReplace
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 )
1395 isEventType = true;
1396 continue;
1398 if ( isEventType && (rProperty.Name == SC_EVENTACC_SCRIPT) )
1400 OUString sValue;
1401 if ( rProperty.Value >>= sValue )
1403 ScMacroInfo* pInfo = getInfo( true );
1404 OSL_ENSURE( pInfo, "shape macro info could not be created!" );
1405 if ( !pInfo )
1406 break;
1407 pInfo->SetMacro( sValue );
1413 // XNameAccess
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 };
1437 return aSeq;
1440 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
1442 return aName == SC_EVENTACC_ONCLICK;
1445 // XElementAccess
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)
1454 return true;
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;
1481 if ( xSI.is() )
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";
1493 return aSupported;
1496 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */