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