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