Update ooo320-m1
[ooovba.git] / slideshow / source / engine / screenupdater.cxx
blob8cfaaddf21e4a04ef821a28ddbb8828ba2e23eeb
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: screenupdater.cxx,v $
10 * $Revision: 1.4 $
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 ************************************************************************/
30 #include "precompiled_slideshow.hxx"
32 #include "screenupdater.hxx"
33 #include "listenercontainer.hxx"
35 #include <boost/bind.hpp>
36 #include <vector>
37 #include <algorithm>
39 namespace {
40 class UpdateLock : public ::slideshow::internal::ScreenUpdater::UpdateLock
42 public:
43 UpdateLock (::slideshow::internal::ScreenUpdater& rUpdater, const bool bStartLocked);
44 virtual ~UpdateLock (void);
45 virtual void Activate (void);
46 private:
47 ::slideshow::internal::ScreenUpdater& mrUpdater;
48 bool mbIsActivated;
52 namespace slideshow
54 namespace internal
56 typedef std::vector<
57 std::pair<UnoViewSharedPtr,bool> > UpdateRequestVector;
59 struct ScreenUpdater::ImplScreenUpdater
61 /** List of registered ViewUpdaters, to consult for necessary
62 updates
64 ThreadUnsafeListenerContainer<
65 ViewUpdateSharedPtr,
66 std::vector<ViewUpdateSharedPtr> > maUpdaters;
68 /// Views that have been notified for update
69 UpdateRequestVector maViewUpdateRequests;
71 /// List of View. Used to issue screen updates on.
72 UnoViewContainer const& mrViewContainer;
74 /// True, if a notifyUpdate() for all views has been issued.
75 bool mbUpdateAllRequest;
77 /// True, if at least one notifyUpdate() call had bViewClobbered set
78 bool mbViewClobbered;
80 /// The screen is updated only when mnLockCount==0
81 sal_Int32 mnLockCount;
83 explicit ImplScreenUpdater( UnoViewContainer const& rViewContainer ) :
84 maUpdaters(),
85 maViewUpdateRequests(),
86 mrViewContainer(rViewContainer),
87 mbUpdateAllRequest(false),
88 mbViewClobbered(false),
89 mnLockCount(0)
93 ScreenUpdater::ScreenUpdater( UnoViewContainer const& rViewContainer ) :
94 mpImpl(new ImplScreenUpdater(rViewContainer) )
98 ScreenUpdater::~ScreenUpdater()
100 // outline because of pimpl
103 void ScreenUpdater::notifyUpdate()
105 mpImpl->mbUpdateAllRequest = true;
108 void ScreenUpdater::notifyUpdate( const UnoViewSharedPtr& rView,
109 bool bViewClobbered )
111 mpImpl->maViewUpdateRequests.push_back(
112 std::make_pair(rView, bViewClobbered) );
114 if( bViewClobbered )
115 mpImpl->mbViewClobbered = true;
118 void ScreenUpdater::commitUpdates()
120 if (mpImpl->mnLockCount > 0)
121 return;
123 // cases:
125 // (a) no update necessary at all
127 // (b) no ViewUpdate-generated update
128 // I. update all views requested -> for_each( mrViewContainer )
129 // II. update some views requested -> for_each( maViewUpdateRequests )
131 // (c) ViewUpdate-triggered update - update all views
134 // any ViewUpdate-triggered updates?
135 const bool bViewUpdatesNeeded(
136 mpImpl->maUpdaters.apply(
137 boost::mem_fn(&ViewUpdate::needsUpdate)) );
139 if( bViewUpdatesNeeded )
141 mpImpl->maUpdaters.applyAll(
142 boost::mem_fn((bool (ViewUpdate::*)())&ViewUpdate::update) );
145 if( bViewUpdatesNeeded ||
146 mpImpl->mbUpdateAllRequest )
148 // unconditionally update all views
149 std::for_each( mpImpl->mrViewContainer.begin(),
150 mpImpl->mrViewContainer.end(),
151 mpImpl->mbViewClobbered ?
152 boost::mem_fn(&View::paintScreen) :
153 boost::mem_fn(&View::updateScreen) );
155 else if( !mpImpl->maViewUpdateRequests.empty() )
157 // update notified views only
158 UpdateRequestVector::const_iterator aIter(
159 mpImpl->maViewUpdateRequests.begin() );
160 const UpdateRequestVector::const_iterator aEnd(
161 mpImpl->maViewUpdateRequests.end() );
162 while( aIter != aEnd )
164 // TODO(P1): this is O(n^2) in the number of views, if
165 // lots of views notify updates.
166 const UnoViewVector::const_iterator aEndOfViews(
167 mpImpl->mrViewContainer.end() );
168 UnoViewVector::const_iterator aFoundView;
169 if( (aFoundView=std::find(mpImpl->mrViewContainer.begin(),
170 aEndOfViews,
171 aIter->first)) != aEndOfViews )
173 if( aIter->second )
174 (*aFoundView)->paintScreen(); // force-paint
175 else
176 (*aFoundView)->updateScreen(); // update changes only
179 ++aIter;
183 // done - clear requests
184 mpImpl->mbViewClobbered = false;
185 mpImpl->mbUpdateAllRequest = false;
186 UpdateRequestVector().swap( mpImpl->maViewUpdateRequests );
189 void ScreenUpdater::addViewUpdate( ViewUpdateSharedPtr const& rViewUpdate )
191 mpImpl->maUpdaters.add( rViewUpdate );
194 void ScreenUpdater::removeViewUpdate( ViewUpdateSharedPtr const& rViewUpdate )
196 mpImpl->maUpdaters.remove( rViewUpdate );
199 void ScreenUpdater::requestImmediateUpdate()
201 if (mpImpl->mnLockCount > 0)
202 return;
204 // TODO(F2): This will interfere with other updates, since it
205 // happens out-of-sync with main animation loop. Might cause
206 // artifacts.
207 std::for_each( mpImpl->mrViewContainer.begin(),
208 mpImpl->mrViewContainer.end(),
209 boost::mem_fn(&View::updateScreen) );
212 void ScreenUpdater::lockUpdates (void)
214 ++mpImpl->mnLockCount;
215 OSL_ASSERT(mpImpl->mnLockCount>0);
218 void ScreenUpdater::unlockUpdates (void)
220 OSL_ASSERT(mpImpl->mnLockCount>0);
221 if (mpImpl->mnLockCount > 0)
223 --mpImpl->mnLockCount;
224 if (mpImpl->mnLockCount)
225 commitUpdates();
229 ::boost::shared_ptr<ScreenUpdater::UpdateLock> ScreenUpdater::createLock (const bool bStartLocked)
231 return ::boost::shared_ptr<ScreenUpdater::UpdateLock>(new ::UpdateLock(*this, bStartLocked));
235 } // namespace internal
236 } // namespace slideshow
238 namespace {
240 UpdateLock::UpdateLock (
241 ::slideshow::internal::ScreenUpdater& rUpdater,
242 const bool bStartLocked)
243 : mrUpdater(rUpdater),
244 mbIsActivated(false)
246 if (bStartLocked)
247 Activate();
253 UpdateLock::~UpdateLock (void)
255 if (mbIsActivated)
256 mrUpdater.unlockUpdates();
262 void UpdateLock::Activate (void)
264 if ( ! mbIsActivated)
266 mbIsActivated = true;
267 mrUpdater.lockUpdates();