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