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