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 : // must be first
21 : #include <canvas/debug.hxx>
22 : #include <tools/diagnose_ex.h>
23 : #include <canvas/verbosetrace.hxx>
24 :
25 : #include <osl/diagnose.hxx>
26 : #include <com/sun/star/awt/Rectangle.hpp>
27 : #include <com/sun/star/beans/XPropertySet.hpp>
28 : #include <com/sun/star/awt/FontWeight.hpp>
29 : #include <comphelper/anytostring.hxx>
30 : #include <cppuhelper/exc_hlp.hxx>
31 :
32 : #include <vcl/metaact.hxx>
33 : #include <vcl/gdimtf.hxx>
34 : #include <vcl/wrkwin.hxx>
35 :
36 : #include <basegfx/numeric/ftools.hxx>
37 :
38 : #include <rtl/math.hxx>
39 :
40 : #include <com/sun/star/drawing/TextAnimationKind.hpp>
41 :
42 : #include <vcl/svapp.hxx>
43 : #include <vcl/window.hxx>
44 : #include <tools/stream.hxx>
45 : #include <com/sun/star/frame/XModel.hpp>
46 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 : #include <com/sun/star/datatransfer/XTransferable.hpp>
48 :
49 : #include <comphelper/scopeguard.hxx>
50 : #include <canvas/canvastools.hxx>
51 :
52 : #include <cmath>
53 : #include <algorithm>
54 : #include <functional>
55 : #include <limits>
56 :
57 : #include "drawshapesubsetting.hxx"
58 : #include "drawshape.hxx"
59 : #include "eventqueue.hxx"
60 : #include "wakeupevent.hxx"
61 : #include "subsettableshapemanager.hxx"
62 : #include "intrinsicanimationactivity.hxx"
63 : #include "slideshowexceptions.hxx"
64 : #include "tools.hxx"
65 : #include "gdimtftools.hxx"
66 : #include "drawinglayeranimation.hxx"
67 :
68 : #include <boost/bind.hpp>
69 : #include <math.h>
70 :
71 : using namespace ::com::sun::star;
72 :
73 :
74 : namespace slideshow
75 : {
76 : namespace internal
77 : {
78 :
79 :
80 : // Private methods
81 :
82 :
83 :
84 0 : GDIMetaFileSharedPtr DrawShape::forceScrollTextMetaFile()
85 : {
86 0 : if ((mnCurrMtfLoadFlags & MTF_LOAD_SCROLL_TEXT_MTF) != MTF_LOAD_SCROLL_TEXT_MTF)
87 : {
88 : // reload with added flags:
89 0 : mpCurrMtf.reset( new GDIMetaFile );
90 0 : mnCurrMtfLoadFlags |= MTF_LOAD_SCROLL_TEXT_MTF;
91 : getMetaFile(
92 : uno::Reference<lang::XComponent>(mxShape, uno::UNO_QUERY),
93 0 : mxPage, *mpCurrMtf, mnCurrMtfLoadFlags,
94 0 : mxComponentContext );
95 :
96 : // TODO(F1): Currently, the scroll metafile will
97 : // never contain any verbose text comments. Thus,
98 : // can only display the full mtf content, no
99 : // subsets.
100 0 : maSubsetting.reset( mpCurrMtf );
101 :
102 : // adapt maBounds. the requested scroll text metafile
103 : // will typically have dimension different from the
104 : // actual shape
105 0 : ::basegfx::B2DRectangle aScrollRect, aPaintRect;
106 0 : ENSURE_OR_THROW( getRectanglesFromScrollMtf( aScrollRect,
107 : aPaintRect,
108 : mpCurrMtf ),
109 : "DrawShape::forceScrollTextMetaFile(): Could "
110 : "not extract scroll anim rectangles from mtf" );
111 :
112 : // take the larger one of the two rectangles (that
113 : // should be the bound rect of the retrieved
114 : // metafile)
115 0 : if( aScrollRect.isInside( aPaintRect ) )
116 0 : maBounds = aScrollRect;
117 : else
118 0 : maBounds = aPaintRect;
119 : }
120 0 : return mpCurrMtf;
121 : }
122 :
123 0 : void DrawShape::updateStateIds() const
124 : {
125 : // Update the states, we've just redrawn or created a new
126 : // attribute layer.
127 0 : if( mpAttributeLayer )
128 : {
129 0 : mnAttributeTransformationState = mpAttributeLayer->getTransformationState();
130 0 : mnAttributeClipState = mpAttributeLayer->getClipState();
131 0 : mnAttributeAlphaState = mpAttributeLayer->getAlphaState();
132 0 : mnAttributePositionState = mpAttributeLayer->getPositionState();
133 0 : mnAttributeContentState = mpAttributeLayer->getContentState();
134 0 : mnAttributeVisibilityState = mpAttributeLayer->getVisibilityState();
135 : }
136 0 : }
137 :
138 0 : ViewShape::RenderArgs DrawShape::getViewRenderArgs() const
139 : {
140 : return ViewShape::RenderArgs(
141 : maBounds,
142 0 : getUpdateArea(),
143 0 : getBounds(),
144 : getActualUnitShapeBounds(),
145 : mpAttributeLayer,
146 0 : maSubsetting.getActiveSubsets(),
147 0 : mnPriority);
148 : }
149 :
150 0 : bool DrawShape::implRender( int nUpdateFlags ) const
151 : {
152 : SAL_INFO( "slideshow", "::presentation::internal::DrawShape::implRender()" );
153 : SAL_INFO( "slideshow", "::presentation::internal::DrawShape: 0x" << std::hex << this );
154 :
155 : // will perform the update now, clear update-enforcing
156 : // flags
157 0 : mbForceUpdate = false;
158 0 : mbAttributeLayerRevoked = false;
159 :
160 0 : ENSURE_OR_RETURN_FALSE( !maViewShapes.empty(),
161 : "DrawShape::implRender(): render called on DrawShape without views" );
162 :
163 0 : if( maBounds.isEmpty() )
164 : {
165 : // zero-sized shapes are effectively invisible,
166 : // thus, we save us the rendering...
167 0 : return true;
168 : }
169 :
170 : // redraw all view shapes, by calling their update() method
171 0 : ViewShape::RenderArgs renderArgs( getViewRenderArgs() );
172 0 : if( ::std::count_if( maViewShapes.begin(),
173 : maViewShapes.end(),
174 : ::boost::bind<bool>(
175 : ::boost::mem_fn( &ViewShape::update ), // though _theoretically_,
176 : // bind should eat this even
177 : // with _1 being a shared_ptr,
178 : // it does _not_ for MSVC without
179 : // the extra mem_fn. WTF.
180 : _1,
181 : ::boost::cref( mpCurrMtf ),
182 : ::boost::cref( renderArgs ),
183 : nUpdateFlags,
184 0 : isVisible() ) )
185 0 : != static_cast<ViewShapeVector::difference_type>(maViewShapes.size()) )
186 : {
187 : // at least one of the ViewShape::update() calls did return
188 : // false - update failed on at least one ViewLayer
189 0 : return false;
190 : }
191 :
192 : // successfully redrawn - update state IDs to detect next changes
193 0 : updateStateIds();
194 :
195 0 : return true;
196 : }
197 :
198 0 : int DrawShape::getUpdateFlags() const
199 : {
200 : // default: update nothing, unless ShapeAttributeStack
201 : // tells us below, or if the attribute layer was revoked
202 0 : int nUpdateFlags(ViewShape::NONE);
203 :
204 : // possibly the whole shape content changed
205 0 : if( mbAttributeLayerRevoked )
206 0 : nUpdateFlags = ViewShape::CONTENT;
207 :
208 :
209 : // determine what has to be updated
210 :
211 :
212 : // do we have an attribute layer?
213 0 : if( mpAttributeLayer )
214 : {
215 : // Prevent nUpdateFlags to be modified when the shape is not
216 : // visible, except when it just was hidden.
217 0 : if (mpAttributeLayer->getVisibility()
218 0 : || mpAttributeLayer->getVisibilityState() != mnAttributeVisibilityState )
219 : {
220 0 : if (mpAttributeLayer->getVisibilityState() != mnAttributeVisibilityState )
221 : {
222 : // Change of the visibility state is mapped to
223 : // content change because when the visibility
224 : // changes then usually a sprite is shown or hidden
225 : // and the background under has to be painted once.
226 0 : nUpdateFlags |= ViewShape::CONTENT;
227 : }
228 :
229 : // TODO(P1): This can be done without conditional branching.
230 : // See HAKMEM.
231 0 : if( mpAttributeLayer->getPositionState() != mnAttributePositionState )
232 : {
233 0 : nUpdateFlags |= ViewShape::POSITION;
234 : }
235 0 : if( mpAttributeLayer->getAlphaState() != mnAttributeAlphaState )
236 : {
237 0 : nUpdateFlags |= ViewShape::ALPHA;
238 : }
239 0 : if( mpAttributeLayer->getClipState() != mnAttributeClipState )
240 : {
241 0 : nUpdateFlags |= ViewShape::CLIP;
242 : }
243 0 : if( mpAttributeLayer->getTransformationState() != mnAttributeTransformationState )
244 : {
245 0 : nUpdateFlags |= ViewShape::TRANSFORMATION;
246 : }
247 0 : if( mpAttributeLayer->getContentState() != mnAttributeContentState )
248 : {
249 0 : nUpdateFlags |= ViewShape::CONTENT;
250 : }
251 : }
252 : }
253 :
254 0 : return nUpdateFlags;
255 : }
256 :
257 0 : ::basegfx::B2DRectangle DrawShape::getActualUnitShapeBounds() const
258 : {
259 0 : ENSURE_OR_THROW( !maViewShapes.empty(),
260 : "DrawShape::getActualUnitShapeBounds(): called on DrawShape without views" );
261 :
262 : const VectorOfDocTreeNodes& rSubsets(
263 0 : maSubsetting.getActiveSubsets() );
264 :
265 0 : const ::basegfx::B2DRectangle aDefaultBounds( 0.0,0.0,1.0,1.0 );
266 :
267 : // perform the cheapest check first
268 0 : if( rSubsets.empty() )
269 : {
270 : // if subset contains the whole shape, no need to call
271 : // the somewhat expensive bound calculation, since as
272 : // long as the subset is empty, this branch will be
273 : // taken.
274 0 : return aDefaultBounds;
275 : }
276 : else
277 : {
278 : OSL_ENSURE( rSubsets.size() != 1 ||
279 : !rSubsets.front().isEmpty(),
280 : "DrawShape::getActualUnitShapeBounds() expects a "
281 : "_non-empty_ subset vector for a subsetted shape!" );
282 :
283 : // are the cached bounds still valid?
284 0 : if( !maCurrentShapeUnitBounds )
285 : {
286 : // no, (re)generate them
287 : // =====================
288 :
289 : // setup cached values to defaults (might fail to
290 : // retrieve true bounds below)
291 0 : maCurrentShapeUnitBounds.reset( aDefaultBounds );
292 :
293 : // TODO(P2): the subset of the master shape (that from
294 : // which the subsets are subtracted) changes
295 : // relatively often (every time a subset shape is
296 : // added or removed). Maybe we should exclude it here,
297 : // always assuming full bounds?
298 :
299 : ::cppcanvas::CanvasSharedPtr pDestinationCanvas(
300 0 : maViewShapes.front()->getViewLayer()->getCanvas() );
301 :
302 : // TODO(Q2): Although this _is_ currently
303 : // view-agnostic, it might not stay like
304 : // that. Maybe this method should again be moved
305 : // to the ViewShape
306 : ::cppcanvas::RendererSharedPtr pRenderer(
307 0 : maViewShapes.front()->getRenderer(
308 0 : pDestinationCanvas, mpCurrMtf, mpAttributeLayer ) );
309 :
310 : // If we cannot not prefetch, be defensive and assume
311 : // full shape size
312 0 : if( pRenderer )
313 : {
314 : // temporarily, switch total transformation to identity
315 : // (need the bounds in the [0,1]x[0,1] unit coordinate
316 : // system.
317 0 : ::basegfx::B2DHomMatrix aEmptyTransformation;
318 :
319 0 : ::basegfx::B2DHomMatrix aOldTransform( pDestinationCanvas->getTransformation() );
320 0 : pDestinationCanvas->setTransformation( aEmptyTransformation );
321 0 : pRenderer->setTransformation( aEmptyTransformation );
322 :
323 : // restore old transformation when leaving the scope
324 : const ::comphelper::ScopeGuard aGuard(
325 : boost::bind( &::cppcanvas::Canvas::setTransformation,
326 0 : pDestinationCanvas, aOldTransform ) );
327 :
328 :
329 : // retrieve bounds for subset of whole metafile
330 :
331 :
332 0 : ::basegfx::B2DRange aTotalBounds;
333 :
334 : // cannot use ::boost::bind, ::basegfx::B2DRange::expand()
335 : // is overloaded.
336 0 : VectorOfDocTreeNodes::const_iterator aCurr( rSubsets.begin() );
337 0 : const VectorOfDocTreeNodes::const_iterator aEnd( rSubsets.end() );
338 0 : while( aCurr != aEnd )
339 : {
340 0 : aTotalBounds.expand( pRenderer->getSubsetArea(
341 : aCurr->getStartIndex(),
342 0 : aCurr->getEndIndex() ) );
343 0 : ++aCurr;
344 : }
345 :
346 : OSL_ENSURE( aTotalBounds.getMinX() >= -0.1 &&
347 : aTotalBounds.getMinY() >= -0.1 &&
348 : aTotalBounds.getMaxX() <= 1.1 &&
349 : aTotalBounds.getMaxY() <= 1.1,
350 : "DrawShape::getActualUnitShapeBounds(): bounds noticeably larger than original shape - clipping!" );
351 :
352 : // really make sure no shape appears larger than its
353 : // original bounds (there _are_ some pathologic cases,
354 : // especially when imported from PPT, that have
355 : // e.g. obscenely large polygon bounds)
356 : aTotalBounds.intersect(
357 : ::basegfx::B2DRange( 0.0, 0.0,
358 0 : 1.0, 1.0 ));
359 :
360 0 : maCurrentShapeUnitBounds.reset( aTotalBounds );
361 0 : }
362 : }
363 :
364 0 : return *maCurrentShapeUnitBounds;
365 : }
366 : }
367 :
368 0 : DrawShape::DrawShape( const uno::Reference< drawing::XShape >& xShape,
369 : const uno::Reference< drawing::XDrawPage >& xContainingPage,
370 : double nPrio,
371 : bool bForeignSource,
372 : const SlideShowContext& rContext ) :
373 : mxShape( xShape ),
374 : mxPage( xContainingPage ),
375 : maAnimationFrames(), // empty, we don't have no intrinsic animation
376 : mnCurrFrame(0),
377 : mpCurrMtf(),
378 : mnCurrMtfLoadFlags( bForeignSource
379 : ? MTF_LOAD_FOREIGN_SOURCE : MTF_LOAD_NONE ),
380 : maCurrentShapeUnitBounds(),
381 : mnPriority( nPrio ), // TODO(F1): When ZOrder someday becomes usable: make this ( getAPIShapePrio( xShape ) ),
382 : maBounds( getAPIShapeBounds( xShape ) ),
383 : mpAttributeLayer(),
384 : mpIntrinsicAnimationActivity(),
385 : mnAttributeTransformationState(0),
386 : mnAttributeClipState(0),
387 : mnAttributeAlphaState(0),
388 : mnAttributePositionState(0),
389 : mnAttributeContentState(0),
390 : mnAttributeVisibilityState(0),
391 : maViewShapes(),
392 : mxComponentContext( rContext.mxComponentContext ),
393 : maHyperlinkIndices(),
394 : maHyperlinkRegions(),
395 : maSubsetting(),
396 : mnIsAnimatedCount(0),
397 : mnAnimationLoopCount(0),
398 : meCycleMode(CYCLE_LOOP),
399 : mbIsVisible( true ),
400 : mbForceUpdate( false ),
401 : mbAttributeLayerRevoked( false ),
402 0 : mbDrawingLayerAnim( false )
403 : {
404 0 : ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
405 0 : ENSURE_OR_THROW( mxPage.is(), "DrawShape::DrawShape(): Invalid containing page" );
406 :
407 : // check for drawing layer animations:
408 0 : drawing::TextAnimationKind eKind = drawing::TextAnimationKind_NONE;
409 : uno::Reference<beans::XPropertySet> xPropSet( mxShape,
410 0 : uno::UNO_QUERY );
411 0 : if( xPropSet.is() )
412 : getPropertyValue( eKind, xPropSet,
413 0 : "TextAnimationKind" );
414 0 : mbDrawingLayerAnim = (eKind != drawing::TextAnimationKind_NONE);
415 :
416 : // must NOT be called from within initializer list, uses
417 : // state from mnCurrMtfLoadFlags!
418 0 : mpCurrMtf.reset( new GDIMetaFile );
419 : getMetaFile(
420 : uno::Reference<lang::XComponent>(xShape, uno::UNO_QUERY),
421 0 : xContainingPage, *mpCurrMtf, mnCurrMtfLoadFlags,
422 0 : mxComponentContext );
423 0 : ENSURE_OR_THROW( mpCurrMtf,
424 : "DrawShape::DrawShape(): Invalid metafile" );
425 0 : maSubsetting.reset( mpCurrMtf );
426 :
427 0 : prepareHyperlinkIndices();
428 0 : }
429 :
430 0 : DrawShape::DrawShape( const uno::Reference< drawing::XShape >& xShape,
431 : const uno::Reference< drawing::XDrawPage >& xContainingPage,
432 : double nPrio,
433 : const Graphic& rGraphic,
434 : const SlideShowContext& rContext ) :
435 : mxShape( xShape ),
436 : mxPage( xContainingPage ),
437 : maAnimationFrames(),
438 : mnCurrFrame(0),
439 : mpCurrMtf(),
440 : mnCurrMtfLoadFlags( MTF_LOAD_NONE ),
441 : maCurrentShapeUnitBounds(),
442 : mnPriority( nPrio ), // TODO(F1): When ZOrder someday becomes usable: make this ( getAPIShapePrio( xShape ) ),
443 : maBounds( getAPIShapeBounds( xShape ) ),
444 : mpAttributeLayer(),
445 : mpIntrinsicAnimationActivity(),
446 : mnAttributeTransformationState(0),
447 : mnAttributeClipState(0),
448 : mnAttributeAlphaState(0),
449 : mnAttributePositionState(0),
450 : mnAttributeContentState(0),
451 : mnAttributeVisibilityState(0),
452 : maViewShapes(),
453 : mxComponentContext( rContext.mxComponentContext ),
454 : maHyperlinkIndices(),
455 : maHyperlinkRegions(),
456 : maSubsetting(),
457 : mnIsAnimatedCount(0),
458 : mnAnimationLoopCount(0),
459 : meCycleMode(CYCLE_LOOP),
460 : mbIsVisible( true ),
461 : mbForceUpdate( false ),
462 : mbAttributeLayerRevoked( false ),
463 0 : mbDrawingLayerAnim( false )
464 : {
465 0 : ENSURE_OR_THROW( rGraphic.IsAnimated(),
466 : "DrawShape::DrawShape(): Graphic is no animation" );
467 :
468 : getAnimationFromGraphic( maAnimationFrames,
469 : mnAnimationLoopCount,
470 : meCycleMode,
471 0 : rGraphic );
472 :
473 0 : ENSURE_OR_THROW( !maAnimationFrames.empty() &&
474 : maAnimationFrames.front().mpMtf,
475 : "DrawShape::DrawShape(): " );
476 0 : mpCurrMtf = maAnimationFrames.front().mpMtf;
477 :
478 0 : ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
479 0 : ENSURE_OR_THROW( mxPage.is(), "DrawShape::DrawShape(): Invalid containing page" );
480 0 : ENSURE_OR_THROW( mpCurrMtf, "DrawShape::DrawShape(): Invalid metafile" );
481 0 : }
482 :
483 0 : DrawShape::DrawShape( const DrawShape& rSrc,
484 : const DocTreeNode& rTreeNode,
485 : double nPrio ) :
486 : mxShape( rSrc.mxShape ),
487 : mxPage( rSrc.mxPage ),
488 : maAnimationFrames(), // don't copy animations for subsets,
489 : // only the current frame!
490 : mnCurrFrame(0),
491 : mpCurrMtf( rSrc.mpCurrMtf ),
492 : mnCurrMtfLoadFlags( rSrc.mnCurrMtfLoadFlags ),
493 : maCurrentShapeUnitBounds(),
494 : mnPriority( nPrio ),
495 : maBounds( rSrc.maBounds ),
496 : mpAttributeLayer(),
497 : mpIntrinsicAnimationActivity(),
498 : mnAttributeTransformationState(0),
499 : mnAttributeClipState(0),
500 : mnAttributeAlphaState(0),
501 : mnAttributePositionState(0),
502 : mnAttributeContentState(0),
503 : mnAttributeVisibilityState(0),
504 : maViewShapes(),
505 : mxComponentContext( rSrc.mxComponentContext ),
506 : maHyperlinkIndices(),
507 : maHyperlinkRegions(),
508 : maSubsetting( rTreeNode, mpCurrMtf ),
509 : mnIsAnimatedCount(0),
510 : mnAnimationLoopCount(0),
511 : meCycleMode(CYCLE_LOOP),
512 : mbIsVisible( rSrc.mbIsVisible ),
513 : mbForceUpdate( false ),
514 : mbAttributeLayerRevoked( false ),
515 0 : mbDrawingLayerAnim( false )
516 : {
517 0 : ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
518 0 : ENSURE_OR_THROW( mpCurrMtf, "DrawShape::DrawShape(): Invalid metafile" );
519 :
520 : // xxx todo: currently not implemented for subsetted shapes;
521 : // would mean modifying set of hyperlink regions when
522 : // subsetting text portions. N.B.: there's already an
523 : // issue for this #i72828#
524 0 : }
525 :
526 :
527 :
528 : // Public methods
529 :
530 :
531 :
532 0 : DrawShapeSharedPtr DrawShape::create(
533 : const uno::Reference< drawing::XShape >& xShape,
534 : const uno::Reference< drawing::XDrawPage >& xContainingPage,
535 : double nPrio,
536 : bool bForeignSource,
537 : const SlideShowContext& rContext )
538 : {
539 : DrawShapeSharedPtr pShape( new DrawShape(xShape,
540 : xContainingPage,
541 : nPrio,
542 : bForeignSource,
543 0 : rContext) );
544 :
545 0 : if( pShape->hasIntrinsicAnimation() )
546 : {
547 : OSL_ASSERT( pShape->maAnimationFrames.empty() );
548 0 : if( pShape->getNumberOfTreeNodes(
549 0 : DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH) > 0 )
550 : {
551 0 : pShape->mpIntrinsicAnimationActivity =
552 : createDrawingLayerAnimActivity(
553 : rContext,
554 0 : pShape);
555 : }
556 : }
557 :
558 0 : if( pShape->hasHyperlinks() )
559 0 : rContext.mpSubsettableShapeManager->addHyperlinkArea( pShape );
560 :
561 0 : return pShape;
562 : }
563 :
564 0 : DrawShapeSharedPtr DrawShape::create(
565 : const uno::Reference< drawing::XShape >& xShape,
566 : const uno::Reference< drawing::XDrawPage >& xContainingPage,
567 : double nPrio,
568 : const Graphic& rGraphic,
569 : const SlideShowContext& rContext )
570 : {
571 : DrawShapeSharedPtr pShape( new DrawShape(xShape,
572 : xContainingPage,
573 : nPrio,
574 : rGraphic,
575 0 : rContext) );
576 :
577 0 : if( pShape->hasIntrinsicAnimation() )
578 : {
579 : OSL_ASSERT( !pShape->maAnimationFrames.empty() );
580 :
581 0 : std::vector<double> aTimeout;
582 : std::transform(
583 0 : pShape->maAnimationFrames.begin(),
584 0 : pShape->maAnimationFrames.end(),
585 : std::back_insert_iterator< std::vector<double> >( aTimeout ),
586 0 : boost::mem_fn(&MtfAnimationFrame::getDuration) );
587 :
588 : WakeupEventSharedPtr pWakeupEvent(
589 0 : new WakeupEvent( rContext.mrEventQueue.getTimer(),
590 0 : rContext.mrActivitiesQueue ) );
591 :
592 : ActivitySharedPtr pActivity =
593 : createIntrinsicAnimationActivity(
594 : rContext,
595 : pShape,
596 : pWakeupEvent,
597 : aTimeout,
598 0 : pShape->mnAnimationLoopCount,
599 0 : pShape->meCycleMode);
600 :
601 0 : pWakeupEvent->setActivity( pActivity );
602 0 : pShape->mpIntrinsicAnimationActivity = pActivity;
603 : }
604 :
605 : OSL_ENSURE( !pShape->hasHyperlinks(),
606 : "DrawShape::create(): graphic-only shapes must not have hyperlinks!" );
607 :
608 0 : return pShape;
609 : }
610 :
611 0 : DrawShape::~DrawShape()
612 : {
613 : try
614 : {
615 : // dispose intrinsic animation activity, else, it will
616 : // linger forever
617 0 : ActivitySharedPtr pActivity( mpIntrinsicAnimationActivity.lock() );
618 0 : if( pActivity )
619 0 : pActivity->dispose();
620 : }
621 0 : catch (uno::Exception &)
622 : {
623 : SAL_WARN( "slideshow", "" << comphelper::anyToString(cppu::getCaughtException() ) );
624 : }
625 0 : }
626 :
627 0 : uno::Reference< drawing::XShape > DrawShape::getXShape() const
628 : {
629 0 : return mxShape;
630 : }
631 :
632 0 : void DrawShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer,
633 : bool bRedrawLayer )
634 : {
635 : // already added?
636 0 : if( ::std::any_of( maViewShapes.begin(),
637 : maViewShapes.end(),
638 : ::boost::bind<bool>(
639 : ::std::equal_to< ViewLayerSharedPtr >(),
640 : ::boost::bind( &ViewShape::getViewLayer,
641 : _1 ),
642 0 : ::boost::cref( rNewLayer ) ) ))
643 : {
644 : // yes, nothing to do
645 0 : return;
646 : }
647 :
648 0 : ViewShapeSharedPtr pNewShape( new ViewShape( rNewLayer ) );
649 :
650 0 : maViewShapes.push_back( pNewShape );
651 :
652 : // pass on animation state
653 0 : if( mnIsAnimatedCount )
654 : {
655 0 : for( int i=0; i<mnIsAnimatedCount; ++i )
656 0 : pNewShape->enterAnimationMode();
657 : }
658 :
659 : // render the Shape on the newly added ViewLayer
660 0 : if( bRedrawLayer )
661 : {
662 : pNewShape->update( mpCurrMtf,
663 : getViewRenderArgs(),
664 : ViewShape::FORCE,
665 0 : isVisible() );
666 0 : }
667 : }
668 :
669 0 : bool DrawShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
670 : {
671 0 : const ViewShapeVector::iterator aEnd( maViewShapes.end() );
672 :
673 : OSL_ENSURE( ::std::count_if(maViewShapes.begin(),
674 : aEnd,
675 : ::boost::bind<bool>(
676 : ::std::equal_to< ViewLayerSharedPtr >(),
677 : ::boost::bind( &ViewShape::getViewLayer,
678 : _1 ),
679 : ::boost::cref( rLayer ) ) ) < 2,
680 : "DrawShape::removeViewLayer(): Duplicate ViewLayer entries!" );
681 :
682 0 : ViewShapeVector::iterator aIter;
683 :
684 0 : if( (aIter=::std::remove_if( maViewShapes.begin(),
685 : aEnd,
686 : ::boost::bind<bool>(
687 : ::std::equal_to< ViewLayerSharedPtr >(),
688 : ::boost::bind( &ViewShape::getViewLayer,
689 : _1 ),
690 0 : ::boost::cref( rLayer ) ) )) == aEnd )
691 : {
692 : // view layer seemingly was not added, failed
693 0 : return false;
694 : }
695 :
696 : // actually erase from container
697 0 : maViewShapes.erase( aIter, aEnd );
698 :
699 0 : return true;
700 : }
701 :
702 0 : bool DrawShape::clearAllViewLayers()
703 : {
704 0 : maViewShapes.clear();
705 0 : return true;
706 : }
707 :
708 0 : bool DrawShape::update() const
709 : {
710 0 : if( mbForceUpdate )
711 : {
712 0 : return render();
713 : }
714 : else
715 : {
716 0 : return implRender( getUpdateFlags() );
717 : }
718 : }
719 :
720 0 : bool DrawShape::render() const
721 : {
722 : // force redraw. Have to also pass on the update flags,
723 : // because e.g. content update (regeneration of the
724 : // metafile renderer) is normally not performed. A simple
725 : // ViewShape::FORCE would only paint the metafile in its
726 : // old state.
727 0 : return implRender( ViewShape::FORCE | getUpdateFlags() );
728 : }
729 :
730 0 : bool DrawShape::isContentChanged() const
731 : {
732 0 : return mbForceUpdate ||
733 0 : getUpdateFlags() != ViewShape::NONE;
734 : }
735 :
736 :
737 0 : ::basegfx::B2DRectangle DrawShape::getBounds() const
738 : {
739 : // little optimization: for non-modified shapes, we don't
740 : // create an ShapeAttributeStack, and therefore also don't
741 : // have to check it.
742 : return getShapePosSize( maBounds,
743 0 : mpAttributeLayer );
744 : }
745 :
746 0 : ::basegfx::B2DRectangle DrawShape::getDomBounds() const
747 : {
748 0 : return maBounds;
749 : }
750 :
751 : namespace
752 : {
753 : /** Functor expanding AA border for each passed ViewShape
754 :
755 : Could not use ::boost::bind here, since
756 : B2DRange::expand is overloaded (which yields one or
757 : the other template type deduction ambiguous)
758 : */
759 : class Expander
760 : {
761 : public:
762 0 : Expander( ::basegfx::B2DSize& rBounds ) :
763 0 : mrBounds( rBounds )
764 : {
765 0 : }
766 :
767 0 : void operator()( const ViewShapeSharedPtr& rShape ) const
768 : {
769 0 : const ::basegfx::B2DSize& rShapeBorder( rShape->getAntialiasingBorder() );
770 :
771 : mrBounds.setX(
772 : ::std::max(
773 0 : rShapeBorder.getX(),
774 0 : mrBounds.getX() ) );
775 : mrBounds.setY(
776 : ::std::max(
777 0 : rShapeBorder.getY(),
778 0 : mrBounds.getY() ) );
779 0 : }
780 :
781 : private:
782 : ::basegfx::B2DSize& mrBounds;
783 : };
784 : }
785 :
786 0 : ::basegfx::B2DRectangle DrawShape::getUpdateArea() const
787 : {
788 0 : ::basegfx::B2DRectangle aBounds;
789 :
790 : // an already empty shape bound need no further
791 : // treatment. In fact, any changes applied below would
792 : // actually remove the special empty state, thus, don't
793 : // change!
794 0 : if( !maBounds.isEmpty() )
795 : {
796 0 : basegfx::B2DRectangle aUnitBounds(0.0,0.0,1.0,1.0);
797 :
798 0 : if( !maViewShapes.empty() )
799 0 : aUnitBounds = getActualUnitShapeBounds();
800 :
801 0 : if( !aUnitBounds.isEmpty() )
802 : {
803 0 : if( mpAttributeLayer )
804 : {
805 : // calc actual shape area (in user coordinate
806 : // space) from the transformation as given by the
807 : // shape attribute layer
808 : aBounds = getShapeUpdateArea( aUnitBounds,
809 0 : getShapeTransformation( getBounds(),
810 : mpAttributeLayer ),
811 0 : mpAttributeLayer );
812 : }
813 : else
814 : {
815 : // no attribute layer, thus, the true shape bounds
816 : // can be directly derived from the XShape bound
817 : // attribute
818 : aBounds = getShapeUpdateArea( aUnitBounds,
819 0 : maBounds );
820 : }
821 :
822 0 : if( !maViewShapes.empty() )
823 : {
824 : // determine border needed for antialiasing the shape
825 0 : ::basegfx::B2DSize aAABorder(0.0,0.0);
826 :
827 : // for every view, get AA border and 'expand' aAABorder
828 : // appropriately.
829 : ::std::for_each( maViewShapes.begin(),
830 : maViewShapes.end(),
831 0 : Expander( aAABorder ) );
832 :
833 : // add calculated AA border to aBounds
834 0 : aBounds = ::basegfx::B2DRectangle( aBounds.getMinX() - aAABorder.getX(),
835 0 : aBounds.getMinY() - aAABorder.getY(),
836 0 : aBounds.getMaxX() + aAABorder.getX(),
837 0 : aBounds.getMaxY() + aAABorder.getY() );
838 : }
839 : }
840 : }
841 :
842 0 : return aBounds;
843 : }
844 :
845 0 : bool DrawShape::isVisible() const
846 : {
847 0 : bool bIsVisible( mbIsVisible );
848 :
849 0 : if( mpAttributeLayer )
850 : {
851 : // check whether visibility and alpha are not default
852 : // (mpAttributeLayer->isVisibilityValid() returns true
853 : // then): bVisible becomes true, if shape visibility
854 : // is on and alpha is not 0.0 (fully transparent)
855 0 : if( mpAttributeLayer->isVisibilityValid() )
856 0 : bIsVisible = mpAttributeLayer->getVisibility();
857 :
858 : // only touch bIsVisible, if the shape is still
859 : // visible - if getVisibility already made us
860 : // invisible, no alpha value will make us appear
861 : // again.
862 0 : if( bIsVisible && mpAttributeLayer->isAlphaValid() )
863 0 : bIsVisible = !::basegfx::fTools::equalZero( mpAttributeLayer->getAlpha() );
864 : }
865 :
866 0 : return bIsVisible;
867 : }
868 :
869 0 : double DrawShape::getPriority() const
870 : {
871 0 : return mnPriority;
872 : }
873 :
874 0 : bool DrawShape::isBackgroundDetached() const
875 : {
876 0 : return mnIsAnimatedCount > 0;
877 : }
878 :
879 0 : bool DrawShape::hasIntrinsicAnimation() const
880 : {
881 0 : return (!maAnimationFrames.empty() || mbDrawingLayerAnim);
882 : }
883 :
884 0 : bool DrawShape::setIntrinsicAnimationFrame( ::std::size_t nCurrFrame )
885 : {
886 0 : ENSURE_OR_RETURN_FALSE( nCurrFrame < maAnimationFrames.size(),
887 : "DrawShape::setIntrinsicAnimationFrame(): frame index out of bounds" );
888 :
889 0 : if( mnCurrFrame != nCurrFrame )
890 : {
891 0 : mnCurrFrame = nCurrFrame;
892 0 : mpCurrMtf = maAnimationFrames[ mnCurrFrame ].mpMtf;
893 0 : mbForceUpdate = true;
894 : }
895 :
896 0 : return true;
897 : }
898 :
899 : // hyperlink support
900 0 : void DrawShape::prepareHyperlinkIndices() const
901 : {
902 0 : if ( !maHyperlinkIndices.empty())
903 : {
904 0 : maHyperlinkIndices.clear();
905 0 : maHyperlinkRegions.clear();
906 : }
907 :
908 0 : sal_Int32 nIndex = 0;
909 0 : for ( MetaAction * pCurrAct = mpCurrMtf->FirstAction();
910 0 : pCurrAct != 0; pCurrAct = mpCurrMtf->NextAction() )
911 : {
912 0 : if (pCurrAct->GetType() == MetaActionType::COMMENT) {
913 : MetaCommentAction * pAct =
914 0 : static_cast<MetaCommentAction *>(pCurrAct);
915 : // skip comment if not a special XTEXT comment
916 0 : if (pAct->GetComment().equalsIgnoreAsciiCase("FIELD_SEQ_BEGIN") &&
917 : // e.g. date field doesn't have data!
918 : // currently assuming that only url field, this is
919 : // somehow fragile! xxx todo if possible
920 0 : pAct->GetData() != 0 &&
921 0 : pAct->GetDataSize() > 0)
922 : {
923 0 : if (!maHyperlinkIndices.empty() &&
924 0 : maHyperlinkIndices.back().second == -1) {
925 : SAL_WARN( "slideshow", "### pending FIELD_SEQ_END!" );
926 0 : maHyperlinkIndices.pop_back();
927 0 : maHyperlinkRegions.pop_back();
928 : }
929 : maHyperlinkIndices.push_back(
930 0 : HyperlinkIndexPair( nIndex + 1,
931 0 : -1 /* to be filled below */ ) );
932 : maHyperlinkRegions.push_back(
933 : HyperlinkRegion(
934 : basegfx::B2DRectangle(),
935 : OUString(
936 : reinterpret_cast<sal_Unicode const*>(
937 0 : pAct->GetData()),
938 0 : pAct->GetDataSize() / sizeof(sal_Unicode) )
939 0 : ) );
940 : }
941 0 : else if (pAct->GetComment().equalsIgnoreAsciiCase("FIELD_SEQ_END") &&
942 : // pending end is expected:
943 0 : !maHyperlinkIndices.empty() &&
944 0 : maHyperlinkIndices.back().second == -1)
945 : {
946 0 : maHyperlinkIndices.back().second = nIndex;
947 : }
948 0 : ++nIndex;
949 : }
950 : else
951 0 : nIndex += getNextActionOffset(pCurrAct);
952 : }
953 0 : if (!maHyperlinkIndices.empty() &&
954 0 : maHyperlinkIndices.back().second == -1) {
955 : SAL_WARN( "slideshow", "### pending FIELD_SEQ_END!" );
956 0 : maHyperlinkIndices.pop_back();
957 0 : maHyperlinkRegions.pop_back();
958 : }
959 : OSL_ASSERT( maHyperlinkIndices.size() == maHyperlinkRegions.size());
960 0 : }
961 :
962 0 : bool DrawShape::hasHyperlinks() const
963 : {
964 0 : return ! maHyperlinkRegions.empty();
965 : }
966 :
967 0 : HyperlinkArea::HyperlinkRegions DrawShape::getHyperlinkRegions() const
968 : {
969 : OSL_ASSERT( !maViewShapes.empty() );
970 :
971 0 : if( !isVisible() )
972 0 : return HyperlinkArea::HyperlinkRegions();
973 :
974 : // late init, determine regions:
975 0 : if( !maHyperlinkRegions.empty() &&
976 0 : !maViewShapes.empty() &&
977 : // region already inited?
978 0 : maHyperlinkRegions.front().first.getWidth() == 0 &&
979 0 : maHyperlinkRegions.front().first.getHeight() == 0 &&
980 0 : maHyperlinkRegions.size() == maHyperlinkIndices.size() )
981 : {
982 : // TODO(Q2): Although this _is_ currently
983 : // view-agnostic, it might not stay like that.
984 0 : ViewShapeSharedPtr const& pViewShape = maViewShapes.front();
985 : cppcanvas::CanvasSharedPtr const pCanvas(
986 0 : pViewShape->getViewLayer()->getCanvas() );
987 :
988 : // reuse Renderer of first view shape:
989 : cppcanvas::RendererSharedPtr const pRenderer(
990 : pViewShape->getRenderer(
991 0 : pCanvas, mpCurrMtf, mpAttributeLayer ) );
992 :
993 : OSL_ASSERT( pRenderer );
994 :
995 0 : if (pRenderer)
996 : {
997 : basegfx::B2DHomMatrix const aOldTransform(
998 0 : pCanvas->getTransformation() );
999 0 : basegfx::B2DHomMatrix aTransform;
1000 0 : pCanvas->setTransformation( aTransform /* empty */ );
1001 :
1002 : comphelper::ScopeGuard const resetOldTransformation(
1003 : boost::bind( &cppcanvas::Canvas::setTransformation,
1004 : pCanvas.get(),
1005 0 : boost::cref(aOldTransform) ));
1006 :
1007 : aTransform.scale( maBounds.getWidth(),
1008 0 : maBounds.getHeight() );
1009 0 : pRenderer->setTransformation( aTransform );
1010 0 : pRenderer->setClip();
1011 :
1012 0 : for( std::size_t pos = maHyperlinkRegions.size(); pos--; )
1013 : {
1014 : // get region:
1015 0 : HyperlinkIndexPair const& rIndices = maHyperlinkIndices[pos];
1016 : basegfx::B2DRectangle const region(
1017 0 : pRenderer->getSubsetArea( rIndices.first,
1018 0 : rIndices.second ));
1019 0 : maHyperlinkRegions[pos].first = region;
1020 0 : }
1021 0 : }
1022 : }
1023 :
1024 : // shift shape-relative hyperlink regions to
1025 : // slide-absolute position
1026 :
1027 0 : HyperlinkRegions aTranslatedRegions;
1028 0 : const basegfx::B2DPoint& rOffset(getBounds().getMinimum());
1029 0 : HyperlinkRegions::const_iterator aIter( maHyperlinkRegions.begin() );
1030 0 : HyperlinkRegions::const_iterator const aEnd ( maHyperlinkRegions.end() );
1031 0 : while( aIter != aEnd )
1032 : {
1033 0 : basegfx::B2DRange const& relRegion( aIter->first );
1034 : aTranslatedRegions.push_back(
1035 : std::make_pair(
1036 : basegfx::B2DRange(
1037 0 : relRegion.getMinimum() + rOffset,
1038 0 : relRegion.getMaximum() + rOffset),
1039 0 : aIter->second) );
1040 0 : ++aIter;
1041 : }
1042 :
1043 0 : return aTranslatedRegions;
1044 : }
1045 :
1046 0 : double DrawShape::getHyperlinkPriority() const
1047 : {
1048 0 : return getPriority();
1049 : }
1050 :
1051 :
1052 : // AnimatableShape methods
1053 :
1054 :
1055 0 : void DrawShape::enterAnimationMode()
1056 : {
1057 : OSL_ENSURE( !maViewShapes.empty(),
1058 : "DrawShape::enterAnimationMode(): called on DrawShape without views" );
1059 :
1060 0 : if( mnIsAnimatedCount == 0 )
1061 : {
1062 : // notify all ViewShapes, by calling their enterAnimationMode method.
1063 : // We're now entering animation mode
1064 : ::std::for_each( maViewShapes.begin(),
1065 : maViewShapes.end(),
1066 0 : ::boost::mem_fn( &ViewShape::enterAnimationMode ) );
1067 : }
1068 :
1069 0 : ++mnIsAnimatedCount;
1070 0 : }
1071 :
1072 0 : void DrawShape::leaveAnimationMode()
1073 : {
1074 : OSL_ENSURE( !maViewShapes.empty(),
1075 : "DrawShape::leaveAnimationMode(): called on DrawShape without views" );
1076 :
1077 0 : --mnIsAnimatedCount;
1078 :
1079 0 : if( mnIsAnimatedCount == 0 )
1080 : {
1081 : // notify all ViewShapes, by calling their leaveAnimationMode method.
1082 : // we're now leaving animation mode
1083 : ::std::for_each( maViewShapes.begin(),
1084 : maViewShapes.end(),
1085 0 : ::boost::mem_fn( &ViewShape::leaveAnimationMode ) );
1086 : }
1087 0 : }
1088 :
1089 :
1090 : // AttributableShape methods
1091 :
1092 :
1093 0 : ShapeAttributeLayerSharedPtr DrawShape::createAttributeLayer()
1094 : {
1095 : // create new layer, with last as its new child
1096 0 : mpAttributeLayer.reset( new ShapeAttributeLayer( mpAttributeLayer ) );
1097 :
1098 : // Update the local state ids to reflect those of the new layer.
1099 0 : updateStateIds();
1100 :
1101 0 : return mpAttributeLayer;
1102 : }
1103 :
1104 0 : bool DrawShape::revokeAttributeLayer( const ShapeAttributeLayerSharedPtr& rLayer )
1105 : {
1106 0 : if( !mpAttributeLayer )
1107 0 : return false; // no layers
1108 :
1109 0 : if( mpAttributeLayer == rLayer )
1110 : {
1111 : // it's the toplevel layer
1112 0 : mpAttributeLayer = mpAttributeLayer->getChildLayer();
1113 :
1114 : // force content redraw, all state variables have
1115 : // possibly changed
1116 0 : mbAttributeLayerRevoked = true;
1117 :
1118 0 : return true;
1119 : }
1120 : else
1121 : {
1122 : // pass on to the layer, to try its children
1123 0 : return mpAttributeLayer->revokeChildLayer( rLayer );
1124 : }
1125 : }
1126 :
1127 0 : ShapeAttributeLayerSharedPtr DrawShape::getTopmostAttributeLayer() const
1128 : {
1129 0 : return mpAttributeLayer;
1130 : }
1131 :
1132 0 : void DrawShape::setVisibility( bool bVisible )
1133 : {
1134 0 : if( mbIsVisible != bVisible )
1135 : {
1136 0 : mbIsVisible = bVisible;
1137 0 : mbForceUpdate = true;
1138 : }
1139 0 : }
1140 :
1141 0 : const DocTreeNodeSupplier& DrawShape::getTreeNodeSupplier() const
1142 : {
1143 0 : return *this;
1144 : }
1145 :
1146 0 : DocTreeNodeSupplier& DrawShape::getTreeNodeSupplier()
1147 : {
1148 0 : return *this;
1149 : }
1150 :
1151 0 : DocTreeNode DrawShape::getSubsetNode() const
1152 : {
1153 : // forward to delegate
1154 0 : return maSubsetting.getSubsetNode();
1155 : }
1156 :
1157 0 : AttributableShapeSharedPtr DrawShape::getSubset( const DocTreeNode& rTreeNode ) const
1158 : {
1159 : // forward to delegate
1160 0 : return maSubsetting.getSubsetShape( rTreeNode );
1161 : }
1162 :
1163 0 : bool DrawShape::createSubset( AttributableShapeSharedPtr& o_rSubset,
1164 : const DocTreeNode& rTreeNode )
1165 : {
1166 : // subset shape already created for this DocTreeNode?
1167 0 : AttributableShapeSharedPtr pSubset( maSubsetting.getSubsetShape( rTreeNode ) );
1168 :
1169 : // when true, this method has created a new subset
1170 : // DrawShape
1171 0 : bool bNewlyCreated( false );
1172 :
1173 0 : if( pSubset )
1174 : {
1175 0 : o_rSubset = pSubset;
1176 :
1177 : // reusing existing subset
1178 : }
1179 : else
1180 : {
1181 : // not yet created, init entry
1182 : o_rSubset.reset( new DrawShape( *this,
1183 : rTreeNode,
1184 : // TODO(Q3): That's a
1185 : // hack. We assume
1186 : // that start and end
1187 : // index will always
1188 : // be less than 65535
1189 0 : mnPriority +
1190 0 : rTreeNode.getStartIndex()/double(SAL_MAX_INT16) ));
1191 :
1192 0 : bNewlyCreated = true; // subset newly created
1193 : }
1194 :
1195 : // always register shape at DrawShapeSubsetting, to keep
1196 : // refcount up-to-date
1197 0 : maSubsetting.addSubsetShape( o_rSubset );
1198 :
1199 : // flush bounds cache
1200 0 : maCurrentShapeUnitBounds.reset();
1201 :
1202 0 : return bNewlyCreated;
1203 : }
1204 :
1205 0 : bool DrawShape::revokeSubset( const AttributableShapeSharedPtr& rShape )
1206 : {
1207 : // flush bounds cache
1208 0 : maCurrentShapeUnitBounds.reset();
1209 :
1210 : // forward to delegate
1211 0 : if( maSubsetting.revokeSubsetShape( rShape ) )
1212 : {
1213 : // force redraw, our content has possibly changed (as
1214 : // one of the subsets now display within our shape
1215 : // again).
1216 0 : mbForceUpdate = true;
1217 :
1218 : // #i47428# TEMP FIX: synchronize visibility of subset
1219 : // with parent.
1220 :
1221 : // TODO(F3): Remove here, and implement
1222 : // TEXT_ONLY/BACKGROUND_ONLY with the proverbial
1223 : // additional level of indirection: create a
1224 : // persistent subset, containing all text/only the
1225 : // background respectively. From _that_ object,
1226 : // generate the temporary character subset shapes.
1227 : const ShapeAttributeLayerSharedPtr& rAttrLayer(
1228 0 : rShape->getTopmostAttributeLayer() );
1229 0 : if( rAttrLayer &&
1230 0 : rAttrLayer->isVisibilityValid() &&
1231 0 : rAttrLayer->getVisibility() != isVisible() )
1232 : {
1233 0 : const bool bVisibility( rAttrLayer->getVisibility() );
1234 :
1235 : // visibilities differ - adjust ours, then
1236 0 : if( mpAttributeLayer )
1237 0 : mpAttributeLayer->setVisibility( bVisibility );
1238 : else
1239 0 : mbIsVisible = bVisibility;
1240 : }
1241 :
1242 : // END TEMP FIX
1243 :
1244 0 : return true;
1245 : }
1246 :
1247 0 : return false;
1248 : }
1249 :
1250 0 : sal_Int32 DrawShape::getNumberOfTreeNodes( DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
1251 : {
1252 0 : return maSubsetting.getNumberOfTreeNodes( eNodeType );
1253 : }
1254 :
1255 0 : DocTreeNode DrawShape::getTreeNode( sal_Int32 nNodeIndex,
1256 : DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
1257 : {
1258 0 : if ( hasHyperlinks())
1259 : {
1260 0 : prepareHyperlinkIndices();
1261 : }
1262 :
1263 0 : return maSubsetting.getTreeNode( nNodeIndex, eNodeType );
1264 : }
1265 :
1266 0 : sal_Int32 DrawShape::getNumberOfSubsetTreeNodes ( const DocTreeNode& rParentNode,
1267 : DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
1268 : {
1269 0 : return maSubsetting.getNumberOfSubsetTreeNodes( rParentNode, eNodeType );
1270 : }
1271 :
1272 0 : DocTreeNode DrawShape::getSubsetTreeNode( const DocTreeNode& rParentNode,
1273 : sal_Int32 nNodeIndex,
1274 : DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
1275 : {
1276 0 : return maSubsetting.getSubsetTreeNode( rParentNode, nNodeIndex, eNodeType );
1277 : }
1278 : }
1279 3 : }
1280 :
1281 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|