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