xref: /aoo41x/main/sc/source/ui/unoobj/shapeuno.cxx (revision b3f79822)
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 
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
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 {
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 
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 
136 ScShapeObj::~ScShapeObj()
137 {
138 //	if (mxShapeAgg.is())
139 //		mxShapeAgg->setDelegator(uno::Reference<uno::XInterface>());
140 }
141 
142 // XInterface
143 
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 
161 void SAL_CALL ScShapeObj::acquire() throw()
162 {
163         OWeakObject::acquire();
164 }
165 
166 void SAL_CALL ScShapeObj::release() throw()
167 {
168         OWeakObject::release();
169 }
170 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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         GetShapePropertySet();
823         if (pShapePropertySet)
824             aAny = pShapePropertySet->getPropertyValue( aPropertyName );
825 	}
826 
827 	return aAny;
828 }
829 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
1209 uno::Reference<text::XText> SAL_CALL ScShapeObj::getText() throw(uno::RuntimeException)
1210 {
1211 	ScUnoGuard aGuard;
1212 	return this;
1213 }
1214 
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 
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 
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 
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 
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 
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 
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 
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 agregated 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 free'd 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 
1372 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 
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:
1408 	ShapeUnoEventAccessImpl( ScShapeObj* pShape ): mpShape( pShape )
1409 	{
1410 	}
1411 
1412 	// XNameReplace
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
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 
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 
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
1516     virtual uno::Type SAL_CALL getElementType() throw(uno::RuntimeException)
1517 	{
1518 		return *SEQTYPE(::getCppuType((const uno::Sequence< beans::PropertyValue >*)0));
1519 	}
1520 
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
1529 ScShapeObj::getEvents(  ) throw(uno::RuntimeException)
1530 {
1531 	return new ShapeUnoEventAccessImpl( this );
1532 }
1533 
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 
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 
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