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