xref: /AOO41X/main/sd/source/ui/sidebar/MasterPageContainerQueue.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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