15b190011SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
35b190011SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
45b190011SAndrew Rist * or more contributor license agreements. See the NOTICE file
55b190011SAndrew Rist * distributed with this work for additional information
65b190011SAndrew Rist * regarding copyright ownership. The ASF licenses this file
75b190011SAndrew Rist * to you under the Apache License, Version 2.0 (the
85b190011SAndrew Rist * "License"); you may not use this file except in compliance
95b190011SAndrew Rist * with the License. You may obtain a copy of the License at
105b190011SAndrew Rist *
115b190011SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
125b190011SAndrew Rist *
135b190011SAndrew Rist * Unless required by applicable law or agreed to in writing,
145b190011SAndrew Rist * software distributed under the License is distributed on an
155b190011SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
165b190011SAndrew Rist * KIND, either express or implied. See the License for the
175b190011SAndrew Rist * specific language governing permissions and limitations
185b190011SAndrew Rist * under the License.
195b190011SAndrew Rist *
205b190011SAndrew Rist *************************************************************/
215b190011SAndrew Rist
22cdf0e10cSrcweir #include "precompiled_sd.hxx"
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "MasterPageContainerQueue.hxx"
25cdf0e10cSrcweir
26cdf0e10cSrcweir #include "tools/IdleDetection.hxx"
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include <set>
29cdf0e10cSrcweir
307a32b0c8SAndre Fischer namespace sd { namespace sidebar {
31cdf0e10cSrcweir
32cdf0e10cSrcweir const sal_Int32 MasterPageContainerQueue::snDelayedCreationTimeout (15);
33cdf0e10cSrcweir const sal_Int32 MasterPageContainerQueue::snDelayedCreationTimeoutWhenNotIdle (100);
34cdf0e10cSrcweir const sal_Int32 MasterPageContainerQueue::snMasterPagePriorityBoost (5);
35cdf0e10cSrcweir const sal_Int32 MasterPageContainerQueue::snWaitForMoreRequestsPriorityThreshold (-10);
36cdf0e10cSrcweir sal_uInt32 MasterPageContainerQueue::snWaitForMoreRequestsCount(15);
37cdf0e10cSrcweir
38cdf0e10cSrcweir //===== MasterPageContainerQueue::PreviewCreationRequest ======================
39cdf0e10cSrcweir
40cdf0e10cSrcweir class MasterPageContainerQueue::PreviewCreationRequest
41cdf0e10cSrcweir {
42cdf0e10cSrcweir public:
PreviewCreationRequest(const SharedMasterPageDescriptor & rpDescriptor,int nPriority)43cdf0e10cSrcweir PreviewCreationRequest (const SharedMasterPageDescriptor& rpDescriptor, int nPriority)
44cdf0e10cSrcweir : mpDescriptor(rpDescriptor),
45cdf0e10cSrcweir mnPriority(nPriority)
46cdf0e10cSrcweir {}
47cdf0e10cSrcweir SharedMasterPageDescriptor mpDescriptor;
48cdf0e10cSrcweir int mnPriority;
49cdf0e10cSrcweir class Compare {public:
operator ()(const PreviewCreationRequest & r1,const PreviewCreationRequest & r2)50cdf0e10cSrcweir bool operator() (const PreviewCreationRequest& r1,const PreviewCreationRequest& r2)
51cdf0e10cSrcweir {
52cdf0e10cSrcweir if (r1.mnPriority != r2.mnPriority)
53cdf0e10cSrcweir {
54cdf0e10cSrcweir // Prefer requests with higher priority.
55cdf0e10cSrcweir return r1.mnPriority > r2.mnPriority;
56cdf0e10cSrcweir }
57cdf0e10cSrcweir else
58cdf0e10cSrcweir {
59cdf0e10cSrcweir // Prefer tokens that have been earlier created (those with lower
60cdf0e10cSrcweir // value).
61cdf0e10cSrcweir return r1.mpDescriptor->maToken < r2.mpDescriptor->maToken;
62cdf0e10cSrcweir }
63cdf0e10cSrcweir }
64cdf0e10cSrcweir };
65cdf0e10cSrcweir class CompareToken {public:
66cdf0e10cSrcweir MasterPageContainer::Token maToken;
CompareToken(MasterPageContainer::Token aToken)67cdf0e10cSrcweir CompareToken(MasterPageContainer::Token aToken) : maToken(aToken) {}
operator ()(const PreviewCreationRequest & rRequest)68cdf0e10cSrcweir bool operator() (const PreviewCreationRequest& rRequest)
69cdf0e10cSrcweir { return maToken==rRequest.mpDescriptor->maToken; }
70cdf0e10cSrcweir };
71cdf0e10cSrcweir };
72cdf0e10cSrcweir
73cdf0e10cSrcweir
74cdf0e10cSrcweir
75cdf0e10cSrcweir
76cdf0e10cSrcweir //===== MasterPageContainerQueue::RequestQueue ================================
77cdf0e10cSrcweir
78cdf0e10cSrcweir class MasterPageContainerQueue::RequestQueue
79cdf0e10cSrcweir : public ::std::set<PreviewCreationRequest,PreviewCreationRequest::Compare>
80cdf0e10cSrcweir {
81cdf0e10cSrcweir public:
RequestQueue(void)82cdf0e10cSrcweir RequestQueue (void) {}
83cdf0e10cSrcweir };
84cdf0e10cSrcweir
85cdf0e10cSrcweir
86cdf0e10cSrcweir
87cdf0e10cSrcweir
88cdf0e10cSrcweir //===== MasterPageContainerQueue ==============================================
89cdf0e10cSrcweir
Create(const::boost::weak_ptr<ContainerAdapter> & rpContainer)90cdf0e10cSrcweir MasterPageContainerQueue* MasterPageContainerQueue::Create (
91cdf0e10cSrcweir const ::boost::weak_ptr<ContainerAdapter>& rpContainer)
92cdf0e10cSrcweir {
93cdf0e10cSrcweir MasterPageContainerQueue* pQueue = new MasterPageContainerQueue(rpContainer);
94cdf0e10cSrcweir pQueue->LateInit();
95cdf0e10cSrcweir return pQueue;
96cdf0e10cSrcweir }
97cdf0e10cSrcweir
98cdf0e10cSrcweir
99cdf0e10cSrcweir
100cdf0e10cSrcweir
MasterPageContainerQueue(const::boost::weak_ptr<ContainerAdapter> & rpContainer)101cdf0e10cSrcweir MasterPageContainerQueue::MasterPageContainerQueue (
102cdf0e10cSrcweir const ::boost::weak_ptr<ContainerAdapter>& rpContainer)
103cdf0e10cSrcweir : mpWeakContainer(rpContainer),
104cdf0e10cSrcweir mpRequestQueue(new RequestQueue()),
105cdf0e10cSrcweir maDelayedPreviewCreationTimer(),
106cdf0e10cSrcweir mnRequestsServedCount(0)
107cdf0e10cSrcweir {
108cdf0e10cSrcweir }
109cdf0e10cSrcweir
110cdf0e10cSrcweir
111cdf0e10cSrcweir
112cdf0e10cSrcweir
~MasterPageContainerQueue(void)113cdf0e10cSrcweir MasterPageContainerQueue::~MasterPageContainerQueue (void)
114cdf0e10cSrcweir {
115cdf0e10cSrcweir maDelayedPreviewCreationTimer.Stop();
116cdf0e10cSrcweir while ( ! mpRequestQueue->empty())
117cdf0e10cSrcweir mpRequestQueue->erase(mpRequestQueue->begin());
118cdf0e10cSrcweir }
119cdf0e10cSrcweir
120cdf0e10cSrcweir
121cdf0e10cSrcweir
122cdf0e10cSrcweir
LateInit(void)123cdf0e10cSrcweir void MasterPageContainerQueue::LateInit (void)
124cdf0e10cSrcweir {
125cdf0e10cSrcweir // Set up the timer for the delayed creation of preview bitmaps.
126cdf0e10cSrcweir maDelayedPreviewCreationTimer.SetTimeout (snDelayedCreationTimeout);
127cdf0e10cSrcweir Link aLink (LINK(this,MasterPageContainerQueue,DelayedPreviewCreation));
128cdf0e10cSrcweir maDelayedPreviewCreationTimer.SetTimeoutHdl(aLink);
129cdf0e10cSrcweir }
130cdf0e10cSrcweir
131cdf0e10cSrcweir
132cdf0e10cSrcweir
133cdf0e10cSrcweir
RequestPreview(const SharedMasterPageDescriptor & rpDescriptor)134cdf0e10cSrcweir bool MasterPageContainerQueue::RequestPreview (const SharedMasterPageDescriptor& rpDescriptor)
135cdf0e10cSrcweir {
136cdf0e10cSrcweir bool bSuccess (false);
137cdf0e10cSrcweir if (rpDescriptor.get() != NULL
138cdf0e10cSrcweir && rpDescriptor->maLargePreview.GetSizePixel().Width() == 0)
139cdf0e10cSrcweir {
140cdf0e10cSrcweir sal_Int32 nPriority (CalculatePriority(rpDescriptor));
141cdf0e10cSrcweir
142cdf0e10cSrcweir // Add a new or replace an existing request.
143cdf0e10cSrcweir RequestQueue::iterator iRequest (::std::find_if(
144cdf0e10cSrcweir mpRequestQueue->begin(),
145cdf0e10cSrcweir mpRequestQueue->end(),
146cdf0e10cSrcweir PreviewCreationRequest::CompareToken(rpDescriptor->maToken)));
147cdf0e10cSrcweir // When a request for the same token exists then the lowest of the
148cdf0e10cSrcweir // two priorities is used.
149cdf0e10cSrcweir if (iRequest != mpRequestQueue->end())
150cdf0e10cSrcweir if (iRequest->mnPriority < nPriority)
151cdf0e10cSrcweir {
152cdf0e10cSrcweir mpRequestQueue->erase(iRequest);
153cdf0e10cSrcweir iRequest = mpRequestQueue->end();
154cdf0e10cSrcweir }
155cdf0e10cSrcweir
156cdf0e10cSrcweir // Add a new request when none exists (or has just been erased).
157cdf0e10cSrcweir if (iRequest == mpRequestQueue->end())
158cdf0e10cSrcweir {
159cdf0e10cSrcweir mpRequestQueue->insert(PreviewCreationRequest(rpDescriptor,nPriority));
160cdf0e10cSrcweir maDelayedPreviewCreationTimer.Start();
161cdf0e10cSrcweir bSuccess = true;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir }
164cdf0e10cSrcweir return bSuccess;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir
167cdf0e10cSrcweir
168cdf0e10cSrcweir
169cdf0e10cSrcweir
CalculatePriority(const SharedMasterPageDescriptor & rpDescriptor) const170cdf0e10cSrcweir sal_Int32 MasterPageContainerQueue::CalculatePriority (
171cdf0e10cSrcweir const SharedMasterPageDescriptor& rpDescriptor) const
172cdf0e10cSrcweir {
173cdf0e10cSrcweir sal_Int32 nPriority;
174cdf0e10cSrcweir
175cdf0e10cSrcweir // The cost is used as a starting value.
176cdf0e10cSrcweir int nCost (0);
177cdf0e10cSrcweir if (rpDescriptor->mpPreviewProvider.get() != NULL)
178cdf0e10cSrcweir {
179cdf0e10cSrcweir nCost = rpDescriptor->mpPreviewProvider->GetCostIndex();
180cdf0e10cSrcweir if (rpDescriptor->mpPreviewProvider->NeedsPageObject())
181cdf0e10cSrcweir if (rpDescriptor->mpPageObjectProvider.get() != NULL)
182cdf0e10cSrcweir nCost += rpDescriptor->mpPageObjectProvider->GetCostIndex();
183cdf0e10cSrcweir }
184cdf0e10cSrcweir
185cdf0e10cSrcweir // Its negative value is used so that requests with a low cost are
186cdf0e10cSrcweir // preferred over those with high costs.
187cdf0e10cSrcweir nPriority = -nCost;
188cdf0e10cSrcweir
189cdf0e10cSrcweir // Add a term that introduces an order based on the appearance in the
190cdf0e10cSrcweir // AllMasterPagesSelector.
191cdf0e10cSrcweir nPriority -= rpDescriptor->maToken / 3;
192cdf0e10cSrcweir
193cdf0e10cSrcweir // Process requests for the CurrentMasterPagesSelector first.
194cdf0e10cSrcweir if (rpDescriptor->meOrigin == MasterPageContainer::MASTERPAGE)
195cdf0e10cSrcweir nPriority += snMasterPagePriorityBoost;
196cdf0e10cSrcweir
197cdf0e10cSrcweir return nPriority;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir
200cdf0e10cSrcweir
201cdf0e10cSrcweir
202cdf0e10cSrcweir
IMPL_LINK(MasterPageContainerQueue,DelayedPreviewCreation,Timer *,pTimer)203cdf0e10cSrcweir IMPL_LINK(MasterPageContainerQueue, DelayedPreviewCreation, Timer*, pTimer)
204cdf0e10cSrcweir {
205cdf0e10cSrcweir bool bIsShowingFullScreenShow (false);
206cdf0e10cSrcweir bool bWaitForMoreRequests (false);
207cdf0e10cSrcweir
208cdf0e10cSrcweir do
209cdf0e10cSrcweir {
210cdf0e10cSrcweir if (mpRequestQueue->size() == 0)
211cdf0e10cSrcweir break;
212cdf0e10cSrcweir
213cdf0e10cSrcweir // First check whether the system is idle.
214cdf0e10cSrcweir sal_Int32 nIdleState (tools::IdleDetection::GetIdleState());
215cdf0e10cSrcweir if (nIdleState != tools::IdleDetection::IDET_IDLE)
216cdf0e10cSrcweir {
217cdf0e10cSrcweir if ((nIdleState&tools::IdleDetection::IDET_FULL_SCREEN_SHOW_ACTIVE) != 0)
218cdf0e10cSrcweir bIsShowingFullScreenShow = true;
219cdf0e10cSrcweir break;
220cdf0e10cSrcweir }
221cdf0e10cSrcweir
222cdf0e10cSrcweir PreviewCreationRequest aRequest (*mpRequestQueue->begin());
223cdf0e10cSrcweir
224cdf0e10cSrcweir // Check if the request should really be processed right now.
225cdf0e10cSrcweir // Reasons to not do it are when its cost is high and not many other
226cdf0e10cSrcweir // requests have been inserted into the queue that would otherwise
227cdf0e10cSrcweir // be processed first.
228cdf0e10cSrcweir if (aRequest.mnPriority < snWaitForMoreRequestsPriorityThreshold
229cdf0e10cSrcweir && (mnRequestsServedCount+mpRequestQueue->size() < snWaitForMoreRequestsCount))
230cdf0e10cSrcweir {
231cdf0e10cSrcweir // Wait for more requests before this one is processed. Note
232cdf0e10cSrcweir // that the queue processing is not started anew when this
233cdf0e10cSrcweir // method is left. That is done when the next request is
234cdf0e10cSrcweir // inserted.
235cdf0e10cSrcweir bWaitForMoreRequests = true;
236cdf0e10cSrcweir break;
237cdf0e10cSrcweir }
238cdf0e10cSrcweir
239cdf0e10cSrcweir mpRequestQueue->erase(mpRequestQueue->begin());
240cdf0e10cSrcweir
241cdf0e10cSrcweir if (aRequest.mpDescriptor.get() != NULL)
242cdf0e10cSrcweir {
243cdf0e10cSrcweir mnRequestsServedCount += 1;
244cdf0e10cSrcweir if ( ! mpWeakContainer.expired())
245cdf0e10cSrcweir {
246cdf0e10cSrcweir ::boost::shared_ptr<ContainerAdapter> pContainer (mpWeakContainer);
247cdf0e10cSrcweir if (pContainer.get() != NULL)
248cdf0e10cSrcweir pContainer->UpdateDescriptor(aRequest.mpDescriptor,false,true,true);
249cdf0e10cSrcweir }
250cdf0e10cSrcweir }
251cdf0e10cSrcweir }
252cdf0e10cSrcweir while (false);
253cdf0e10cSrcweir
254cdf0e10cSrcweir if (mpRequestQueue->size() > 0 && ! bWaitForMoreRequests)
255cdf0e10cSrcweir {
256cdf0e10cSrcweir int nTimeout (snDelayedCreationTimeout);
257cdf0e10cSrcweir if (bIsShowingFullScreenShow)
258cdf0e10cSrcweir nTimeout = snDelayedCreationTimeoutWhenNotIdle;
259cdf0e10cSrcweir maDelayedPreviewCreationTimer.SetTimeout(nTimeout);
260cdf0e10cSrcweir pTimer->Start();
261cdf0e10cSrcweir }
262cdf0e10cSrcweir
263cdf0e10cSrcweir return 0;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir
266cdf0e10cSrcweir
267cdf0e10cSrcweir
268cdf0e10cSrcweir
HasRequest(MasterPageContainer::Token aToken) const269cdf0e10cSrcweir bool MasterPageContainerQueue::HasRequest (MasterPageContainer::Token aToken) const
270cdf0e10cSrcweir {
271cdf0e10cSrcweir RequestQueue::iterator iRequest (::std::find_if(
272cdf0e10cSrcweir mpRequestQueue->begin(),
273cdf0e10cSrcweir mpRequestQueue->end(),
274cdf0e10cSrcweir PreviewCreationRequest::CompareToken(aToken)));
275cdf0e10cSrcweir return (iRequest != mpRequestQueue->end());
276cdf0e10cSrcweir }
277cdf0e10cSrcweir
278cdf0e10cSrcweir
279cdf0e10cSrcweir
280cdf0e10cSrcweir
IsEmpty(void) const281cdf0e10cSrcweir bool MasterPageContainerQueue::IsEmpty (void) const
282cdf0e10cSrcweir {
283cdf0e10cSrcweir return mpRequestQueue->empty();
284cdf0e10cSrcweir }
285cdf0e10cSrcweir
286cdf0e10cSrcweir
287cdf0e10cSrcweir
288cdf0e10cSrcweir
ProcessAllRequests(void)289cdf0e10cSrcweir void MasterPageContainerQueue::ProcessAllRequests (void)
290cdf0e10cSrcweir {
291cdf0e10cSrcweir snWaitForMoreRequestsCount = 0;
292cdf0e10cSrcweir if (mpRequestQueue->size() > 0)
293cdf0e10cSrcweir maDelayedPreviewCreationTimer.Start();
294cdf0e10cSrcweir }
295cdf0e10cSrcweir
296cdf0e10cSrcweir
2977a32b0c8SAndre Fischer } } // end of namespace sd::sidebar
298