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