Update ooo320-m1
[ooovba.git] / slideshow / source / engine / slide / shapemanagerimpl.cxx
blob052758d2031b78974b3a5863b315c82ead4f0df4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: shapemanagerimpl.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 #include <canvas/debug.hxx>
35 #include <tools/diagnose_ex.h>
36 #include <com/sun/star/awt/MouseButton.hpp>
37 #include <com/sun/star/awt/SystemPointer.hpp>
38 #include <com/sun/star/presentation/XShapeEventListener.hpp>
39 #include <com/sun/star/presentation/XSlideShowListener.hpp>
40 #include <com/sun/star/awt/MouseButton.hpp>
42 #include "shapemanagerimpl.hxx"
44 #include <boost/bind.hpp>
46 using namespace com::sun::star;
48 namespace slideshow {
49 namespace internal {
51 ShapeManagerImpl::ShapeManagerImpl( EventMultiplexer& rMultiplexer,
52 LayerManagerSharedPtr const& rLayerManager,
53 CursorManager& rCursorManager,
54 const ShapeEventListenerMap& rGlobalListenersMap,
55 const ShapeCursorMap& rGlobalCursorMap ):
56 mrMultiplexer(rMultiplexer),
57 mpLayerManager(rLayerManager),
58 mrCursorManager(rCursorManager),
59 mrGlobalListenersMap(rGlobalListenersMap),
60 mrGlobalCursorMap(rGlobalCursorMap),
61 maShapeListenerMap(),
62 maShapeCursorMap(),
63 maHyperlinkShapes(),
64 mbEnabled(false)
68 void ShapeManagerImpl::activate( bool bSlideBackgoundPainted )
70 if( !mbEnabled )
72 mbEnabled = true;
74 // register this handler on EventMultiplexer.
75 // Higher prio (overrides other engine handlers)
76 mrMultiplexer.addMouseMoveHandler( shared_from_this(), 2.0 );
77 mrMultiplexer.addClickHandler( shared_from_this(), 2.0 );
78 mrMultiplexer.addShapeListenerHandler( shared_from_this() );
80 // clone listener map
81 uno::Reference<presentation::XShapeEventListener> xDummyListener;
82 std::for_each( mrGlobalListenersMap.begin(),
83 mrGlobalListenersMap.end(),
84 boost::bind( &ShapeManagerImpl::listenerAdded,
85 this,
86 boost::cref(xDummyListener),
87 boost::bind(
88 std::select1st<ShapeEventListenerMap::value_type>(),
89 _1 )));
91 // clone cursor map
92 std::for_each( mrGlobalCursorMap.begin(),
93 mrGlobalCursorMap.end(),
94 boost::bind( &ShapeManagerImpl::cursorChanged,
95 this,
96 boost::bind(
97 std::select1st<ShapeCursorMap::value_type>(),
98 _1 ),
99 boost::bind(
100 std::select2nd<ShapeCursorMap::value_type>(),
101 _1 )));
103 if( mpLayerManager )
104 mpLayerManager->activate( bSlideBackgoundPainted );
108 void ShapeManagerImpl::deactivate()
110 if( mbEnabled )
112 mbEnabled = false;
114 if( mpLayerManager )
115 mpLayerManager->deactivate();
117 maShapeListenerMap.clear();
118 maShapeCursorMap.clear();
120 mrMultiplexer.removeShapeListenerHandler( shared_from_this() );
121 mrMultiplexer.removeMouseMoveHandler( shared_from_this() );
122 mrMultiplexer.removeClickHandler( shared_from_this() );
126 void ShapeManagerImpl::dispose()
128 // remove listeners (EventMultiplexer holds shared_ptr on us)
129 deactivate();
131 maHyperlinkShapes.clear();
132 maShapeCursorMap.clear();
133 maShapeListenerMap.clear();
134 mpLayerManager.reset();
137 bool ShapeManagerImpl::handleMousePressed( awt::MouseEvent const& )
139 // not used here
140 return false; // did not handle the event
143 bool ShapeManagerImpl::handleMouseReleased( awt::MouseEvent const& e )
145 if( !mbEnabled || e.Buttons != awt::MouseButton::LEFT)
146 return false;
148 basegfx::B2DPoint const aPosition( e.X, e.Y );
150 // first check for hyperlinks, because these have
151 // highest prio:
152 rtl::OUString const hyperlink( checkForHyperlink(aPosition) );
153 if( hyperlink.getLength() > 0 )
155 mrMultiplexer.notifyHyperlinkClicked(hyperlink);
156 return true; // event consumed
159 // find matching shape (scan reversely, to coarsely match
160 // paint order)
161 ShapeToListenersMap::reverse_iterator aCurrBroadcaster(
162 maShapeListenerMap.rbegin() );
163 ShapeToListenersMap::reverse_iterator const aEndBroadcasters(
164 maShapeListenerMap.rend() );
165 while( aCurrBroadcaster != aEndBroadcasters )
167 // TODO(F2): Get proper geometry polygon from the
168 // shape, to avoid having areas outside the shape
169 // react on the mouse
170 if( aCurrBroadcaster->first->getBounds().isInside( aPosition ) &&
171 aCurrBroadcaster->first->isVisible() )
173 // shape hit, and shape is visible. Raise
174 // event.
176 boost::shared_ptr<cppu::OInterfaceContainerHelper> const pCont(
177 aCurrBroadcaster->second );
178 uno::Reference<drawing::XShape> const xShape(
179 aCurrBroadcaster->first->getXShape() );
181 // DON'T do anything with /this/ after this point!
182 pCont->forEach<presentation::XShapeEventListener>(
183 boost::bind( &presentation::XShapeEventListener::click,
184 _1,
185 boost::cref(xShape),
186 boost::cref(e) ));
188 return true; // handled this event
191 ++aCurrBroadcaster;
194 return false; // did not handle this event
197 bool ShapeManagerImpl::handleMouseEntered( const awt::MouseEvent& )
199 // not used here
200 return false; // did not handle the event
203 bool ShapeManagerImpl::handleMouseExited( const awt::MouseEvent& )
205 // not used here
206 return false; // did not handle the event
209 bool ShapeManagerImpl::handleMouseDragged( const awt::MouseEvent& )
211 // not used here
212 return false; // did not handle the event
215 bool ShapeManagerImpl::handleMouseMoved( const awt::MouseEvent& e )
217 if( !mbEnabled )
218 return false;
220 // find hit shape in map
221 const ::basegfx::B2DPoint aPosition( e.X, e.Y );
222 sal_Int16 nNewCursor(-1);
224 if( checkForHyperlink(aPosition).getLength() > 0 )
226 nNewCursor = awt::SystemPointer::REFHAND;
228 else
230 // find matching shape (scan reversely, to coarsely match
231 // paint order)
232 ShapeToCursorMap::reverse_iterator aCurrCursor(
233 maShapeCursorMap.rbegin() );
234 ShapeToCursorMap::reverse_iterator const aEndCursors(
235 maShapeCursorMap.rend() );
236 while( aCurrCursor != aEndCursors )
238 // TODO(F2): Get proper geometry polygon from the
239 // shape, to avoid having areas outside the shape
240 // react on the mouse
241 if( aCurrCursor->first->getBounds().isInside( aPosition ) &&
242 aCurrCursor->first->isVisible() )
244 // shape found, and it's visible. set
245 // requested cursor to shape's
246 nNewCursor = aCurrCursor->second;
247 break;
250 ++aCurrCursor;
254 if( nNewCursor == -1 )
255 mrCursorManager.resetCursor();
256 else
257 mrCursorManager.requestCursor( nNewCursor );
259 return false; // we don't /eat/ this event. Lower prio
260 // handler should see it, too.
263 bool ShapeManagerImpl::update()
265 if( mbEnabled && mpLayerManager )
266 return mpLayerManager->update();
268 return false;
271 bool ShapeManagerImpl::update( ViewSharedPtr const& /*rView*/ )
273 // am not doing view-specific updates here.
274 return false;
277 bool ShapeManagerImpl::needsUpdate() const
279 if( mbEnabled && mpLayerManager )
280 return mpLayerManager->isUpdatePending();
282 return false;
285 void ShapeManagerImpl::enterAnimationMode( const AnimatableShapeSharedPtr& rShape )
287 if( mbEnabled && mpLayerManager )
288 mpLayerManager->enterAnimationMode(rShape);
291 void ShapeManagerImpl::leaveAnimationMode( const AnimatableShapeSharedPtr& rShape )
293 if( mbEnabled && mpLayerManager )
294 mpLayerManager->leaveAnimationMode(rShape);
297 void ShapeManagerImpl::notifyShapeUpdate( const ShapeSharedPtr& rShape )
299 if( mbEnabled && mpLayerManager )
300 mpLayerManager->notifyShapeUpdate(rShape);
303 ShapeSharedPtr ShapeManagerImpl::lookupShape( uno::Reference< drawing::XShape > const & xShape ) const
305 if( mpLayerManager )
306 return mpLayerManager->lookupShape(xShape);
308 return ShapeSharedPtr();
311 void ShapeManagerImpl::addHyperlinkArea( const HyperlinkAreaSharedPtr& rArea )
313 maHyperlinkShapes.insert(rArea);
316 void ShapeManagerImpl::removeHyperlinkArea( const HyperlinkAreaSharedPtr& rArea )
318 maHyperlinkShapes.erase(rArea);
321 AttributableShapeSharedPtr ShapeManagerImpl::getSubsetShape( const AttributableShapeSharedPtr& rOrigShape,
322 const DocTreeNode& rTreeNode )
324 if( mpLayerManager )
325 return mpLayerManager->getSubsetShape(rOrigShape,rTreeNode);
327 return AttributableShapeSharedPtr();
330 void ShapeManagerImpl::revokeSubset( const AttributableShapeSharedPtr& rOrigShape,
331 const AttributableShapeSharedPtr& rSubsetShape )
333 if( mpLayerManager )
334 mpLayerManager->revokeSubset(rOrigShape,rSubsetShape);
337 bool ShapeManagerImpl::listenerAdded(
338 const uno::Reference<presentation::XShapeEventListener>& /*xListener*/,
339 const uno::Reference<drawing::XShape>& xShape )
341 ShapeEventListenerMap::const_iterator aIter;
342 if( (aIter = mrGlobalListenersMap.find( xShape )) ==
343 mrGlobalListenersMap.end() )
345 ENSURE_OR_RETURN(false,
346 "ShapeManagerImpl::listenerAdded(): global "
347 "shape listener map inconsistency!");
350 // is this one of our shapes? other shapes are ignored.
351 ShapeSharedPtr pShape( lookupShape(xShape) );
352 if( pShape )
354 maShapeListenerMap.insert(
355 ShapeToListenersMap::value_type(
356 pShape,
357 aIter->second));
360 return true;
363 bool ShapeManagerImpl::listenerRemoved(
364 const uno::Reference<presentation::XShapeEventListener>& /*xListener*/,
365 const uno::Reference<drawing::XShape>& xShape )
367 // shape really erased from map? maybe there are other listeners
368 // for the same shape pending...
369 if( mrGlobalListenersMap.find(xShape) == mrGlobalListenersMap.end() )
371 // is this one of our shapes? other shapes are ignored.
372 ShapeSharedPtr pShape( lookupShape(xShape) );
373 if( pShape )
374 maShapeListenerMap.erase(pShape);
377 return true;
380 bool ShapeManagerImpl::cursorChanged( const uno::Reference<drawing::XShape>& xShape,
381 sal_Int16 nCursor )
383 ShapeSharedPtr pShape( lookupShape(xShape) );
385 // is this one of our shapes? other shapes are ignored.
386 if( !pShape )
387 return false;
389 if( mrGlobalCursorMap.find(xShape) == mrGlobalCursorMap.end() )
391 // erased from global map - erase locally, too
392 maShapeCursorMap.erase(pShape);
394 else
396 // included in global map - update local one
397 ShapeToCursorMap::iterator aIter;
398 if( (aIter = maShapeCursorMap.find(pShape))
399 == maShapeCursorMap.end() )
401 maShapeCursorMap.insert(
402 ShapeToCursorMap::value_type(
403 pShape,
404 nCursor ));
406 else
408 aIter->second = nCursor;
412 return true;
415 rtl::OUString ShapeManagerImpl::checkForHyperlink( basegfx::B2DPoint const& hitPos ) const
417 // find matching region (scan reversely, to coarsely match
418 // paint order): set is ordered by priority
419 AreaSet::const_reverse_iterator iPos( maHyperlinkShapes.rbegin() );
420 AreaSet::const_reverse_iterator const iEnd( maHyperlinkShapes.rend() );
421 for( ; iPos != iEnd; ++iPos )
423 HyperlinkAreaSharedPtr const& pArea = *iPos;
425 HyperlinkArea::HyperlinkRegions const linkRegions(
426 pArea->getHyperlinkRegions() );
428 for( std::size_t i = linkRegions.size(); i--; )
430 basegfx::B2DRange const& region = linkRegions[i].first;
431 if( region.isInside(hitPos) )
432 return linkRegions[i].second;
436 return rtl::OUString();
439 void ShapeManagerImpl::addIntrinsicAnimationHandler( const IntrinsicAnimationEventHandlerSharedPtr& rHandler )
441 maIntrinsicAnimationEventHandlers.add( rHandler );
444 void ShapeManagerImpl::removeIntrinsicAnimationHandler( const IntrinsicAnimationEventHandlerSharedPtr& rHandler )
446 maIntrinsicAnimationEventHandlers.remove( rHandler );
449 bool ShapeManagerImpl::notifyIntrinsicAnimationsEnabled()
451 return maIntrinsicAnimationEventHandlers.applyAll(
452 boost::mem_fn(&IntrinsicAnimationEventHandler::enableAnimations));
455 bool ShapeManagerImpl::notifyIntrinsicAnimationsDisabled()
457 return maIntrinsicAnimationEventHandlers.applyAll(
458 boost::mem_fn(&IntrinsicAnimationEventHandler::disableAnimations));
463 } // namespace internal
464 } // namespace presentation