1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27 #include <tools/debug.hxx>
28 #include <comphelper/uno3.hxx>
29 #include <comphelper/stl_types.hxx>
30 #include <svtools/unoevent.hxx>
31 #include <svtools/unoimap.hxx>
32 #include <svx/svdobj.hxx>
33 #include <svx/unoshape.hxx>
34 #include <editeng/unofield.hxx>
35 #include <svx/shapepropertynotifier.hxx>
36 #include <toolkit/helper/convert.hxx>
37 #include <cppuhelper/implbase2.hxx>
38
39 #include <com/sun/star/drawing/XShape.hpp>
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41
42 #include "shapeuno.hxx"
43 #include "miscuno.hxx"
44 #include "cellsuno.hxx"
45 #include "textuno.hxx"
46 #include "fielduno.hxx"
47 #include "docsh.hxx"
48 #include "drwlayer.hxx"
49 #include "userdat.hxx"
50 #include "unonames.hxx"
51 #include "unoguard.hxx"
52
53 using namespace ::com::sun::star;
54
55 //------------------------------------------------------------------------
56
57 DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence< sal_Int8 > *, ScShapeImplementationIdMap );
58
59 static ScShapeImplementationIdMap aImplementationIdMap;
60
lcl_GetShapeMap()61 const SfxItemPropertyMapEntry* lcl_GetShapeMap()
62 {
63 static SfxItemPropertyMapEntry aShapeMap_Impl[] =
64 {
65 {MAP_CHAR_LEN(SC_UNONAME_ANCHOR), 0, &getCppuType((uno::Reference<uno::XInterface>*)0), 0, 0 },
66 {MAP_CHAR_LEN(SC_UNONAME_HORIPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
67 {MAP_CHAR_LEN(SC_UNONAME_IMAGEMAP), 0, &getCppuType((uno::Reference<container::XIndexContainer>*)0), 0, 0 },
68 {MAP_CHAR_LEN(SC_UNONAME_VERTPOS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
69 {0,0,0,0,0,0}
70 };
71 return aShapeMap_Impl;
72 }
73
74 // static
GetSupportedMacroItems()75 const SvEventDescription* ScShapeObj::GetSupportedMacroItems()
76 {
77 static const SvEventDescription aMacroDescriptionsImpl[] =
78 {
79 { 0, NULL }
80 };
81 return aMacroDescriptionsImpl;
82 }
83
84 //------------------------------------------------------------------------
85
86 namespace
87 {
lcl_initializeNotifier(SdrObject & _rSdrObj,::cppu::OWeakObject & _rShape)88 void lcl_initializeNotifier( SdrObject& _rSdrObj, ::cppu::OWeakObject& _rShape )
89 {
90 ::svx::PPropertyValueProvider pProvider( new ::svx::PropertyValueProvider( _rShape, "Anchor" ) );
91 _rSdrObj.getShapePropertyChangeNotifier().registerProvider( ::svx::eSpreadsheetAnchor, pProvider );
92 }
93 }
94
95 //------------------------------------------------------------------------
96
ScShapeObj(uno::Reference<drawing::XShape> & xShape)97 ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) :
98 pShapePropertySet(NULL),
99 pShapePropertyState(NULL),
100 pImplementationId(NULL),
101 bIsTextShape(false),
102 bIsNoteCaption(false),
103 bInitializedNotifier(false)
104 {
105 comphelper::increment( m_refCount );
106
107 {
108 mxShapeAgg = uno::Reference<uno::XAggregation>( xShape, uno::UNO_QUERY );
109 // extra block to force deletion of the temporary before setDelegator
110 }
111
112 if (mxShapeAgg.is())
113 {
114 xShape = NULL; // during setDelegator, mxShapeAgg must be the only ref
115
116 mxShapeAgg->setDelegator( (cppu::OWeakObject*)this );
117
118 xShape.set(uno::Reference<drawing::XShape>( mxShapeAgg, uno::UNO_QUERY ));
119
120 bIsTextShape = ( SvxUnoTextBase::getImplementation( mxShapeAgg ) != NULL );
121 }
122
123 {
124 SdrObject* pObj = GetSdrObject();
125 if ( pObj )
126 {
127 bIsNoteCaption = ScDrawLayer::IsNoteCaption( pObj );
128 lcl_initializeNotifier( *pObj, *this );
129 bInitializedNotifier = true;
130 }
131 }
132
133 comphelper::decrement( m_refCount );
134 }
135
~ScShapeObj()136 ScShapeObj::~ScShapeObj()
137 {
138 // if (mxShapeAgg.is())
139 // mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>());
140 }
141
142 // XInterface
143
queryInterface(const uno::Type & rType)144 uno::Any SAL_CALL ScShapeObj::queryInterface( const uno::Type& rType )
145 {
146 uno::Any aRet = ScShapeObj_Base::queryInterface( rType );
147
148 if ( !aRet.hasValue() && bIsTextShape )
149 aRet = ScShapeObj_TextBase::queryInterface( rType );
150
151 if ( !aRet.hasValue() && bIsNoteCaption )
152 aRet = ScShapeObj_ChildBase::queryInterface( rType );
153
154 if ( !aRet.hasValue() && mxShapeAgg.is() )
155 aRet = mxShapeAgg->queryAggregation( rType );
156
157 return aRet;
158 }
159
acquire()160 void SAL_CALL ScShapeObj::acquire() throw()
161 {
162 OWeakObject::acquire();
163 }
164
release()165 void SAL_CALL ScShapeObj::release() throw()
166 {
167 OWeakObject::release();
168 }
169
GetShapePropertySet()170 void ScShapeObj::GetShapePropertySet()
171 {
172 // #i61908# Store the result of queryAggregation in a member.
173 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
174
175 if (!pShapePropertySet)
176 {
177 uno::Reference<beans::XPropertySet> xProp;
178 if ( mxShapeAgg.is() )
179 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertySet>*) 0) ) >>= xProp;
180 pShapePropertySet = xProp.get();
181 }
182 }
183
GetShapePropertyState()184 void ScShapeObj::GetShapePropertyState()
185 {
186 // #i61908# Store the result of queryAggregation in a member.
187 // The reference in mxShapeAgg is kept for this object's lifetime, so the pointer is always valid.
188
189 if (!pShapePropertyState)
190 {
191 uno::Reference<beans::XPropertyState> xState;
192 if ( mxShapeAgg.is() )
193 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<beans::XPropertyState>*) 0) ) >>= xState;
194 pShapePropertyState = xState.get();
195 }
196 }
197
lcl_GetComponent(const uno::Reference<uno::XAggregation> & xAgg)198 uno::Reference<lang::XComponent> lcl_GetComponent( const uno::Reference<uno::XAggregation>& xAgg )
199 {
200 uno::Reference<lang::XComponent> xRet;
201 if ( xAgg.is() )
202 xAgg->queryAggregation( getCppuType((uno::Reference<lang::XComponent>*) 0) ) >>= xRet;
203 return xRet;
204 }
205
lcl_GetText(const uno::Reference<uno::XAggregation> & xAgg)206 uno::Reference<text::XText> lcl_GetText( const uno::Reference<uno::XAggregation>& xAgg )
207 {
208 uno::Reference<text::XText> xRet;
209 if ( xAgg.is() )
210 xAgg->queryAggregation( getCppuType((uno::Reference<text::XText>*) 0) ) >>= xRet;
211 return xRet;
212 }
213
lcl_GetSimpleText(const uno::Reference<uno::XAggregation> & xAgg)214 uno::Reference<text::XSimpleText> lcl_GetSimpleText( const uno::Reference<uno::XAggregation>& xAgg )
215 {
216 uno::Reference<text::XSimpleText> xRet;
217 if ( xAgg.is() )
218 xAgg->queryAggregation( getCppuType((uno::Reference<text::XSimpleText>*) 0) ) >>= xRet;
219 return xRet;
220 }
221
lcl_GetTextRange(const uno::Reference<uno::XAggregation> & xAgg)222 uno::Reference<text::XTextRange> lcl_GetTextRange( const uno::Reference<uno::XAggregation>& xAgg )
223 {
224 uno::Reference<text::XTextRange> xRet;
225 if ( xAgg.is() )
226 xAgg->queryAggregation( getCppuType((uno::Reference<text::XTextRange>*) 0) ) >>= xRet;
227 return xRet;
228 }
229
230 // XPropertySet
231
getPropertySetInfo()232 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScShapeObj::getPropertySetInfo()
233 {
234 ScUnoGuard aGuard;
235
236 // #i61527# cache property set info for this object
237 if ( !mxPropSetInfo.is() )
238 {
239 // mix own and aggregated properties:
240 GetShapePropertySet();
241 if (pShapePropertySet)
242 {
243 uno::Reference<beans::XPropertySetInfo> xAggInfo(pShapePropertySet->getPropertySetInfo());
244 const uno::Sequence<beans::Property> aPropSeq(xAggInfo->getProperties());
245 mxPropSetInfo.set(new SfxExtItemPropertySetInfo( lcl_GetShapeMap(), aPropSeq ));
246 }
247 }
248 return mxPropSetInfo;
249 }
250
lcl_GetPageNum(SdrPage * pPage,SdrModel & rModel,SCTAB & rNum)251 sal_Bool lcl_GetPageNum( SdrPage* pPage, SdrModel& rModel, SCTAB& rNum )
252 {
253 sal_uInt16 nCount = rModel.GetPageCount();
254 for (sal_uInt16 i=0; i<nCount; i++)
255 if ( rModel.GetPage(i) == pPage )
256 {
257 rNum = static_cast<SCTAB>(i);
258 return sal_True;
259 }
260
261 return sal_False;
262 }
263
lcl_GetCaptionPoint(uno::Reference<drawing::XShape> & xShape,awt::Point & rCaptionPoint)264 sal_Bool lcl_GetCaptionPoint( uno::Reference< drawing::XShape >& xShape, awt::Point& rCaptionPoint )
265 {
266 sal_Bool bReturn = sal_False;
267 rtl::OUString sType(xShape->getShapeType());
268 sal_Bool bCaptionShape(sType.equalsAscii("com.sun.star.drawing.CaptionShape"));
269 if (bCaptionShape)
270 {
271 uno::Reference < beans::XPropertySet > xShapeProp (xShape, uno::UNO_QUERY);
272 if (xShapeProp.is())
273 {
274 xShapeProp->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )) ) >>= rCaptionPoint;
275 bReturn = sal_True;
276 }
277 }
278 return bReturn;
279 }
280
lcl_GetAnchorCell(uno::Reference<drawing::XShape> & xShape,ScDocument * pDoc,SCTAB nTab,awt::Point & rUnoPoint,awt::Size & rUnoSize,awt::Point & rCaptionPoint)281 ScRange lcl_GetAnchorCell( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab,
282 awt::Point& rUnoPoint, awt::Size& rUnoSize, awt::Point& rCaptionPoint )
283 {
284 ScRange aReturn;
285 rUnoPoint = xShape->getPosition();
286 rtl::OUString sType(xShape->getShapeType());
287 sal_Bool bCaptionShape(lcl_GetCaptionPoint(xShape, rCaptionPoint));
288 if (pDoc->IsNegativePage(nTab))
289 {
290 rUnoSize = xShape->getSize();
291 rUnoPoint.X += rUnoSize.Width; // the right top point is base
292 if (bCaptionShape)
293 {
294 if (rCaptionPoint.X > 0 && rCaptionPoint.X > rUnoSize.Width)
295 rUnoPoint.X += rCaptionPoint.X - rUnoSize.Width;
296 if (rCaptionPoint.Y < 0)
297 rUnoPoint.Y += rCaptionPoint.Y;
298 }
299 aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
300 }
301 else
302 {
303 if (bCaptionShape)
304 {
305 if (rCaptionPoint.X < 0)
306 rUnoPoint.X += rCaptionPoint.X;
307 if (rCaptionPoint.Y < 0)
308 rUnoPoint.Y += rCaptionPoint.Y;
309 }
310 aReturn = pDoc->GetRange( nTab, Rectangle( VCLPoint(rUnoPoint), VCLPoint(rUnoPoint) ));
311 }
312
313 return aReturn;
314 }
315
lcl_GetRelativePos(uno::Reference<drawing::XShape> & xShape,ScDocument * pDoc,SCTAB nTab,ScRange & rRange,awt::Size & rUnoSize,awt::Point & rCaptionPoint)316 awt::Point lcl_GetRelativePos( uno::Reference< drawing::XShape >& xShape, ScDocument* pDoc, SCTAB nTab, ScRange& rRange,
317 awt::Size& rUnoSize, awt::Point& rCaptionPoint)
318 {
319 awt::Point aUnoPoint;
320 rRange = lcl_GetAnchorCell(xShape, pDoc, nTab, aUnoPoint, rUnoSize, rCaptionPoint);
321 if (pDoc->IsNegativePage(nTab))
322 {
323 Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
324 Point aPoint(aRect.TopRight());
325 aUnoPoint.X -= aPoint.X();
326 aUnoPoint.Y -= aPoint.Y();
327 }
328 else
329 {
330 ScRange aRange = pDoc->GetRange( nTab, Rectangle( VCLPoint(aUnoPoint), VCLPoint(aUnoPoint) ));
331 Rectangle aRect(pDoc->GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ));
332 Point aPoint(aRect.TopLeft());
333 aUnoPoint.X -= aPoint.X();
334 aUnoPoint.Y -= aPoint.Y();
335 }
336
337 return aUnoPoint;
338 }
339
setPropertyValue(const rtl::OUString & aPropertyName,const uno::Any & aValue)340 void SAL_CALL ScShapeObj::setPropertyValue(
341 const rtl::OUString& aPropertyName, const uno::Any& aValue )
342 {
343 ScUnoGuard aGuard;
344 String aNameString(aPropertyName);
345
346 if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
347 {
348 uno::Reference<sheet::XCellRangeAddressable> xRangeAdd(aValue, uno::UNO_QUERY);
349 if (xRangeAdd.is())
350 {
351 SdrObject *pObj = GetSdrObject();
352 if (pObj)
353 {
354 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
355 SdrPage* pPage = pObj->GetPage();
356 if ( pModel && pPage )
357 {
358 ScDocument* pDoc = pModel->GetDocument();
359 if ( pDoc )
360 {
361 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
362 if ( pObjSh && pObjSh->ISA(ScDocShell) )
363 {
364 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
365
366 SCTAB nTab = 0;
367 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
368 {
369 table::CellRangeAddress aAddress = xRangeAdd->getRangeAddress();
370 if (nTab == aAddress.Sheet)
371 {
372 if (aAddress.StartRow != aAddress.EndRow) //should be a Spreadsheet
373 {
374 DBG_ASSERT(aAddress.StartRow == 0 && aAddress.EndRow == MAXROW &&
375 aAddress.StartColumn == 0 && aAddress.EndColumn == MAXCOL, "here should be a XSpreadsheet");
376 ScDrawLayer::SetAnchor(pObj, SCA_PAGE);
377 }
378 else
379 {
380 DBG_ASSERT(aAddress.StartRow == aAddress.EndRow &&
381 aAddress.StartColumn == aAddress.EndColumn, "here should be a XCell");
382 ScDrawLayer::SetAnchor(pObj, SCA_CELL);
383 }
384 Rectangle aRect(pDoc->GetMMRect( static_cast<SCCOL>(aAddress.StartColumn), static_cast<SCROW>(aAddress.StartRow),
385 static_cast<SCCOL>(aAddress.EndColumn), static_cast<SCROW>(aAddress.EndRow), aAddress.Sheet ));
386 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
387 if (xShape.is())
388 {
389 Point aPoint;
390 Point aEndPoint;
391 if (pDoc->IsNegativePage(nTab))
392 {
393 aPoint = aRect.TopRight();
394 aEndPoint = aRect.BottomLeft();
395 }
396 else
397 {
398 aPoint = aRect.TopLeft();
399 aEndPoint = aRect.BottomRight();
400 }
401 awt::Size aUnoSize;
402 awt::Point aCaptionPoint;
403 ScRange aRange;
404 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
405
406 aUnoPoint.X += aPoint.X();
407 aUnoPoint.Y += aPoint.Y();
408
409 if ( aUnoPoint.Y > aEndPoint.Y() )
410 aUnoPoint.Y = aEndPoint.Y() - 2;
411 if (pDoc->IsNegativePage(nTab))
412 {
413 if ( aUnoPoint.X < aEndPoint.X() )
414 aUnoPoint.X = aEndPoint.X() + 2;
415 aUnoPoint.X -= aUnoSize.Width;
416 // remove difference to caption point
417 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
418 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
419 }
420 else
421 {
422 if ( aUnoPoint.X > aEndPoint.X() )
423 aUnoPoint.X = aEndPoint.X() - 2;
424 if (aCaptionPoint.X < 0)
425 aUnoPoint.X -= aCaptionPoint.X;
426 }
427 if (aCaptionPoint.Y < 0)
428 aUnoPoint.Y -= aCaptionPoint.Y;
429
430 xShape->setPosition(aUnoPoint);
431 pDocSh->SetModified();
432 }
433 }
434 }
435 }
436 }
437 }
438 }
439 }
440 else
441 throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("only XCell or XSpreadsheet objects allowed")), static_cast<cppu::OWeakObject*>(this), 0);
442 }
443 else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
444 {
445 SdrObject* pObj = GetSdrObject();
446 if ( pObj )
447 {
448 ImageMap aImageMap;
449 uno::Reference< uno::XInterface > xImageMapInt(aValue, uno::UNO_QUERY);
450
451 if( !xImageMapInt.is() || !SvUnoImageMap_fillImageMap( xImageMapInt, aImageMap ) )
452 throw lang::IllegalArgumentException();
453
454 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
455 if( pIMapInfo )
456 {
457 // replace existing image map
458 pIMapInfo->SetImageMap( aImageMap );
459 }
460 else
461 {
462 // insert new user data with image map
463 pObj->InsertUserData(new ScIMapInfo(aImageMap) );
464 }
465 }
466 }
467 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
468 {
469 sal_Int32 nPos = 0;
470 if (aValue >>= nPos)
471 {
472 SdrObject *pObj = GetSdrObject();
473 if (pObj)
474 {
475 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
476 SdrPage* pPage = pObj->GetPage();
477 if ( pModel && pPage )
478 {
479 SCTAB nTab = 0;
480 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
481 {
482 ScDocument* pDoc = pModel->GetDocument();
483 if ( pDoc )
484 {
485 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
486 if ( pObjSh && pObjSh->ISA(ScDocShell) )
487 {
488 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
489 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
490 if (xShape.is())
491 {
492 if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE)
493 {
494 awt::Point aPoint(xShape->getPosition());
495 awt::Size aSize(xShape->getSize());
496 awt::Point aCaptionPoint;
497 if (pDoc->IsNegativePage(nTab))
498 {
499 nPos *= -1;
500 nPos -= aSize.Width;
501 }
502 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
503 {
504 if (pDoc->IsNegativePage(nTab))
505 {
506 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aSize.Width)
507 nPos -= aCaptionPoint.X - aSize.Width;
508 }
509 else
510 {
511 if (aCaptionPoint.X < 0)
512 nPos -= aCaptionPoint.X;
513 }
514 }
515 aPoint.X = nPos;
516 xShape->setPosition(aPoint);
517 pDocSh->SetModified();
518 }
519 else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
520 {
521 awt::Size aUnoSize;
522 awt::Point aCaptionPoint;
523 ScRange aRange;
524 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
525 Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
526 if (pDoc->IsNegativePage(nTab))
527 {
528 aUnoPoint.X = -nPos;
529 Point aPoint(aRect.TopRight());
530 Point aEndPoint(aRect.BottomLeft());
531 aUnoPoint.X += aPoint.X();
532 if (aUnoPoint.X < aEndPoint.X())
533 aUnoPoint.X = aEndPoint.X() + 2;
534 aUnoPoint.X -= aUnoSize.Width;
535 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
536 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
537 }
538 else
539 {
540 aUnoPoint.X = nPos;
541 Point aPoint(aRect.TopLeft());
542 Point aEndPoint(aRect.BottomRight());
543 aUnoPoint.X += aPoint.X();
544 if (aUnoPoint.X > aEndPoint.X())
545 aUnoPoint.X = aEndPoint.X() - 2;
546 if (aCaptionPoint.X < 0)
547 aUnoPoint.X -= aCaptionPoint.X;
548 }
549 aUnoPoint.Y = xShape->getPosition().Y;
550 xShape->setPosition(aUnoPoint);
551 pDocSh->SetModified();
552 }
553 else
554 {
555 DBG_ERROR("unknown anchor type");
556 }
557 }
558 }
559 }
560 }
561 }
562 }
563 }
564 }
565 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
566 {
567 sal_Int32 nPos = 0;
568 if (aValue >>= nPos)
569 {
570 SdrObject *pObj = GetSdrObject();
571 if (pObj)
572 {
573 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
574 SdrPage* pPage = pObj->GetPage();
575 if ( pModel && pPage )
576 {
577 SCTAB nTab = 0;
578 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
579 {
580 ScDocument* pDoc = pModel->GetDocument();
581 if ( pDoc )
582 {
583 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
584 if ( pObjSh && pObjSh->ISA(ScDocShell) )
585 {
586 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
587 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
588 if (xShape.is())
589 {
590 if (ScDrawLayer::GetAnchor(pObj) == SCA_PAGE)
591 {
592 awt::Point aPoint = xShape->getPosition();
593 awt::Point aCaptionPoint;
594 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
595 {
596 if (aCaptionPoint.Y < 0)
597 nPos -= aCaptionPoint.Y;
598 }
599 aPoint.Y = nPos;
600 xShape->setPosition(aPoint);
601 pDocSh->SetModified();
602 }
603 else if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
604 {
605 awt::Size aUnoSize;
606 awt::Point aCaptionPoint;
607 ScRange aRange;
608 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
609 Rectangle aRect(pDoc->GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
610 Point aPoint(aRect.TopRight());
611 Point aEndPoint(aRect.BottomLeft());
612 aUnoPoint.Y = nPos;
613 aUnoPoint.Y += aPoint.Y();
614 if (aUnoPoint.Y > aEndPoint.Y())
615 aUnoPoint.Y = aEndPoint.Y() - 2;
616 if (aCaptionPoint.Y < 0)
617 aUnoPoint.Y -= aCaptionPoint.Y;
618 aUnoPoint.X = xShape->getPosition().X;
619 xShape->setPosition(aUnoPoint);
620 pDocSh->SetModified();
621 }
622 else
623 {
624 DBG_ERROR("unknown anchor type");
625 }
626 }
627 }
628 }
629 }
630 }
631 }
632 }
633 }
634 else
635 {
636 GetShapePropertySet();
637 if (pShapePropertySet)
638 pShapePropertySet->setPropertyValue( aPropertyName, aValue );
639 }
640 }
641
getPropertyValue(const rtl::OUString & aPropertyName)642 uno::Any SAL_CALL ScShapeObj::getPropertyValue( const rtl::OUString& aPropertyName )
643 {
644 ScUnoGuard aGuard;
645 String aNameString = aPropertyName;
646
647 uno::Any aAny;
648 if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
649 {
650 SdrObject *pObj = GetSdrObject();
651 if (pObj)
652 {
653 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
654 SdrPage* pPage = pObj->GetPage();
655 if ( pModel && pPage )
656 {
657 ScDocument* pDoc = pModel->GetDocument();
658 if ( pDoc )
659 {
660 SCTAB nTab = 0;
661 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
662 {
663 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
664 if ( pObjSh && pObjSh->ISA(ScDocShell) )
665 {
666 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
667 uno::Reference< uno::XInterface > xAnchor;
668 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
669 {
670 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
671 if (xShape.is())
672 {
673 awt::Size aUnoSize;
674 awt::Point aCaptionPoint;
675 ScRange aRange;
676 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
677
678 xAnchor.set(static_cast<cppu::OWeakObject*>(new ScCellObj( pDocSh, aRange.aStart )));
679 }
680 }
681 else
682 {
683 xAnchor.set(static_cast<cppu::OWeakObject*>(new ScTableSheetObj( pDocSh, nTab )));
684 }
685 aAny <<= xAnchor;
686 }
687 }
688 }
689 }
690 }
691 }
692 else if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
693 {
694 uno::Reference< uno::XInterface > xImageMap;
695 SdrObject* pObj = GetSdrObject();
696 if ( pObj )
697 {
698 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(GetSdrObject());
699 if( pIMapInfo )
700 {
701 const ImageMap& rIMap = pIMapInfo->GetImageMap();
702 xImageMap.set(SvUnoImageMap_createInstance( rIMap, GetSupportedMacroItems() ));
703 }
704 else
705 xImageMap = SvUnoImageMap_createInstance( GetSupportedMacroItems() );
706 }
707 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
708 }
709 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
710 {
711 SdrObject *pObj = GetSdrObject();
712 if (pObj)
713 {
714 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
715 SdrPage* pPage = pObj->GetPage();
716 if ( pModel && pPage )
717 {
718 ScDocument* pDoc = pModel->GetDocument();
719 if ( pDoc )
720 {
721 SCTAB nTab = 0;
722 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
723 {
724 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
725 if (xShape.is())
726 {
727 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
728 {
729 awt::Size aUnoSize;
730 awt::Point aCaptionPoint;
731 ScRange aRange;
732 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
733 if (pDoc->IsNegativePage(nTab))
734 aUnoPoint.X *= -1;
735 aAny <<= aUnoPoint.X;
736 }
737 else
738 {
739 awt::Point aCaptionPoint;
740 awt::Point aUnoPoint(xShape->getPosition());
741 awt::Size aUnoSize(xShape->getSize());
742 if (pDoc->IsNegativePage(nTab))
743 {
744 aUnoPoint.X *= -1;
745 aUnoPoint.X -= aUnoSize.Width;
746 }
747 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
748 {
749 if (pDoc->IsNegativePage(nTab))
750 {
751 if (aCaptionPoint.X > 0 && aCaptionPoint.X > aUnoSize.Width)
752 aUnoPoint.X -= aCaptionPoint.X - aUnoSize.Width;
753 }
754 else
755 {
756 if (aCaptionPoint.X < 0)
757 aUnoPoint.X += aCaptionPoint.X;
758 }
759 }
760 aAny <<= aUnoPoint.X;
761 }
762 }
763 }
764 }
765 }
766 }
767 }
768 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
769 {
770 SdrObject *pObj = GetSdrObject();
771 if (pObj)
772 {
773 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
774 SdrPage* pPage = pObj->GetPage();
775 if ( pModel && pPage )
776 {
777 ScDocument* pDoc = pModel->GetDocument();
778 if ( pDoc )
779 {
780 SCTAB nTab = 0;
781 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
782 {
783 uno::Reference<drawing::XShape> xShape( mxShapeAgg, uno::UNO_QUERY );
784 if (xShape.is())
785 {
786 uno::Reference< uno::XInterface > xAnchor;
787 if (ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
788 {
789 awt::Size aUnoSize;
790 awt::Point aCaptionPoint;
791 ScRange aRange;
792 awt::Point aUnoPoint(lcl_GetRelativePos( xShape, pDoc, nTab, aRange, aUnoSize, aCaptionPoint ));
793
794 aAny <<= aUnoPoint.Y;
795 }
796 else
797 {
798 awt::Point aUnoPoint(xShape->getPosition());
799 awt::Point aCaptionPoint;
800 if (lcl_GetCaptionPoint(xShape, aCaptionPoint))
801 {
802 if (aCaptionPoint.Y < 0)
803 aUnoPoint.Y += aCaptionPoint.Y;
804 }
805 aAny <<= aUnoPoint.Y;
806 }
807 }
808 }
809 }
810 }
811 }
812 }
813 else
814 {
815 if(!pShapePropertySet) GetShapePropertySet(); //performance consideration
816 if (pShapePropertySet)
817 aAny = pShapePropertySet->getPropertyValue( aPropertyName );
818 }
819
820 return aAny;
821 }
822
addPropertyChangeListener(const rtl::OUString & aPropertyName,const uno::Reference<beans::XPropertyChangeListener> & aListener)823 void SAL_CALL ScShapeObj::addPropertyChangeListener( const rtl::OUString& aPropertyName,
824 const uno::Reference<beans::XPropertyChangeListener>& aListener)
825 {
826 ScUnoGuard aGuard;
827
828 GetShapePropertySet();
829 if (pShapePropertySet)
830 pShapePropertySet->addPropertyChangeListener( aPropertyName, aListener );
831
832 if ( !bInitializedNotifier )
833 {
834 // here's the latest chance to initialize the property notification at the SdrObject
835 // (in the ctor, where we also attempt to do this, we do not necessarily have
836 // and SdrObject, yet)
837 SdrObject* pObj = GetSdrObject();
838 OSL_ENSURE( pObj, "ScShapeObj::addPropertyChangeListener: no SdrObject -> no property change notification!" );
839 if ( pObj )
840 lcl_initializeNotifier( *pObj, *this );
841 bInitializedNotifier = true;
842 }
843 }
844
removePropertyChangeListener(const rtl::OUString & aPropertyName,const uno::Reference<beans::XPropertyChangeListener> & aListener)845 void SAL_CALL ScShapeObj::removePropertyChangeListener( const rtl::OUString& aPropertyName,
846 const uno::Reference<beans::XPropertyChangeListener>& aListener)
847 {
848 ScUnoGuard aGuard;
849
850 GetShapePropertySet();
851 if (pShapePropertySet)
852 pShapePropertySet->removePropertyChangeListener( aPropertyName, aListener );
853 }
854
addVetoableChangeListener(const rtl::OUString & aPropertyName,const uno::Reference<beans::XVetoableChangeListener> & aListener)855 void SAL_CALL ScShapeObj::addVetoableChangeListener( const rtl::OUString& aPropertyName,
856 const uno::Reference<beans::XVetoableChangeListener>& aListener)
857 {
858 ScUnoGuard aGuard;
859
860 GetShapePropertySet();
861 if (pShapePropertySet)
862 pShapePropertySet->addVetoableChangeListener( aPropertyName, aListener );
863 }
864
removeVetoableChangeListener(const rtl::OUString & aPropertyName,const uno::Reference<beans::XVetoableChangeListener> & aListener)865 void SAL_CALL ScShapeObj::removeVetoableChangeListener( const rtl::OUString& aPropertyName,
866 const uno::Reference<beans::XVetoableChangeListener>& aListener)
867 {
868 ScUnoGuard aGuard;
869
870 GetShapePropertySet();
871 if (pShapePropertySet)
872 pShapePropertySet->removeVetoableChangeListener( aPropertyName, aListener );
873 }
874
875 // XPropertyState
876
getPropertyState(const rtl::OUString & aPropertyName)877 beans::PropertyState SAL_CALL ScShapeObj::getPropertyState( const rtl::OUString& aPropertyName )
878 {
879 ScUnoGuard aGuard;
880 String aNameString(aPropertyName);
881
882 beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
883 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
884 {
885 // ImageMap is always "direct"
886 }
887 else if ( aNameString.EqualsAscii( SC_UNONAME_ANCHOR ) )
888 {
889 // Anchor is always "direct"
890 }
891 else if ( aNameString.EqualsAscii( SC_UNONAME_HORIPOS ) )
892 {
893 // HoriPos is always "direct"
894 }
895 else if ( aNameString.EqualsAscii( SC_UNONAME_VERTPOS ) )
896 {
897 // VertPos is always "direct"
898 }
899 else
900 {
901 GetShapePropertyState();
902 if (pShapePropertyState)
903 eRet = pShapePropertyState->getPropertyState( aPropertyName );
904 }
905
906 return eRet;
907 }
908
getPropertyStates(const uno::Sequence<rtl::OUString> & aPropertyNames)909 uno::Sequence<beans::PropertyState> SAL_CALL ScShapeObj::getPropertyStates(
910 const uno::Sequence<rtl::OUString>& aPropertyNames )
911 {
912 ScUnoGuard aGuard;
913
914 // simple loop to get own and aggregated states
915
916 const rtl::OUString* pNames = aPropertyNames.getConstArray();
917 uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
918 beans::PropertyState* pStates = aRet.getArray();
919 for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
920 pStates[i] = getPropertyState(pNames[i]);
921 return aRet;
922 }
923
setPropertyToDefault(const rtl::OUString & aPropertyName)924 void SAL_CALL ScShapeObj::setPropertyToDefault( const rtl::OUString& aPropertyName )
925 {
926 ScUnoGuard aGuard;
927 String aNameString(aPropertyName);
928
929 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
930 {
931 SdrObject* pObj = GetSdrObject();
932 if ( pObj )
933 {
934 ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo(pObj);
935 if( pIMapInfo )
936 {
937 ImageMap aEmpty;
938 pIMapInfo->SetImageMap( aEmpty ); // replace with empty image map
939 }
940 else
941 {
942 // nothing to do (no need to insert user data for an empty map)
943 }
944 }
945 }
946 else
947 {
948 GetShapePropertyState();
949 if (pShapePropertyState)
950 pShapePropertyState->setPropertyToDefault( aPropertyName );
951 }
952 }
953
getPropertyDefault(const rtl::OUString & aPropertyName)954 uno::Any SAL_CALL ScShapeObj::getPropertyDefault( const rtl::OUString& aPropertyName )
955 {
956 ScUnoGuard aGuard;
957 String aNameString = aPropertyName;
958
959 uno::Any aAny;
960 if ( aNameString.EqualsAscii( SC_UNONAME_IMAGEMAP ) )
961 {
962 // default: empty ImageMap
963 uno::Reference< uno::XInterface > xImageMap(SvUnoImageMap_createInstance( GetSupportedMacroItems() ));
964 aAny <<= uno::Reference< container::XIndexContainer >::query( xImageMap );
965 }
966 else
967 {
968 GetShapePropertyState();
969 if (pShapePropertyState)
970 aAny = pShapePropertyState->getPropertyDefault( aPropertyName );
971 }
972
973 return aAny;
974 }
975
976 // XTextContent
977
attach(const uno::Reference<text::XTextRange> &)978 void SAL_CALL ScShapeObj::attach( const uno::Reference<text::XTextRange>& /* xTextRange */ )
979 {
980 ScUnoGuard aGuard;
981
982 throw lang::IllegalArgumentException(); // anchor cannot be changed
983 }
984
getAnchor()985 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getAnchor()
986 {
987 ScUnoGuard aGuard;
988
989 uno::Reference<text::XTextRange> xRet;
990
991 SdrObject* pObj = GetSdrObject();
992 if( pObj )
993 {
994 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
995 SdrPage* pPage = pObj->GetPage();
996 if ( pModel )
997 {
998 ScDocument* pDoc = pModel->GetDocument();
999 if ( pDoc )
1000 {
1001 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1002 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1003 {
1004 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
1005
1006 SCTAB nTab = 0;
1007 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
1008 {
1009 Point aPos(pObj->GetCurrentBoundRect().TopLeft());
1010 ScRange aRange(pDoc->GetRange( nTab, Rectangle( aPos, aPos ) ));
1011
1012 // anchor is always the cell
1013
1014 xRet.set(new ScCellObj( pDocSh, aRange.aStart ));
1015 }
1016 }
1017 }
1018 }
1019 }
1020
1021 return xRet;
1022 }
1023
1024 // XComponent
1025
dispose()1026 void SAL_CALL ScShapeObj::dispose()
1027 {
1028 ScUnoGuard aGuard;
1029
1030 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1031 if ( xAggComp.is() )
1032 xAggComp->dispose();
1033 }
1034
addEventListener(const uno::Reference<lang::XEventListener> & xListener)1035 void SAL_CALL ScShapeObj::addEventListener(
1036 const uno::Reference<lang::XEventListener>& xListener )
1037 {
1038 ScUnoGuard aGuard;
1039
1040 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1041 if ( xAggComp.is() )
1042 xAggComp->addEventListener(xListener);
1043 }
1044
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)1045 void SAL_CALL ScShapeObj::removeEventListener(
1046 const uno::Reference<lang::XEventListener>& xListener )
1047 {
1048 ScUnoGuard aGuard;
1049
1050 uno::Reference<lang::XComponent> xAggComp(lcl_GetComponent(mxShapeAgg));
1051 if ( xAggComp.is() )
1052 xAggComp->removeEventListener(xListener);
1053 }
1054
1055 // XText
1056 // (special handling for ScCellFieldObj)
1057
lcl_CopyOneProperty(beans::XPropertySet & rDest,beans::XPropertySet & rSource,const sal_Char * pName)1058 void lcl_CopyOneProperty( beans::XPropertySet& rDest, beans::XPropertySet& rSource, const sal_Char* pName )
1059 {
1060 rtl::OUString aNameStr(rtl::OUString::createFromAscii(pName));
1061 try
1062 {
1063 rDest.setPropertyValue( aNameStr, rSource.getPropertyValue( aNameStr ) );
1064 }
1065 catch (uno::Exception&)
1066 {
1067 DBG_ERROR("Exception in text field");
1068 }
1069 }
1070
insertTextContent(const uno::Reference<text::XTextRange> & xRange,const uno::Reference<text::XTextContent> & xContent,sal_Bool bAbsorb)1071 void SAL_CALL ScShapeObj::insertTextContent( const uno::Reference<text::XTextRange>& xRange,
1072 const uno::Reference<text::XTextContent>& xContent,
1073 sal_Bool bAbsorb )
1074 {
1075 ScUnoGuard aGuard;
1076
1077 uno::Reference<text::XTextContent> xEffContent;
1078
1079 ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent );
1080 if ( pCellField )
1081 {
1082 // #105585# createInstance("TextField.URL") from the document creates a ScCellFieldObj.
1083 // To insert it into drawing text, a SvxUnoTextField is needed instead.
1084 // The ScCellFieldObj object is left in non-inserted state.
1085
1086 SvxUnoTextField* pDrawField = new SvxUnoTextField( ID_URLFIELD );
1087 xEffContent.set(pDrawField);
1088 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_URL );
1089 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_REPR );
1090 lcl_CopyOneProperty( *pDrawField, *pCellField, SC_UNONAME_TARGET );
1091 }
1092 else
1093 xEffContent.set(xContent);
1094
1095 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1096 if ( xAggText.is() )
1097 xAggText->insertTextContent( xRange, xEffContent, bAbsorb );
1098 }
1099
removeTextContent(const uno::Reference<text::XTextContent> & xContent)1100 void SAL_CALL ScShapeObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
1101 {
1102 ScUnoGuard aGuard;
1103
1104 // ScCellFieldObj can't be used here.
1105
1106 uno::Reference<text::XText> xAggText(lcl_GetText(mxShapeAgg));
1107 if ( xAggText.is() )
1108 xAggText->removeTextContent( xContent );
1109 }
1110
1111 // XSimpleText (parent of XText)
1112 // Use own SvxUnoTextCursor subclass - everything is just passed to aggregated object
1113
createTextCursor()1114 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursor()
1115 {
1116 ScUnoGuard aGuard;
1117
1118 if ( mxShapeAgg.is() )
1119 {
1120 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1121
1122 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
1123 if (pText)
1124 return new ScDrawTextCursor( this, *pText );
1125 }
1126
1127 return uno::Reference<text::XTextCursor>();
1128 }
1129
createTextCursorByRange(const uno::Reference<text::XTextRange> & aTextPosition)1130 uno::Reference<text::XTextCursor> SAL_CALL ScShapeObj::createTextCursorByRange(
1131 const uno::Reference<text::XTextRange>& aTextPosition )
1132 {
1133 ScUnoGuard aGuard;
1134
1135 if ( mxShapeAgg.is() && aTextPosition.is() )
1136 {
1137 // ScDrawTextCursor must be used to ensure the ScShapeObj is returned by getText
1138
1139 SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( mxShapeAgg );
1140 SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
1141 if ( pText && pRange )
1142 {
1143 SvxUnoTextCursor* pCursor = new ScDrawTextCursor( this, *pText );
1144 uno::Reference<text::XTextCursor> xCursor( pCursor );
1145 pCursor->SetSelection( pRange->GetSelection() );
1146 return xCursor;
1147 }
1148 }
1149
1150 return uno::Reference<text::XTextCursor>();
1151 }
1152
insertString(const uno::Reference<text::XTextRange> & xRange,const rtl::OUString & aString,sal_Bool bAbsorb)1153 void SAL_CALL ScShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange,
1154 const rtl::OUString& aString, sal_Bool bAbsorb )
1155 {
1156 ScUnoGuard aGuard;
1157
1158 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1159 if ( xAggSimpleText.is() )
1160 xAggSimpleText->insertString( xRange, aString, bAbsorb );
1161 else
1162 throw uno::RuntimeException();
1163 }
1164
insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,sal_Int16 nControlCharacter,sal_Bool bAbsorb)1165 void SAL_CALL ScShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
1166 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
1167 {
1168 ScUnoGuard aGuard;
1169
1170 uno::Reference<text::XSimpleText> xAggSimpleText(lcl_GetSimpleText(mxShapeAgg));
1171 if ( xAggSimpleText.is() )
1172 xAggSimpleText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
1173 else
1174 throw uno::RuntimeException();
1175 }
1176
1177 // XTextRange
1178 // (parent of XSimpleText)
1179
getText()1180 uno::Reference<text::XText> SAL_CALL ScShapeObj::getText()
1181 {
1182 ScUnoGuard aGuard;
1183 return this;
1184 }
1185
getStart()1186 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getStart()
1187 {
1188 ScUnoGuard aGuard;
1189
1190 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1191 if ( xAggTextRange.is() )
1192 return xAggTextRange->getStart();
1193 else
1194 throw uno::RuntimeException();
1195
1196 // return uno::Reference<text::XTextRange>();
1197 }
1198
getEnd()1199 uno::Reference<text::XTextRange> SAL_CALL ScShapeObj::getEnd()
1200 {
1201 ScUnoGuard aGuard;
1202
1203 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1204 if ( xAggTextRange.is() )
1205 return xAggTextRange->getEnd();
1206 else
1207 throw uno::RuntimeException();
1208
1209 // return uno::Reference<text::XTextRange>();
1210 }
1211
getString()1212 rtl::OUString SAL_CALL ScShapeObj::getString()
1213 {
1214 ScUnoGuard aGuard;
1215
1216 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1217 if ( xAggTextRange.is() )
1218 return xAggTextRange->getString();
1219 else
1220 throw uno::RuntimeException();
1221
1222 // return rtl::OUString();
1223 }
1224
setString(const rtl::OUString & aText)1225 void SAL_CALL ScShapeObj::setString( const rtl::OUString& aText )
1226 {
1227 ScUnoGuard aGuard;
1228
1229 uno::Reference<text::XTextRange> xAggTextRange(lcl_GetTextRange(mxShapeAgg));
1230 if ( xAggTextRange.is() )
1231 xAggTextRange->setString( aText );
1232 else
1233 throw uno::RuntimeException();
1234 }
1235
1236 // XChild
1237
getParent()1238 uno::Reference< uno::XInterface > SAL_CALL ScShapeObj::getParent()
1239 {
1240 ScUnoGuard aGuard;
1241
1242 // receive cell position from caption object (parent of a note caption is the note cell)
1243 SdrObject* pObj = GetSdrObject();
1244 if( pObj )
1245 {
1246 ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel();
1247 SdrPage* pPage = pObj->GetPage();
1248 if ( pModel )
1249 {
1250 ScDocument* pDoc = pModel->GetDocument();
1251 if ( pDoc )
1252 {
1253 SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
1254 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1255 {
1256 ScDocShell* pDocSh = (ScDocShell*)pObjSh;
1257
1258 SCTAB nTab = 0;
1259 if ( lcl_GetPageNum( pPage, *pModel, nTab ) )
1260 {
1261 const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab );
1262 if( pCaptData )
1263 return static_cast< ::cppu::OWeakObject* >( new ScCellObj( pDocSh, pCaptData->maStart ) );
1264 }
1265 }
1266 }
1267 }
1268 }
1269
1270 return 0;
1271 }
1272
setParent(const uno::Reference<uno::XInterface> &)1273 void SAL_CALL ScShapeObj::setParent( const uno::Reference< uno::XInterface >& )
1274 {
1275 throw lang::NoSupportException();
1276 }
1277
1278 // XTypeProvider
1279
getTypes()1280 uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes()
1281 {
1282 uno::Sequence< uno::Type > aBaseTypes( ScShapeObj_Base::getTypes() );
1283
1284 uno::Sequence< uno::Type > aTextTypes;
1285 if ( bIsTextShape )
1286 aTextTypes = ScShapeObj_TextBase::getTypes();
1287
1288 uno::Reference<lang::XTypeProvider> xBaseProvider;
1289 if ( mxShapeAgg.is() )
1290 mxShapeAgg->queryAggregation( getCppuType((uno::Reference<lang::XTypeProvider>*) 0) ) >>= xBaseProvider;
1291 DBG_ASSERT( xBaseProvider.is(), "ScShapeObj: No XTypeProvider from aggregated shape!" );
1292
1293 uno::Sequence< uno::Type > aAggTypes;
1294 if( xBaseProvider.is() )
1295 aAggTypes = xBaseProvider->getTypes();
1296
1297 return ::comphelper::concatSequences( aBaseTypes, aTextTypes, aAggTypes );
1298 }
1299
getImplementationId()1300 uno::Sequence<sal_Int8> SAL_CALL ScShapeObj::getImplementationId()
1301 {
1302 ScUnoGuard aGuard;
1303 // do we need to compute the implementation id for this instance?
1304 if( !pImplementationId && mxShapeAgg.is())
1305 {
1306 uno::Reference< drawing::XShape > xAggShape;
1307 mxShapeAgg->queryAggregation( ::getCppuType((uno::Reference< drawing::XShape >*)0) ) >>= xAggShape;
1308
1309 if( xAggShape.is() )
1310 {
1311 const rtl::OUString aShapeType( xAggShape->getShapeType() );
1312 // did we already compute an implementation id for the aggregated shape type?
1313 ScShapeImplementationIdMap::iterator aIter( aImplementationIdMap.find(aShapeType ) );
1314 if( aIter == aImplementationIdMap.end() )
1315 {
1316 // we need to create a new implementation id for this
1317 // note: this memory is not freed until application exists
1318 // but since we have a fixed set of shapetypes and the
1319 // memory will be reused this is ok.
1320 pImplementationId = new uno::Sequence< sal_Int8 >( 16 );
1321 rtl_createUuid( (sal_uInt8 *) pImplementationId->getArray(), 0, sal_True );
1322 aImplementationIdMap[ aShapeType ] = pImplementationId;
1323 }
1324 else
1325 {
1326 // use the already computed implementation id
1327 pImplementationId = (*aIter).second;
1328 }
1329 }
1330 }
1331 if( NULL == pImplementationId )
1332 {
1333 DBG_ERROR( "Could not create an implementation id for a ScXShape!" );
1334 return uno::Sequence< sal_Int8 > ();
1335 }
1336 else
1337 {
1338 return *pImplementationId;
1339 }
1340 }
1341
GetSdrObject() const1342 SdrObject* ScShapeObj::GetSdrObject() const throw()
1343 {
1344 if(mxShapeAgg.is())
1345 {
1346 SvxShape* pShape = SvxShape::getImplementation( mxShapeAgg );
1347 if(pShape)
1348 return pShape->GetSdrObject();
1349 }
1350
1351 return NULL;
1352 }
1353
1354 #define SC_EVENTACC_ONCLICK ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) )
1355 #ifdef ISSUE66550_HLINK_FOR_SHAPES
1356 #define SC_EVENTACC_ONACTION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAction" ) )
1357 #define SC_EVENTACC_URL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) )
1358 #define SC_EVENTACC_ACTION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Action" ) )
1359 #endif
1360 #define SC_EVENTACC_SCRIPT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Script" ) )
1361 #define SC_EVENTACC_EVENTTYPE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) )
1362
1363 typedef ::cppu::WeakImplHelper1< container::XNameReplace > ShapeUnoEventAcess_BASE;
1364 class ShapeUnoEventAccessImpl : public ShapeUnoEventAcess_BASE
1365 {
1366 private:
1367 ScShapeObj* mpShape;
1368
getInfo(sal_Bool bCreate=sal_False)1369 ScMacroInfo* getInfo( sal_Bool bCreate = sal_False )
1370 {
1371 if( mpShape )
1372 if( SdrObject* pObj = mpShape->GetSdrObject() )
1373 return ScDrawLayer::GetMacroInfo( pObj, bCreate );
1374 return 0;
1375 }
1376
1377 public:
ShapeUnoEventAccessImpl(ScShapeObj * pShape)1378 ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
1379 {
1380 }
1381
1382 // XNameReplace
replaceByName(const rtl::OUString & aName,const uno::Any & aElement)1383 virtual void SAL_CALL replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
1384 {
1385 if ( !hasByName( aName ) )
1386 throw container::NoSuchElementException();
1387 uno::Sequence< beans::PropertyValue > aProperties;
1388 aElement >>= aProperties;
1389 const beans::PropertyValue* pProperties = aProperties.getConstArray();
1390 const sal_Int32 nCount = aProperties.getLength();
1391 sal_Int32 nIndex;
1392 bool isEventType = false;
1393 for( nIndex = 0; nIndex < nCount; nIndex++, pProperties++ )
1394 {
1395 if ( pProperties->Name.equals( SC_EVENTACC_EVENTTYPE ) )
1396 {
1397 isEventType = true;
1398 continue;
1399 }
1400 #ifdef ISSUE66550_HLINK_FOR_SHAPES
1401 if ( isEventType && ((pProperties->Name == SC_EVENTACC_SCRIPT) || (pProperties->Name == SC_EVENTACC_URL)) )
1402 #else
1403 if ( isEventType && (pProperties->Name == SC_EVENTACC_SCRIPT) )
1404 #endif
1405 {
1406 rtl::OUString sValue;
1407 if ( pProperties->Value >>= sValue )
1408 {
1409 ScMacroInfo* pInfo = getInfo( sal_True );
1410 DBG_ASSERT( pInfo, "shape macro info could not be created!" );
1411 if ( !pInfo )
1412 break;
1413 if ( pProperties->Name == SC_EVENTACC_SCRIPT )
1414 pInfo->SetMacro( sValue );
1415 #ifdef ISSUE66550_HLINK_FOR_SHAPES
1416 else
1417 pInfo->SetHlink( sValue );
1418 #endif
1419 }
1420 }
1421 }
1422 }
1423
1424 // XNameAccess
getByName(const rtl::OUString & aName)1425 virtual uno::Any SAL_CALL getByName( const rtl::OUString& aName )
1426 {
1427 uno::Sequence< beans::PropertyValue > aProperties;
1428 ScMacroInfo* pInfo = getInfo();
1429
1430 if ( aName == SC_EVENTACC_ONCLICK )
1431 {
1432 if ( pInfo && (pInfo->GetMacro().getLength() > 0) )
1433 {
1434 aProperties.realloc( 2 );
1435 aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
1436 aProperties[ 0 ].Value <<= SC_EVENTACC_SCRIPT;
1437 aProperties[ 1 ].Name = SC_EVENTACC_SCRIPT;
1438 aProperties[ 1 ].Value <<= pInfo->GetMacro();
1439 }
1440 }
1441 #ifdef ISSUE66550_HLINK_FOR_SHAPES
1442 else if( aName == SC_EVENTACC_ONACTION )
1443 {
1444 if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
1445 {
1446 aProperties.realloc( 2 );
1447 aProperties[ 0 ].Name = SC_EVENTACC_EVENTTYPE;
1448 aProperties[ 0 ].Value <<= SC_EVENTACC_ACTION;
1449 aProperties[ 1 ].Name = SC_EVENTACC_URL;
1450 aProperties[ 1 ].Value <<= pInfo->GetHlink();
1451 }
1452 }
1453 #endif
1454 else
1455 {
1456 throw container::NoSuchElementException();
1457 }
1458
1459 return uno::Any( aProperties );
1460 }
1461
getElementNames()1462 virtual uno::Sequence< rtl::OUString > SAL_CALL getElementNames()
1463 {
1464 #ifdef ISSUE66550_HLINK_FOR_SHAPES
1465 uno::Sequence< rtl::OUString > aSeq( 2 );
1466 #else
1467 uno::Sequence< rtl::OUString > aSeq( 1 );
1468 #endif
1469 aSeq[ 0 ] = SC_EVENTACC_ONCLICK;
1470 #ifdef ISSUE66550_HLINK_FOR_SHAPES
1471 aSeq[ 1 ] = SC_EVENTACC_ONACTION;
1472 #endif
1473 return aSeq;
1474 }
1475
hasByName(const rtl::OUString & aName)1476 virtual sal_Bool SAL_CALL hasByName( const rtl::OUString& aName )
1477 {
1478 #ifdef ISSUE66550_HLINK_FOR_SHAPES
1479 return (aName == SC_EVENTACC_ONCLICK) || (aName == SC_EVENTACC_ONACTION);
1480 #else
1481 return aName == SC_EVENTACC_ONCLICK;
1482 #endif
1483 }
1484
1485 // XElementAccess
getElementType()1486 virtual uno::Type SAL_CALL getElementType()
1487 {
1488 return *SEQTYPE(::getCppuType((const uno::Sequence< beans::PropertyValue >*)0));
1489 }
1490
hasElements()1491 virtual sal_Bool SAL_CALL hasElements()
1492 {
1493 // elements are always present (but contained property sequences may be empty)
1494 return sal_True;
1495 }
1496 };
1497
1498 ::uno::Reference< container::XNameReplace > SAL_CALL
getEvents()1499 ScShapeObj::getEvents( )
1500 {
1501 return new ShapeUnoEventAccessImpl( this );
1502 }
1503
getImplementationName()1504 ::rtl::OUString SAL_CALL ScShapeObj::getImplementationName( )
1505 {
1506 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sc.ScShapeObj" ) );
1507 }
1508
supportsService(const::rtl::OUString & _ServiceName)1509 ::sal_Bool SAL_CALL ScShapeObj::supportsService( const ::rtl::OUString& _ServiceName )
1510 {
1511 uno::Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
1512 for ( const ::rtl::OUString* pSupported = aSupported.getConstArray();
1513 pSupported != aSupported.getConstArray() + aSupported.getLength();
1514 ++pSupported
1515 )
1516 if ( _ServiceName == *pSupported )
1517 return sal_True;
1518 return sal_False;
1519 }
1520
getSupportedServiceNames()1521 uno::Sequence< ::rtl::OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( )
1522 {
1523 uno::Reference<lang::XServiceInfo> xSI;
1524 if ( mxShapeAgg.is() )
1525 mxShapeAgg->queryAggregation( lang::XServiceInfo::static_type() ) >>= xSI;
1526
1527 uno::Sequence< ::rtl::OUString > aSupported;
1528 if ( xSI.is() )
1529 aSupported = xSI->getSupportedServiceNames();
1530
1531 aSupported.realloc( aSupported.getLength() + 1 );
1532 aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) );
1533
1534 if( bIsNoteCaption )
1535 {
1536 aSupported.realloc( aSupported.getLength() + 1 );
1537 aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.CellAnnotationShape" ) );
1538 }
1539
1540 return aSupported;
1541 }
1542