LibreOffice Module sc (master)  1
shapeuno.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <comphelper/sequence.hxx>
23 #include <svtools/unoevent.hxx>
24 #include <svtools/unoimap.hxx>
25 #include <svx/svdobj.hxx>
26 #include <svx/ImageMapInfo.hxx>
27 #include <vcl/svapp.hxx>
28 #include <sfx2/event.hxx>
29 #include <svx/unoshape.hxx>
30 #include <editeng/unofield.hxx>
32 #include <cppuhelper/implbase.hxx>
34 
35 #include <com/sun/star/drawing/XShape.hpp>
36 #include <com/sun/star/lang/NoSupportException.hpp>
37 
38 #include <shapeuno.hxx>
39 #include <cellsuno.hxx>
40 #include <textuno.hxx>
41 #include <fielduno.hxx>
42 #include <docsh.hxx>
43 #include <drwlayer.hxx>
44 #include <userdat.hxx>
45 #include <unonames.hxx>
46 
47 using namespace ::com::sun::star;
48 
50 {
51  static const SfxItemPropertyMapEntry aShapeMap_Impl[] =
52  {
61  { u"", 0, css::uno::Type(), 0, 0 }
62  };
63  return aShapeMap_Impl;
64 }
65 
67 {
68  static const SvEventDescription aMacroDescriptionsImpl[] =
69  {
70  { SvMacroItemId::NONE, nullptr }
71  };
72  return aMacroDescriptionsImpl;
73 }
74 ScMacroInfo* ScShapeObj_getShapeHyperMacroInfo( const ScShapeObj* pShape, bool bCreate = false )
75 {
76  if( pShape )
77  if( SdrObject* pObj = pShape->GetSdrObject() )
78  return ScDrawLayer::GetMacroInfo( pObj, bCreate );
79  return nullptr;
80 }
81 
82 ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) :
83  pShapePropertySet(nullptr),
84  pShapePropertyState(nullptr),
85  bIsTextShape(false),
86  bIsNoteCaption(false)
87 {
88  osl_atomic_increment( &m_refCount );
89 
90  {
91  mxShapeAgg.set( xShape, uno::UNO_QUERY );
92  // extra block to force deletion of the temporary before setDelegator
93  }
94 
95  if (mxShapeAgg.is())
96  {
97  xShape = nullptr; // during setDelegator, mxShapeAgg must be the only ref
98 
99  mxShapeAgg->setDelegator( static_cast<cppu::OWeakObject*>(this) );
100 
101  xShape.set(uno::Reference<drawing::XShape>( mxShapeAgg, uno::UNO_QUERY ));
102 
103  bIsTextShape = ( comphelper::getUnoTunnelImplementation<SvxUnoTextBase>( mxShapeAgg ) != nullptr );
104  }
105 
106  {
107  SdrObject* pObj = GetSdrObject();
108  if ( pObj )
109  {
111  }
112  }
113 
114  osl_atomic_decrement( &m_refCount );
115 }
116 
118 {
119 // if (mxShapeAgg.is())
120 // mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>());
121 }
122 
123 // XInterface
124 
126 {
127  uno::Any aRet = ScShapeObj_Base::queryInterface( rType );
128 
129  if ( !aRet.hasValue() && bIsTextShape )
130  aRet = ScShapeObj_TextBase::queryInterface( rType );
131 
132  if ( !aRet.hasValue() && bIsNoteCaption )
133  aRet = ScShapeObj_ChildBase::queryInterface( rType );
134 
135  if ( !aRet.hasValue() && mxShapeAgg.is() )
136  aRet = mxShapeAgg->queryAggregation( rType );
137 
138  return aRet;
139 }
140 
141 void SAL_CALL ScShapeObj::acquire() throw()
142 {
143  OWeakObject::acquire();
144 }
145 
146 void SAL_CALL ScShapeObj::release() throw()
147 {
148  OWeakObject::release();
149 }
150 
152 {
153  // #i61908# Store the result of queryAggregation in a member.
154  // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
155 
156  if (!pShapePropertySet)
157  {
158  uno::Reference<beans::XPropertySet> xProp;
159  if ( mxShapeAgg.is() )
160  mxShapeAgg->queryAggregation( cppu::UnoType<beans::XPropertySet>::get()) >>= xProp;
161  pShapePropertySet = xProp.get();
162  }
163 }
164 
166 {
167  // #i61908# Store the result of queryAggregation in a member.
168  // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
169 
170  if (!pShapePropertyState)
171  {
172  uno::Reference<beans::XPropertyState> xState;
173  if ( mxShapeAgg.is() )
174  mxShapeAgg->queryAggregation( cppu::UnoType<beans::XPropertyState>::get()) >>= xState;
175  pShapePropertyState = xState.get();
176  }
177 }
178 
179 static uno::Reference<lang::XComponent> lcl_GetComponent( const uno::Reference<uno::XAggregation>& xAgg )
180 {
181  uno::Reference<lang::XComponent> xRet;
182  if ( xAgg.is() )
183  xAgg->queryAggregation( cppu::UnoType<lang::XComponent>::get()) >>= xRet;
184  return xRet;
185 }
186 
187 static uno::Reference<text::XText> lcl_GetText( const uno::Reference<uno::XAggregation>& xAgg )
188 {
189  uno::Reference<text::XText> xRet;
190  if ( xAgg.is() )
191  xAgg->queryAggregation( cppu::UnoType<text::XText>::get()) >>= xRet;
192  return xRet;
193 }
194 
195 static uno::Reference<text::XSimpleText> lcl_GetSimpleText( const uno::Reference<uno::XAggregation>& xAgg )
196 {
197  uno::Reference<text::XSimpleText> xRet;
198  if ( xAgg.is() )
199  xAgg->queryAggregation( cppu::UnoType<text::XSimpleText>::get()) >>= xRet;
200  return xRet;
201 }
202 
203 static uno::Reference<text::XTextRange> lcl_GetTextRange( const uno::Reference<uno::XAggregation>& xAgg )
204 {
205  uno::Reference<text::XTextRange> xRet;
206  if ( xAgg.is() )
207  xAgg->queryAggregation( cppu::UnoType<text::XTextRange>::get()) >>= xRet;
208  return xRet;
209 }
210 
211 // XPropertySet
212 
213 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScShapeObj::getPropertySetInfo()
214 {
215  SolarMutexGuard aGuard;
216 
217  // #i61527# cache property set info for this object
218  if ( !mxPropSetInfo.is() )
219  {
220  // mix own and aggregated properties:
222  if (pShapePropertySet)
223  {
224  uno::Reference<beans::XPropertySetInfo> xAggInfo(pShapePropertySet->getPropertySetInfo());
225  const uno::Sequence<beans::Property> aPropSeq(xAggInfo->getProperties());
227  }
228  }
229  return mxPropSetInfo;
230 }
231 
232 static bool lcl_GetPageNum( const SdrPage* pPage, SdrModel& rModel, SCTAB& rNum )
233 {
234  sal_uInt16 nCount = rModel.GetPageCount();
235  for (sal_uInt16 i=0; i<nCount; i++)
236  if ( rModel.GetPage(i) == pPage )
237  {
238  rNum = static_cast<SCTAB>(i);
239  return true;
240  }
241 
242  return false;
243 }
244 
245 static bool lcl_GetCaptionPoint( const uno::Reference< drawing::XShape >& xShape, awt::Point& rCaptionPoint )
246 {
247  bool bReturn = false;
248  OUString sType(xShape->getShapeType());
249  bool bCaptionShape( sType == "com.sun.star.drawing.CaptionShape" );
250  if (bCaptionShape)
251  {
252  uno::Reference < beans::XPropertySet > xShapeProp (xShape, uno::UNO_QUERY);
253  if (xShapeProp.is())
254  {
255  xShapeProp->getPropertyValue("CaptionPoint") >>= rCaptionPoint;
256  bReturn = true;
257  }
258  }
259  return bReturn;
260 }
261 
262 static ScRange lcl_GetAnchorCell( const uno::Reference< drawing::XShape >& xShape, const ScDocument* pDoc, SCTAB nTab,
263  awt::Point& rUnoPoint, awt::Size& rUnoSize, awt::Point& rCaptionPoint )
264 {
265  ScRange aReturn;
266  rUnoPoint = xShape->getPosition();
267  bool bCaptionShape(lcl_GetCaptionPoint(xShape, rCaptionPoint));
268  if (pDoc->IsNegativePage(nTab))
269  {
270  rUnoSize = xShape->getSize();
271  rUnoPoint.X += rUnoSize.Width; // the right top point is base
272  if (bCaptionShape)
273  {
274  if (rCaptionPoint.X > 0 && rCaptionPoint.X > rUnoSize.Width)
275  rUnoPoint.X += rCaptionPoint.X - rUnoSize.Width;
276  if (rCaptionPoint.Y < 0)
277  rUnoPoint.Y += rCaptionPoint.Y;
278  }
279  aReturn = pDoc->GetRange( nTab, tools::Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
280  }
281  else
282  {
283  if (bCaptionShape)
284  {
285  if (rCaptionPoint.X < 0)
286  rUnoPoint.X += rCaptionPoint.X;
287  if (rCaptionPoint.Y < 0)
288  rUnoPoint.Y += rCaptionPoint.Y;
289  }
290  aReturn = pDoc->GetRange( nTab, tools::Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
291  }
292 
293  return aReturn;
294 }
295 
296 static awt::Point lcl_GetRelativePos( const uno::Reference< drawing::XShape >& xShape, const ScDocument* pDoc, SCTAB nTab, ScRange& rRange,
297  awt::Size& rUnoSize, awt::Point& rCaptionPoint)
298 {
299  awt::Point aUnoPoint;
300  rRange = lcl_GetAnchorCell(xShape, pDoc, nTab, aUnoPoint, rUnoSize, rCaptionPoint);
301  tools::Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
302  Point aPoint = pDoc->IsNegativePage(nTab) ? aRect.TopRight() : aRect.TopLeft();
303  aUnoPoint.X -= aPoint.X();
304  aUnoPoint.Y -= aPoint.Y();
305  return aUnoPoint;
306 }
307 
308 void SAL_CALL ScShapeObj::setPropertyValue(const OUString& aPropertyName, const uno::Any& aValue)
309 {
310  SolarMutexGuard aGuard;
311 
312  if ( aPropertyName == SC_UNONAME_ANCHOR )
313  {
314  uno::Reference<sheet::XCellRangeAddressable> xRangeAdd(aValue, uno::UNO_QUERY);
315  if (!xRangeAdd.is())
316  throw lang::IllegalArgumentException("only XCell or XSpreadsheet objects allowed", static_cast<cppu::OWeakObject*>(this), 0);
317 
318  SdrObject *pObj = GetSdrObject();
319  if (pObj)
320  {
321  ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
322  SdrPage* pPage(pObj->getSdrPageFromSdrObject());
323 
324  if ( pPage )
325  {
326  ScDocument* pDoc(rModel.GetDocument());
327 
328  if ( pDoc )
329  {
330  SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
331  if ( auto pDocSh = dynamic_cast<ScDocShell*>( pObjSh) )
332  {
333  SCTAB nTab = 0;
334  if ( lcl_GetPageNum( pPage, rModel, nTab ) )
335  {
336  table::CellRangeAddress aAddress = xRangeAdd->getRangeAddress();
337  if (nTab == aAddress.Sheet)
338  {
339  tools::Rectangle aRect(pDoc->GetMMRect( static_cast<SCCOL>(aAddress.StartColumn), static_cast<SCROW>(aAddress.StartRow),
340  static_cast<SCCOL>(aAddress.EndColumn), static_cast<SCROW>(aAddress.EndRow), aAddress.Sheet ));
341  awt::Point aRelPoint;
342  uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
343  if (xShape.is())
344  {
345  Point aPoint;
346  Point aEndPoint;
347  if (pDoc->IsNegativePage(nTab))
348  {
349  aPoint = aRect.TopRight();
350  aEndPoint = aRect.BottomLeft();
351  }
352  else
353  {
354  aPoint = aRect.TopLeft();
355  aEndPoint = aRect.BottomRight();
356  }
357  awt::Size aUnoSize;
358  awt::Point aCaptionPoint;
359  ScRange aRange;
360  aRelPoint = lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint );
361  awt::Point aUnoPoint(aRelPoint);
362 
363  aUnoPoint.X += aPoint.X();
364  aUnoPoint.Y += aPoint.Y();
365 
366  if ( aUnoPoint.Y > aEndPoint.Y() )
367  aUnoPoint.Y = aEndPoint.Y() - 2;
368  if (pDoc->IsNegativePage(nTab))
369  {
370  if ( aUnoPoint.X < aEndPoint.X() )
371  aUnoPoint.X = aEndPoint.X() + 2;
372  aUnoPoint.X -= aUnoSize.Width;
373  // remove difference to caption point
374  if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
375  aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
376  }
377  else
378  {
379  if ( aUnoPoint.X > aEndPoint.X() )
380  aUnoPoint.X = aEndPoint.X() - 2;
381  if (aCaptionPoint.X < 0)
382  aUnoPoint.X -= aCaptionPoint.X;
383  }
384  if (aCaptionPoint.Y < 0)
385  aUnoPoint.Y -= aCaptionPoint.Y;
386 
387  xShape->setPosition(aUnoPoint);
388  pDocSh->SetModified();
389  }
390 
391  if (aAddress.StartRow != aAddress.EndRow) //should be a Spreadsheet
392  {
393  OSL_ENSURE(aAddress.StartRow == 0 && aAddress.EndRow == pDoc->MaxRow() &&
394  aAddress.StartColumn == 0 && aAddress.EndColumn == pDoc->MaxCol(), "here should be a XSpreadsheet");
396  }
397  else
398  {
399  OSL_ENSURE(aAddress.StartRow == aAddress.EndRow &&
400  aAddress.StartColumn == aAddress.EndColumn, "here should be a XCell");
401  ScDrawObjData aAnchor;
402  aAnchor.maStart = ScAddress(aAddress.StartColumn, aAddress.StartRow, aAddress.Sheet);
403  aAnchor.maStartOffset = Point(aRelPoint.X, aRelPoint.Y);
404  ScDrawObjData* pDrawObjData = ScDrawLayer::GetObjData(pObj);
405  if (pDrawObjData)
406  aAnchor.mbResizeWithCell = pDrawObjData->mbResizeWithCell;
407  //Uno sets the Anchor in terms of the unrotated shape, not much we can do
408  //about that since uno also displays the shape geometry in terms of the unrotated
409  //shape. #TODO think about changing the anchoring behaviour here too
410  //Currently we've only got a start anchor, not an end-anchor, so generate that now
411  ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, aAnchor, *pDoc, aAddress.Sheet);
412  ScDrawLayer::SetCellAnchored(*pObj, aAnchor);
413  }
414  }
415  }
416  }
417  }
418  }
419  }
420 
421  }
422  else if ( aPropertyName == SC_UNONAME_RESIZE_WITH_CELL )
423  {
424  SdrObject* pObj = GetSdrObject();
425  if (!pObj)
426  return;
427  ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType(*pObj);
428 
429  // Nothing to do if anchored to page
430  if (aAnchorType == SCA_PAGE)
431  return;
432 
433  ScDrawObjData* pDrawObjData = ScDrawLayer::GetObjData(pObj);
434  if (!pDrawObjData)
435  return;
436 
437  aValue >>= pDrawObjData->mbResizeWithCell;
438  ScDrawLayer::SetCellAnchored(*pObj, *pDrawObjData);
439  }
440  else if ( aPropertyName == SC_UNONAME_IMAGEMAP )
441  {
442  SdrObject* pObj = GetSdrObject();
443  if ( pObj )
444  {
445  ImageMap aImageMap;
446  uno::Reference< uno::XInterface > xImageMapInt(aValue, uno::UNO_QUERY);
447 
448  if( !xImageMapInt.is() || !SvUnoImageMap_fillImageMap( xImageMapInt, aImageMap ) )
449  throw lang::IllegalArgumentException();
450 
451  SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo(pObj);
452  if( pIMapInfo )
453  {
454  // replace existing image map
455  pIMapInfo->SetImageMap( aImageMap );
456  }
457  else
458  {
459  // insert new user data with image map
460  pObj->AppendUserData(std::unique_ptr<SdrObjUserData>(new SvxIMapInfo(aImageMap) ));
461  }
462  }
463  }
464  else if ( aPropertyName == SC_UNONAME_HORIPOS )
465  {
466  sal_Int32 nPos = 0;
467  if (aValue >>= nPos)
468  {
469  SdrObject *pObj = GetSdrObject();
470  if (pObj)
471  {
472  ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
473  SdrPage* pPage(pObj->getSdrPageFromSdrObject());
474 
475  if ( pPage )
476  {
477  SCTAB nTab = 0;
478  if ( lcl_GetPageNum( pPage, rModel, nTab ) )
479  {
480  ScDocument* pDoc = rModel.GetDocument();
481  if ( pDoc )
482  {
483  SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
484  if ( auto pDocSh = dynamic_cast<ScDocShell*>( pObjSh) )
485  {
486  uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
487  if (xShape.is())
488  {
489  if (ScDrawLayer::GetAnchorType(*pObj) == SCA_PAGE)
490  {
491  awt::Point aPoint(xShape->getPosition());
492  awt::Size aSize(xShape->getSize());
493  awt::Point aCaptionPoint;
494  if (pDoc->IsNegativePage(nTab))
495  {
496  nPos *= -1;
497  nPos -= aSize.Width;
498  }
499  if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
500  {
501  if (pDoc->IsNegativePage(nTab))
502  {
503  if (aCaptionPoint.X > 0 && aCaptionPoint.X > aSize.Width)
504  nPos -= aCaptionPoint.X - aSize.Width;
505  }
506  else
507  {
508  if (aCaptionPoint.X < 0)
509  nPos -= aCaptionPoint.X;
510  }
511  }
512  aPoint.X = nPos;
513  xShape->setPosition(aPoint);
514  pDocSh->SetModified();
515  }
516  else if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL
518  == SCA_CELL_RESIZE)
519  {
520  awt::Size aUnoSize;
521  awt::Point aCaptionPoint;
522  ScRange aRange;
523  awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
524  tools::Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
525  if (pDoc->IsNegativePage(nTab))
526  {
527  aUnoPoint.X = -nPos;
528  Point aPoint(aRect.TopRight());
529  Point aEndPoint(aRect.BottomLeft());
530  aUnoPoint.X += aPoint.X();
531  if (aUnoPoint.X < aEndPoint.X())
532  aUnoPoint.X = aEndPoint.X() + 2;
533  aUnoPoint.X -= aUnoSize.Width;
534  if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
535  aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
536  }
537  else
538  {
539  aUnoPoint.X = nPos;
540  Point aPoint(aRect.TopLeft());
541  Point aEndPoint(aRect.BottomRight());
542  aUnoPoint.X += aPoint.X();
543  if (aUnoPoint.X > aEndPoint.X())
544  aUnoPoint.X = aEndPoint.X() - 2;
545  if (aCaptionPoint.X < 0)
546  aUnoPoint.X -= aCaptionPoint.X;
547  }
548  aUnoPoint.Y = xShape->getPosition().Y;
549  xShape->setPosition(aUnoPoint);
550  pDocSh->SetModified();
551  }
552  else
553  {
554  OSL_FAIL("unknown anchor type");
555  }
556  }
557  }
558  }
559  }
560  }
561  }
562  }
563  }
564  else if ( aPropertyName == SC_UNONAME_VERTPOS )
565  {
566  sal_Int32 nPos = 0;
567  if (aValue >>= nPos)
568  {
569  SdrObject *pObj = GetSdrObject();
570  if (pObj)
571  {
572  ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
573  SdrPage* pPage(pObj->getSdrPageFromSdrObject());
574 
575  if ( pPage )
576  {
577  SCTAB nTab = 0;
578  if ( lcl_GetPageNum( pPage, rModel, nTab ) )
579  {
580  ScDocument* pDoc = rModel.GetDocument();
581  if ( pDoc )
582  {
583  SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
584  if ( auto pDocSh = dynamic_cast<ScDocShell*>( pObjSh) )
585  {
586  uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
587  if (xShape.is())
588  {
589  if (ScDrawLayer::GetAnchorType(*pObj) == SCA_PAGE)
590  {
591  awt::Point aPoint = xShape->getPosition();
592  awt::Point aCaptionPoint;
593  if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
594  {
595  if (aCaptionPoint.Y < 0)
596  nPos -= aCaptionPoint.Y;
597  }
598  aPoint.Y = nPos;
599  xShape->setPosition(aPoint);
600  pDocSh->SetModified();
601  }
602  else if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL
604  == SCA_CELL_RESIZE)
605  {
606  awt::Size aUnoSize;
607  awt::Point aCaptionPoint;
608  ScRange aRange;
609  awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
610  tools::Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
611  Point aPoint(aRect.TopRight());
612  Point aEndPoint(aRect.BottomLeft());
613  aUnoPoint.Y = nPos;
614  aUnoPoint.Y += aPoint.Y();
615  if (aUnoPoint.Y > aEndPoint.Y())
616  aUnoPoint.Y = aEndPoint.Y() - 2;
617  if (aCaptionPoint.Y < 0)
618  aUnoPoint.Y -= aCaptionPoint.Y;
619  aUnoPoint.X = xShape->getPosition().X;
620  xShape->setPosition(aUnoPoint);
621  pDocSh->SetModified();
622  }
623  else
624  {
625  OSL_FAIL("unknown anchor type");
626  }
627  }
628  }
629  }
630  }
631  }
632  }
633  }
634  }
635  else if ( aPropertyName == SC_UNONAME_HYPERLINK ||
636  aPropertyName == SC_UNONAME_URL )
637  {
638  OUString sHlink;
639  ScMacroInfo* pInfo = ScShapeObj_getShapeHyperMacroInfo(this, true);
640  if ( ( aValue >>= sHlink ) && pInfo )
641  pInfo->SetHlink( sHlink );
642  }
643  else if ( aPropertyName == SC_UNONAME_MOVEPROTECT )
644  {
645  if( SdrObject* pObj = GetSdrObject() )
646  {
647  bool aProt = false;
648  if( aValue >>= aProt )
649  pObj->SetMoveProtect( aProt );
650  }
651  }
652  else
653  {
655  if (pShapePropertySet)
656  pShapePropertySet->setPropertyValue( aPropertyName, aValue );
657  }
658 }
659 
660 uno::Any SAL_CALL ScShapeObj::getPropertyValue( const OUString& aPropertyName )
661 {
662  SolarMutexGuard aGuard;
663 
664  uno::Any aAny;
665  if ( aPropertyName == SC_UNONAME_ANCHOR )
666  {
667  SdrObject *pObj = GetSdrObject();
668  if (pObj)
669  {
670  ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
671  SdrPage* pPage(pObj->getSdrPageFromSdrObject());
672 
673  if ( pPage )
674  {
675  ScDocument* pDoc = rModel.GetDocument();
676  if ( pDoc )
677  {
678  SCTAB nTab = 0;
679  if ( lcl_GetPageNum( pPage, rModel, nTab ) )
680  {
681  SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
682  if ( auto pDocSh = dynamic_cast<ScDocShell*>( pObjSh) )
683  {
684  uno::Reference< uno::XInterface > xAnchor;
685  if (ScDrawObjData *pAnchor = ScDrawLayer::GetObjDataTab(pObj, nTab))
686  xAnchor.set(static_cast<cppu::OWeakObject*>(new ScCellObj( pDocSh, pAnchor->maStart)));
687  else
688  xAnchor.set(static_cast<cppu::OWeakObject*>(new ScTableSheetObj( pDocSh, nTab )));
689  aAny <<= xAnchor;
690  }
691  }
692  }
693  }
694  }
695  }
696  else if (aPropertyName == SC_UNONAME_RESIZE_WITH_CELL)
697  {
698  bool bIsResizeWithCell = false;
699  SdrObject* pObj = GetSdrObject();
700  if (pObj)
701  {
702  ScAnchorType anchorType = ScDrawLayer::GetAnchorType(*pObj);
703  bIsResizeWithCell = (anchorType == SCA_CELL_RESIZE);
704  }
705  aAny <<= bIsResizeWithCell;
706  }
707  else if ( aPropertyName == SC_UNONAME_IMAGEMAP )
708  {
709  uno::Reference< uno::XInterface > xImageMap;
710  SdrObject* pObj = GetSdrObject();
711  if ( pObj )
712  {
714  if( pIMapInfo )
715  {
716  const ImageMap& rIMap = pIMapInfo->GetImageMap();
717  xImageMap.set(SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() ));
718  }
719  else
720  xImageMap = SvUnoImageMap_createInstance();
721  }
722  aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
723  }
724  else if ( aPropertyName == SC_UNONAME_HORIPOS )
725  {
726  SdrObject *pObj = GetSdrObject();
727  if (pObj)
728  {
729  ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
730  SdrPage* pPage(pObj->getSdrPageFromSdrObject());
731 
732  if ( pPage )
733  {
734  ScDocument* pDoc = rModel.GetDocument();
735  if ( pDoc )
736  {
737  SCTAB nTab = 0;
738  if ( lcl_GetPageNum( pPage, rModel, nTab ) )
739  {
740  uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
741  if (xShape.is())
742  {
745  {
746  awt::Size aUnoSize;
747  awt::Point aCaptionPoint;
748  ScRange aRange;
749  awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
750  if (pDoc->IsNegativePage(nTab))
751  aUnoPoint.X *= -1;
752  aAny <<= aUnoPoint.X;
753  }
754  else
755  {
756  awt::Point aCaptionPoint;
757  awt::Point aUnoPoint(xShape->getPosition());
758  awt::Size aUnoSize(xShape->getSize());
759  if (pDoc->IsNegativePage(nTab))
760  {
761  aUnoPoint.X *= -1;
762  aUnoPoint.X -= aUnoSize.Width;
763  }
764  if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
765  {
766  if (pDoc->IsNegativePage(nTab))
767  {
768  if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
769  aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
770  }
771  else
772  {
773  if (aCaptionPoint.X < 0)
774  aUnoPoint.X += aCaptionPoint.X;
775  }
776  }
777  aAny <<= aUnoPoint.X;
778  }
779  }
780  }
781  }
782  }
783  }
784  }
785  else if ( aPropertyName == SC_UNONAME_VERTPOS )
786  {
787  SdrObject *pObj = GetSdrObject();
788  if (pObj)
789  {
790  ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
791  SdrPage* pPage(pObj->getSdrPageFromSdrObject());
792 
793  if ( pPage )
794  {
795  ScDocument* pDoc = rModel.GetDocument();
796  if ( pDoc )
797  {
798  SCTAB nTab = 0;
799  if ( lcl_GetPageNum( pPage, rModel, nTab ) )
800  {
801  uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
802  if (xShape.is())
803  {
806  {
807  awt::Size aUnoSize;
808  awt::Point aCaptionPoint;
809  ScRange aRange;
810  awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
811 
812  aAny <<= aUnoPoint.Y;
813  }
814  else
815  {
816  awt::Point aUnoPoint(xShape->getPosition());
817  awt::Point aCaptionPoint;
818  if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
819  {
820  if (aCaptionPoint.Y < 0)
821  aUnoPoint.Y += aCaptionPoint.Y;
822  }
823  aAny <<= aUnoPoint.Y;
824  }
825  }
826  }
827  }
828  }
829  }
830  }
831  else if ( aPropertyName == SC_UNONAME_HYPERLINK ||
832  aPropertyName == SC_UNONAME_URL )
833  {
834  OUString sHlink;
835  if ( ScMacroInfo* pInfo = ScShapeObj_getShapeHyperMacroInfo(this) )
836  sHlink = pInfo->GetHlink();
837  aAny <<= sHlink;
838  }
839  else if ( aPropertyName == SC_UNONAME_MOVEPROTECT )
840  {
841  bool aProt = false;
842  if ( SdrObject* pObj = GetSdrObject() )
843  aProt = pObj->IsMoveProtect();
844  aAny <<= aProt;
845  }
846  else
847  {
848  if(!pShapePropertySet) //performance consideration
850  if (pShapePropertySet)
851  aAny = pShapePropertySet->getPropertyValue( aPropertyName );
852  }
853 
854  return aAny;
855 }
856 
857 void SAL_CALL ScShapeObj::addPropertyChangeListener( const OUString& aPropertyName,
858  const uno::Reference<beans::XPropertyChangeListener>& aListener)
859 {
860  SolarMutexGuard aGuard;
861 
863  if (pShapePropertySet)
864  pShapePropertySet->addPropertyChangeListener( aPropertyName, aListener );
865 }
866 
867 void SAL_CALL ScShapeObj::removePropertyChangeListener( const OUString& aPropertyName,
868  const uno::Reference<beans::XPropertyChangeListener>& aListener)
869 {
870  SolarMutexGuard aGuard;
871 
873  if (pShapePropertySet)
874  pShapePropertySet->removePropertyChangeListener( aPropertyName, aListener );
875 }
876 
877 void SAL_CALL ScShapeObj::addVetoableChangeListener( const OUString& aPropertyName,
878  const uno::Reference<beans::XVetoableChangeListener>& aListener)
879 {
880  SolarMutexGuard aGuard;
881 
883  if (pShapePropertySet)
884  pShapePropertySet->addVetoableChangeListener( aPropertyName, aListener );
885 }
886 
887 void SAL_CALL ScShapeObj::removeVetoableChangeListener( const OUString& aPropertyName,
888  const uno::Reference<beans::XVetoableChangeListener>& aListener)
889 {
890  SolarMutexGuard aGuard;
891 
893  if (pShapePropertySet)
894  pShapePropertySet->removeVetoableChangeListener( aPropertyName, aListener );
895 }
896 
897 // XPropertyState
898 
899 beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const OUString& aPropertyName )
900 {
901  SolarMutexGuard aGuard;
902 
903  beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
904  if ( aPropertyName == SC_UNONAME_IMAGEMAP )
905  {
906  // ImageMap is always "direct"
907  }
908  else if ( aPropertyName == SC_UNONAME_ANCHOR )
909  {
910  // Anchor is always "direct"
911  }
912  else if ( aPropertyName == SC_UNONAME_HORIPOS )
913  {
914  // HoriPos is always "direct"
915  }
916  else if ( aPropertyName == SC_UNONAME_VERTPOS )
917  {
918  // VertPos is always "direct"
919  }
920  else
921  {
924  eRet = pShapePropertyState->getPropertyState( aPropertyName );
925  }
926 
927  return eRet;
928 }
929 
930 uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates(
931  const uno::Sequence<OUString>& aPropertyNames )
932 {
933  SolarMutexGuard aGuard;
934 
935  // simple loop to get own and aggregated states
936 
937  uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
938  std::transform(aPropertyNames.begin(), aPropertyNames.end(), aRet.begin(),
939  [this](const OUString& rName) -> beans::PropertyState { return getPropertyState(rName); });
940  return aRet;
941 }
942 
943 void SAL_CALL ScShapeObj::setPropertyToDefault( const OUString& aPropertyName )
944 {
945  SolarMutexGuard aGuard;
946 
947  if ( aPropertyName == SC_UNONAME_IMAGEMAP )
948  {
949  SdrObject* pObj = GetSdrObject();
950  if ( pObj )
951  {
952  SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo(pObj);
953  if( pIMapInfo )
954  {
955  ImageMap aEmpty;
956  pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map
957  }
958  else
959  {
960  // nothing to do (no need to insert user data for an empty map)
961  }
962  }
963  }
964  else
965  {
968  pShapePropertyState->setPropertyToDefault( aPropertyName );
969  }
970 }
971 
972 uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const OUString& aPropertyName )
973 {
974  SolarMutexGuard aGuard;
975 
976  uno::Any aAny;
977  if ( aPropertyName == SC_UNONAME_IMAGEMAP )
978  {
979  // default: empty ImageMap
980  uno::Reference< uno::XInterface > xImageMap(SvUnoImageMap_createInstance());
981  aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
982  }
983  else
984  {
987  aAny = pShapePropertyState->getPropertyDefault( aPropertyName );
988  }
989 
990  return aAny;
991 }
992 
993 // XTextContent
994 
995 void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& /* xTextRange */ )
996 {
997  SolarMutexGuard aGuard;
998 
999  throw lang::IllegalArgumentException(); // anchor cannot be changed
1000 }
1001 
1002 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor()
1003 {
1004  SolarMutexGuard aGuard;
1005 
1006  uno::Reference<text::XTextRange> xRet;
1007 
1008  SdrObject* pObj = GetSdrObject();
1009  if( pObj )
1010  {
1011  ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
1012  SdrPage* pPage(pObj->getSdrPageFromSdrObject());
1013  ScDocument* pDoc = rModel.GetDocument();
1014 
1015  if ( pPage && pDoc )
1016  {
1017  SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1018  if ( auto pDocSh = dynamic_cast<ScDocShell*>( pObjSh) )
1019  {
1020  SCTAB nTab = 0;
1021  if ( lcl_GetPageNum( pPage, rModel, nTab ) )
1022  {
1023  Point aPos(pObj->GetCurrentBoundRect().TopLeft());
1024  ScRange aRange(pDoc->GetRange( nTab, tools::Rectangle( aPos, aPos ) ));
1025 
1026  // anchor is always the cell
1027 
1028  xRet.set(new ScCellObj( pDocSh, aRange.aStart ));
1029  }
1030  }
1031  }
1032  }
1033 
1034  return xRet;
1035 }
1036 
1037 // XComponent
1038 
1039 void SAL_CALL ScShapeObj::dispose()
1040 {
1041  SolarMutexGuard aGuard;
1042 
1043  uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1044  if ( xAggComp.is() )
1045  xAggComp->dispose();
1046 }
1047 
1049  const uno::Reference<lang::XEventListener>& xListener )
1050 {
1051  SolarMutexGuard aGuard;
1052 
1053  uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1054  if ( xAggComp.is() )
1055  xAggComp->addEventListener(xListener);
1056 }
1057 
1059  const uno::Reference<lang::XEventListener>& xListener )
1060 {
1061  SolarMutexGuard aGuard;
1062 
1063  uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1064  if ( xAggComp.is() )
1065  xAggComp->removeEventListener(xListener);
1066 }
1067 
1068 // XText
1069 // (special handling for ScCellFieldObj)
1070 
1071 static void lcl_CopyOneProperty( beans::XPropertySet& rDest, beans::XPropertySet& rSource, const char* pName )
1072 {
1073  OUString aNameStr(OUString::createFromAscii(pName));
1074  try
1075  {
1076  rDest.setPropertyValue( aNameStr, rSource.getPropertyValue( aNameStr ) );
1077  }
1078  catch (uno::Exception&)
1079  {
1080  OSL_FAIL("Exception in text field");
1081  }
1082 }
1083 
1084 void SAL_CALL ScShapeObj::insertTextContent( const uno::Reference<text::XTextRange>& xRange,
1085  const uno::Reference<text::XTextContent>& xContent,
1086  sal_Bool bAbsorb )
1087 {
1088  SolarMutexGuard aGuard;
1089 
1090  uno::Reference<text::XTextContent> xEffContent;
1091 
1092  ScEditFieldObj* pCellField = comphelper::getUnoTunnelImplementation<ScEditFieldObj>( xContent );
1093  if ( pCellField )
1094  {
1095  // createInstance("TextField.URL") from the document creates a ScCellFieldObj.
1096  // To insert it into drawing text, a SvxUnoTextField is needed instead.
1097  // The ScCellFieldObj object is left in non-inserted state.
1098 
1099  SvxUnoTextField* pDrawField = new SvxUnoTextField( text::textfield::Type::URL );
1100  xEffContent.set(pDrawField);
1101  lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL );
1102  lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR );
1103  lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET );
1104  }
1105  else
1106  xEffContent.set(xContent);
1107 
1108  uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1109  if ( xAggText.is() )
1110  xAggText->insertTextContent( xRange, xEffContent, bAbsorb );
1111 }
1112 
1113 void SAL_CALL ScShapeObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
1114 {
1115  SolarMutexGuard aGuard;
1116 
1117  // ScCellFieldObj can't be used here.
1118 
1119  uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1120  if ( xAggText.is() )
1121  xAggText->removeTextContent( xContent );
1122 }
1123 
1124 // XSimpleText (parent of XText)
1125 // Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object
1126 
1127 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursor()
1128 {
1129  SolarMutexGuard aGuard;
1130 
1131  if ( mxShapeAgg.is() )
1132  {
1133  // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1134 
1135  SvxUnoTextBase* pText = comphelper::getUnoTunnelImplementation<SvxUnoTextBase>( mxShapeAgg );
1136  if (pText)
1137  return new ScDrawTextCursor( this, *pText );
1138  }
1139 
1140  return uno::Reference<text::XTextCursor>();
1141 }
1142 
1143 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursorByRange(
1144  const uno::Reference<text::XTextRange>& aTextPosition )
1145 {
1146  SolarMutexGuard aGuard;
1147 
1148  if ( mxShapeAgg.is() && aTextPosition.is() )
1149  {
1150  // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1151 
1152  SvxUnoTextBase* pText = comphelper::getUnoTunnelImplementation<SvxUnoTextBase>( mxShapeAgg );
1153  SvxUnoTextRangeBase* pRange = comphelper::getUnoTunnelImplementation<SvxUnoTextRangeBase>( aTextPosition );
1154  if ( pText && pRange )
1155  {
1156  SvxUnoTextCursor* pCursor = new ScDrawTextCursor( this, *pText );
1157  uno::Reference<text::XTextCursor> xCursor( pCursor );
1158  pCursor->SetSelection( pRange->GetSelection() );
1159  return xCursor;
1160  }
1161  }
1162 
1163  return uno::Reference<text::XTextCursor>();
1164 }
1165 
1166 void SAL_CALL ScShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange,
1167  const OUString& aString, sal_Bool bAbsorb )
1168 {
1169  SolarMutexGuard aGuard;
1170 
1171  uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1172  if ( !xAggSimpleText.is() )
1173  throw uno::RuntimeException();
1174 
1175  xAggSimpleText->insertString( xRange, aString, bAbsorb );
1176 }
1177 
1178 void SAL_CALL ScShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
1179  sal_Int16 nControlCharacter, sal_Bool bAbsorb )
1180 {
1181  SolarMutexGuard aGuard;
1182 
1183  uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1184  if ( !xAggSimpleText.is() )
1185  throw uno::RuntimeException();
1186 
1187  xAggSimpleText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
1188 }
1189 
1190 // XTextRange
1191 // (parent of XSimpleText)
1192 
1193 uno::Reference<text::XText> SAL_CALL ScShapeObj::getText()
1194 {
1195  return this;
1196 }
1197 
1198 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart()
1199 {
1200  SolarMutexGuard aGuard;
1201 
1202  uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1203  if ( !xAggTextRange.is() )
1204  throw uno::RuntimeException();
1205 
1206  return xAggTextRange->getStart();
1207 }
1208 
1209 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getEnd()
1210 {
1211  SolarMutexGuard aGuard;
1212 
1213  uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1214  if ( !xAggTextRange.is() )
1215  throw uno::RuntimeException();
1216 
1217  return xAggTextRange->getEnd();
1218 }
1219 
1220 OUString SAL_CALL ScShapeObj::getString()
1221 {
1222  SolarMutexGuard aGuard;
1223 
1224  uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1225  if ( !xAggTextRange.is() )
1226  throw uno::RuntimeException();
1227 
1228  return xAggTextRange->getString();
1229 }
1230 
1231 void SAL_CALL ScShapeObj::setString( const OUString& aText )
1232 {
1233  SolarMutexGuard aGuard;
1234 
1235  uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1236  if ( !xAggTextRange.is() )
1237  throw uno::RuntimeException();
1238 
1239  xAggTextRange->setString( aText );
1240 }
1241 
1242 // XChild
1243 
1244 uno::Reference< uno::XInterface > SAL_CALL ScShapeObj::getParent()
1245 {
1246  SolarMutexGuard aGuard;
1247 
1248  // receive cell position from caption object (parent of a note caption is the note cell)
1249  SdrObject* pObj = GetSdrObject();
1250  if( pObj )
1251  {
1252  ScDrawLayer& rModel(static_cast< ScDrawLayer& >(pObj->getSdrModelFromSdrObject()));
1253  SdrPage* pPage(pObj->getSdrPageFromSdrObject());
1254  ScDocument* pDoc = rModel.GetDocument();
1255 
1256  if ( pPage && pDoc )
1257  {
1258  SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1259  if ( auto pDocSh = dynamic_cast<ScDocShell*>( pObjSh) )
1260  {
1261  SCTAB nTab = 0;
1262  if ( lcl_GetPageNum( pPage, rModel, nTab ) )
1263  {
1264  const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab );
1265  if( pCaptData )
1266  return static_cast< ::cppu::OWeakObject* >( new ScCellObj( pDocSh, pCaptData->maStart ) );
1267  }
1268  }
1269  }
1270  }
1271 
1272  return nullptr;
1273 }
1274 
1275 void SAL_CALL ScShapeObj::setParent( const uno::Reference< uno::XInterface >& )
1276 {
1277  throw lang::NoSupportException();
1278 }
1279 
1280 // XTypeProvider
1281 
1282 uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes()
1283 {
1284  uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() );
1285 
1286  uno::Sequence< uno::Type > aTextTypes;
1287  if ( bIsTextShape )
1288  aTextTypes = ScShapeObj_TextBase::getTypes();
1289 
1290  uno::Reference<lang::XTypeProvider> xBaseProvider;
1291  if ( mxShapeAgg.is() )
1292  mxShapeAgg->queryAggregation( cppu::UnoType<lang::XTypeProvider>::get()) >>= xBaseProvider;
1293  OSL_ENSURE( xBaseProvider.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" );
1294 
1295  uno::Sequence< uno::Type > aAggTypes;
1296  if( xBaseProvider.is() )
1297  aAggTypes = xBaseProvider->getTypes();
1298 
1299  return ::comphelper::concatSequences( aBaseTypes, aTextTypes, aAggTypes );
1300 }
1301 
1302 uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId()
1303 {
1304  return css::uno::Sequence<sal_Int8>();
1305 }
1306 
1308 {
1309  if(mxShapeAgg.is())
1310  {
1311  SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( mxShapeAgg );
1312  if(pShape)
1313  return pShape->GetSdrObject();
1314  }
1315 
1316  return nullptr;
1317 }
1318 
1319 #define SC_EVENTACC_ONCLICK "OnClick"
1320 #define SC_EVENTACC_SCRIPT "Script"
1321 #define SC_EVENTACC_EVENTTYPE "EventType"
1322 
1323 class ShapeUnoEventAccessImpl : public ::cppu::WeakImplHelper< container::XNameReplace >
1324 {
1325 private:
1327 
1328  ScMacroInfo* getInfo( bool bCreate )
1329  {
1330  return ScShapeObj_getShapeHyperMacroInfo( mpShape, bCreate );
1331  }
1332 
1333 public:
1334  explicit ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
1335  {
1336  }
1337 
1338  // XNameReplace
1339  virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override
1340  {
1341  if ( !hasByName( aName ) )
1342  throw container::NoSuchElementException();
1343  uno::Sequence< beans::PropertyValue > aProperties;
1344  aElement >>= aProperties;
1345  bool isEventType = false;
1346  for( const beans::PropertyValue& rProperty : std::as_const(aProperties) )
1347  {
1348  if ( rProperty.Name == SC_EVENTACC_EVENTTYPE )
1349  {
1350  isEventType = true;
1351  continue;
1352  }
1353  if ( isEventType && (rProperty.Name == SC_EVENTACC_SCRIPT) )
1354  {
1355  OUString sValue;
1356  if ( rProperty.Value >>= sValue )
1357  {
1358  ScMacroInfo* pInfo = getInfo( true );
1359  OSL_ENSURE( pInfo, "shape macro info could not be created!" );
1360  if ( !pInfo )
1361  break;
1362  if ( rProperty.Name == SC_EVENTACC_SCRIPT )
1363  pInfo->SetMacro( sValue );
1364  else
1365  pInfo->SetHlink( sValue );
1366  }
1367  }
1368  }
1369  }
1370 
1371  // XNameAccess
1372  virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
1373  {
1374  uno::Sequence< beans::PropertyValue > aProperties;
1375  ScMacroInfo* pInfo = getInfo(false);
1376 
1377  if ( aName != SC_EVENTACC_ONCLICK )
1378  {
1379  throw container::NoSuchElementException();
1380  }
1381 
1382  if ( pInfo && !pInfo->GetMacro().isEmpty() )
1383  {
1384  aProperties.realloc( 2 );
1385  aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
1386  aProperties[ 0 ].Value <<= OUString(SC_EVENTACC_SCRIPT);
1387  aProperties[ 1 ].Name = SC_EVENTACC_SCRIPT;
1388  aProperties[ 1 ].Value <<= pInfo->GetMacro();
1389  }
1390 
1391  return uno::Any( aProperties );
1392  }
1393 
1394  virtual uno::Sequence< OUString > SAL_CALL getElementNames() override
1395  {
1396  uno::Sequence<OUString> aSeq { SC_EVENTACC_ONCLICK };
1397  return aSeq;
1398  }
1399 
1400  virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
1401  {
1402  return aName == SC_EVENTACC_ONCLICK;
1403  }
1404 
1405  // XElementAccess
1406  virtual uno::Type SAL_CALL getElementType() override
1407  {
1409  }
1410 
1411  virtual sal_Bool SAL_CALL hasElements() override
1412  {
1413  // elements are always present (but contained property sequences may be empty)
1414  return true;
1415  }
1416 };
1417 
1418 ::uno::Reference< container::XNameReplace > SAL_CALL
1420 {
1421  return new ShapeUnoEventAccessImpl( this );
1422 }
1423 
1425 {
1426  return "com.sun.star.comp.sc.ScShapeObj";
1427 }
1428 
1429 sal_Bool SAL_CALL ScShapeObj::supportsService( const OUString& ServiceName )
1430 {
1431  return cppu::supportsService(this, ServiceName);
1432 }
1433 
1434 uno::Sequence< OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( )
1435 {
1436  uno::Reference<lang::XServiceInfo> xSI;
1437  if ( mxShapeAgg.is() )
1438  mxShapeAgg->queryAggregation( cppu::UnoType<lang::XServiceInfo>::get() ) >>= xSI;
1439 
1440  uno::Sequence< OUString > aSupported;
1441  if ( xSI.is() )
1442  aSupported = xSI->getSupportedServiceNames();
1443 
1444  aSupported.realloc( aSupported.getLength() + 1 );
1445  aSupported[ aSupported.getLength() - 1 ] = "com.sun.star.sheet.Shape";
1446 
1447  if( bIsNoteCaption )
1448  {
1449  aSupported.realloc( aSupported.getLength() + 1 );
1450  aSupported[ aSupported.getLength() - 1 ] = "com.sun.star.sheet.CellAnnotationShape";
1451  }
1452 
1453  return aSupported;
1454 }
1455 
1456 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getEnd() override
Definition: shapeuno.cxx:1209
Point TopLeft() const
virtual uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: shapeuno.cxx:1394
#define SC_UNONAME_HORIPOS
Definition: unonames.hxx:196
static uno::Reference< lang::XComponent > lcl_GetComponent(const uno::Reference< uno::XAggregation > &xAgg)
Definition: shapeuno.cxx:179
static bool lcl_GetCaptionPoint(const uno::Reference< drawing::XShape > &xShape, awt::Point &rCaptionPoint)
Definition: shapeuno.cxx:245
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: shapeuno.cxx:1434
bool hasValue()
ScAddress aStart
Definition: address.hxx:500
void SetImageMap(const ImageMap &rIMap)
virtual const tools::Rectangle & GetCurrentBoundRect() const
css::beans::XPropertyState * pShapePropertyState
Definition: shapeuno.hxx:69
friend class ShapeUnoEventAccessImpl
Definition: shapeuno.hxx:79
static uno::Reference< text::XSimpleText > lcl_GetSimpleText(const uno::Reference< uno::XAggregation > &xAgg)
Definition: shapeuno.cxx:195
#define SC_EVENTACC_SCRIPT
Definition: shapeuno.cxx:1320
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
Definition: document.cxx:1002
const OUString & GetMacro() const
Definition: userdat.hxx:84
SCROW Row() const
Definition: address.hxx:262
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: shapeuno.cxx:213
#define SC_UNONAME_RESIZE_WITH_CELL
Definition: unonames.hxx:195
static void SetPageAnchored(SdrObject &)
Definition: drwlayer.cxx:2315
Point BottomLeft() const
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: shapeuno.cxx:887
#define SC_UNONAME_REPR
Definition: unonames.hxx:329
ULONG m_refCount
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
Definition: shapeuno.cxx:1244
static ScMacroInfo * GetMacroInfo(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2516
static ScDrawObjData * GetObjData(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2477
virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates(const css::uno::Sequence< OUString > &aPropertyName) override
Definition: shapeuno.cxx:930
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: shapeuno.cxx:877
virtual sal_Bool SAL_CALL hasElements() override
Definition: shapeuno.cxx:1411
#define SC_UNONAME_URL
Definition: unonames.hxx:331
bool SvUnoImageMap_fillImageMap(const Reference< XInterface > &xImageMap, ImageMap &rMap)
static void lcl_CopyOneProperty(beans::XPropertySet &rDest, beans::XPropertySet &rSource, const char *pName)
Definition: shapeuno.cxx:1071
virtual void SAL_CALL release() override
Definition: shapeuno.cxx:146
static const SfxItemPropertyMapEntry * lcl_GetShapeMap()
Definition: shapeuno.cxx:49
ScAddress aEnd
Definition: address.hxx:501
css::uno::Reference< css::beans::XPropertySetInfo > mxPropSetInfo
Definition: shapeuno.hxx:70
SC_DLLPUBLIC ScRange GetRange(SCTAB nTab, const tools::Rectangle &rMMRect, bool bHiddenAsZero=true) const
Definition: documen3.cxx:1782
static uno::Reference< text::XTextRange > lcl_GetTextRange(const uno::Reference< uno::XAggregation > &xAgg)
Definition: shapeuno.cxx:203
virtual OUString SAL_CALL getImplementationName() override
Definition: shapeuno.cxx:1424
virtual uno::Type SAL_CALL getElementType() override
Definition: shapeuno.cxx:1406
ScAddress maStart
Definition: userdat.hxx:38
ScShapeObj(css::uno::Reference< css::drawing::XShape > &xShape)
Definition: shapeuno.cxx:82
css::beans::XPropertySet * pShapePropertySet
Definition: shapeuno.hxx:68
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: shapeuno.cxx:1429
Generic UNO wrapper for edit engine's field item in cells, headers, and footers.
Definition: fielduno.hxx:163
virtual uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: shapeuno.cxx:1372
#define SC_UNONAME_ANCHOR
Definition: unonames.hxx:194
PropertiesInfo aProperties
static ScRange lcl_GetAnchorCell(const uno::Reference< drawing::XShape > &xShape, const ScDocument *pDoc, SCTAB nTab, awt::Point &rUnoPoint, awt::Size &rUnoSize, awt::Point &rCaptionPoint)
Definition: shapeuno.cxx:262
SdrPage * getSdrPageFromSdrObject() const
static uno::Reference< text::XText > lcl_GetText(const uno::Reference< uno::XAggregation > &xAgg)
Definition: shapeuno.cxx:187
virtual void SAL_CALL dispose() override
Definition: shapeuno.cxx:1039
int nCount
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursorByRange(const css::uno::Reference< css::text::XTextRange > &aTextPosition) override
Definition: shapeuno.cxx:1143
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: shapeuno.cxx:867
void GetShapePropertyState()
Definition: shapeuno.cxx:165
SCTAB Tab() const
Definition: address.hxx:271
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: shapeuno.cxx:1400
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: shapeuno.cxx:1302
virtual void SAL_CALL replaceByName(const OUString &aName, const uno::Any &aElement) override
Definition: shapeuno.cxx:1339
bool mbResizeWithCell
Definition: userdat.hxx:43
Point BottomRight() const
ScDocument * GetDocument() const
Definition: drwlayer.hxx:122
virtual void SAL_CALL setParent(const css::uno::Reference< css::uno::XInterface > &xParent) override
Definition: shapeuno.cxx:1275
ScAnchorType
Definition: global.hxx:383
sal_uInt16 char * pName
Definition: callform.cxx:58
static void SetCellAnchored(SdrObject &, const ScDrawObjData &rAnchor)
Definition: drwlayer.cxx:2183
static awt::Point lcl_GetRelativePos(const uno::Reference< drawing::XShape > &xShape, const ScDocument *pDoc, SCTAB nTab, ScRange &rRange, awt::Size &rUnoSize, awt::Point &rCaptionPoint)
Definition: shapeuno.cxx:296
OptionalString sType
int i
ScMacroInfo * getInfo(bool bCreate)
Definition: shapeuno.cxx:1328
virtual void SAL_CALL insertControlCharacter(const css::uno::Reference< css::text::XTextRange > &xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb) override
Definition: shapeuno.cxx:1178
static ScAnchorType GetAnchorType(const SdrObject &)
Definition: drwlayer.cxx:2321
static ScDrawObjData * GetNoteCaptionData(SdrObject *pObj, SCTAB nTab)
Returns the object data, if the passed object is a cell note caption.
Definition: drwlayer.cxx:2510
virtual ~ScShapeObj() override
Definition: shapeuno.cxx:117
void SetHlink(const OUString &rHlink)
Definition: userdat.hxx:86
virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString &PropertyName) override
Definition: shapeuno.cxx:899
const SdrPage * GetPage(sal_uInt16 nPgNum) const
void SetMacro(const OUString &rMacro)
Definition: userdat.hxx:83
#define SC_UNONAME_TARGET
Definition: unonames.hxx:330
float u
unsigned char sal_Bool
virtual void SAL_CALL insertString(const css::uno::Reference< css::text::XTextRange > &xRange, const OUString &aString, sal_Bool bAbsorb) override
Definition: shapeuno.cxx:1166
SdrModel & getSdrModelFromSdrObject() const
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: shapeuno.cxx:308
Point maStartOffset
Definition: userdat.hxx:40
inline::Point VCLPoint(const css::awt::Point &rAWTPoint)
css::uno::Type const & get()
SC_DLLPUBLIC tools::Rectangle GetMMRect(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: documen3.cxx:1972
virtual css::uno::Reference< css::text::XText > SAL_CALL getText() override
Definition: shapeuno.cxx:1193
virtual void SAL_CALL setString(const OUString &aString) override
Definition: shapeuno.cxx:1231
SCCOL Col() const
Definition: address.hxx:267
virtual void SAL_CALL attach(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: shapeuno.cxx:995
void AppendUserData(std::unique_ptr< SdrObjUserData > pData)
friend ScMacroInfo * ScShapeObj_getShapeHyperMacroInfo(const ScShapeObj *pShape, bool bCreate)
Definition: shapeuno.cxx:74
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
Definition: shapeuno.cxx:1048
ShapeUnoEventAccessImpl(ScShapeObj *pShape)
Definition: shapeuno.cxx:1334
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: shapeuno.cxx:660
css::uno::Reference< css::uno::XAggregation > mxShapeAgg
Definition: shapeuno.hxx:66
#define SC_EVENTACC_EVENTTYPE
Definition: shapeuno.cxx:1321
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: shapeuno.cxx:1282
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: shapeuno.cxx:125
virtual void SAL_CALL removeTextContent(const css::uno::Reference< css::text::XTextContent > &xContent) override
Definition: shapeuno.cxx:1113
virtual css::uno::Any SAL_CALL getPropertyDefault(const OUString &aPropertyName) override
Definition: shapeuno.cxx:972
#define SC_UNONAME_VERTPOS
Definition: unonames.hxx:197
static ScDrawObjData * GetObjDataTab(SdrObject *pObj, SCTAB nTab)
Definition: drwlayer.cxx:2491
virtual OUString SAL_CALL getString() override
Definition: shapeuno.cxx:1220
#define SC_UNONAME_HYPERLINK
Definition: unonames.hxx:198
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: shapeuno.cxx:857
virtual void SAL_CALL setPropertyToDefault(const OUString &PropertyName) override
Definition: shapeuno.cxx:943
really derive cell from range?
Definition: cellsuno.hxx:628
static void UpdateCellAnchorFromPositionEnd(const SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect=true)
Definition: drwlayer.cxx:2280
SdrObject * GetSdrObject() const
SdrObject * GetSdrObject() const
Definition: shapeuno.cxx:1307
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getAnchor() override
Definition: shapeuno.cxx:1002
Sequence< sal_Int8 > aSeq
virtual void SAL_CALL insertTextContent(const css::uno::Reference< css::text::XTextRange > &xRange, const css::uno::Reference< css::text::XTextContent > &xContent, sal_Bool bAbsorb) override
Definition: shapeuno.cxx:1084
const ImageMap & GetImageMap() const
bool bIsNoteCaption
Definition: shapeuno.hxx:72
static bool IsNoteCaption(SdrObject *pObj)
Returns true, if the passed object is the caption of a cell note.
Definition: drwlayer.cxx:2504
Reference< XInterface > SvUnoImageMap_createInstance()
#define SC_EVENTACC_ONCLICK
Definition: shapeuno.cxx:1319
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1064
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
Definition: shapeuno.cxx:1058
void GetShapePropertySet()
Definition: shapeuno.cxx:151
void SetSelection(const ESelection &rSelection)
virtual void SAL_CALL acquire() override
Definition: shapeuno.cxx:141
static bool lcl_GetPageNum(const SdrPage *pPage, SdrModel &rModel, SCTAB &rNum)
Definition: shapeuno.cxx:232
virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents() override
Definition: shapeuno.cxx:1419
bool bIsTextShape
Definition: shapeuno.hxx:71
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getStart() override
Definition: shapeuno.cxx:1198
static const SvEventDescription * GetSupportedMacroItems()
Definition: shapeuno.cxx:66
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursor() override
Definition: shapeuno.cxx:1127
#define SC_UNONAME_IMAGEMAP
Definition: unonames.hxx:193
Point TopRight() const
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
#define SC_UNONAME_MOVEPROTECT
Definition: unonames.hxx:199
sal_uInt16 GetPageCount() const
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:23
ScMacroInfo * ScShapeObj_getShapeHyperMacroInfo(const ScShapeObj *pShape, bool bCreate=false)
Definition: shapeuno.cxx:74
static SvxIMapInfo * GetIMapInfo(const SdrObject *pObject)