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