1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MasterPageContainerQueue.cxx,v $
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 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "MasterPageContainerQueue.hxx"
36 #include "tools/IdleDetection.hxx"
40 namespace sd
{ namespace toolpanel
{ namespace controls
{
42 const sal_Int32
MasterPageContainerQueue::snDelayedCreationTimeout (15);
43 const sal_Int32
MasterPageContainerQueue::snDelayedCreationTimeoutWhenNotIdle (100);
44 const sal_Int32
MasterPageContainerQueue::snMasterPagePriorityBoost (5);
45 const sal_Int32
MasterPageContainerQueue::snWaitForMoreRequestsPriorityThreshold (-10);
46 sal_uInt32
MasterPageContainerQueue::snWaitForMoreRequestsCount(15);
48 //===== MasterPageContainerQueue::PreviewCreationRequest ======================
50 class MasterPageContainerQueue::PreviewCreationRequest
53 PreviewCreationRequest (const SharedMasterPageDescriptor
& rpDescriptor
, int nPriority
)
54 : mpDescriptor(rpDescriptor
),
57 SharedMasterPageDescriptor mpDescriptor
;
59 class Compare
{public:
60 bool operator() (const PreviewCreationRequest
& r1
,const PreviewCreationRequest
& r2
)
62 if (r1
.mnPriority
!= r2
.mnPriority
)
64 // Prefer requests with higher priority.
65 return r1
.mnPriority
> r2
.mnPriority
;
69 // Prefer tokens that have been earlier created (those with lower
71 return r1
.mpDescriptor
->maToken
< r2
.mpDescriptor
->maToken
;
75 class CompareToken
{public:
76 MasterPageContainer::Token maToken
;
77 CompareToken(MasterPageContainer::Token aToken
) : maToken(aToken
) {}
78 bool operator() (const PreviewCreationRequest
& rRequest
)
79 { return maToken
==rRequest
.mpDescriptor
->maToken
; }
86 //===== MasterPageContainerQueue::RequestQueue ================================
88 class MasterPageContainerQueue::RequestQueue
89 : public ::std::set
<PreviewCreationRequest
,PreviewCreationRequest::Compare
>
92 RequestQueue (void) {}
98 //===== MasterPageContainerQueue ==============================================
100 MasterPageContainerQueue
* MasterPageContainerQueue::Create (
101 const ::boost::weak_ptr
<ContainerAdapter
>& rpContainer
)
103 MasterPageContainerQueue
* pQueue
= new MasterPageContainerQueue(rpContainer
);
111 MasterPageContainerQueue::MasterPageContainerQueue (
112 const ::boost::weak_ptr
<ContainerAdapter
>& rpContainer
)
113 : mpWeakContainer(rpContainer
),
114 mpRequestQueue(new RequestQueue()),
115 maDelayedPreviewCreationTimer(),
116 mnRequestsServedCount(0)
123 MasterPageContainerQueue::~MasterPageContainerQueue (void)
125 maDelayedPreviewCreationTimer
.Stop();
126 while ( ! mpRequestQueue
->empty())
127 mpRequestQueue
->erase(mpRequestQueue
->begin());
133 void MasterPageContainerQueue::LateInit (void)
135 // Set up the timer for the delayed creation of preview bitmaps.
136 maDelayedPreviewCreationTimer
.SetTimeout (snDelayedCreationTimeout
);
137 Link
aLink (LINK(this,MasterPageContainerQueue
,DelayedPreviewCreation
));
138 maDelayedPreviewCreationTimer
.SetTimeoutHdl(aLink
);
144 bool MasterPageContainerQueue::RequestPreview (const SharedMasterPageDescriptor
& rpDescriptor
)
146 bool bSuccess (false);
147 if (rpDescriptor
.get() != NULL
148 && rpDescriptor
->maLargePreview
.GetSizePixel().Width() == 0)
150 sal_Int32
nPriority (CalculatePriority(rpDescriptor
));
152 // Add a new or replace an existing request.
153 RequestQueue::iterator
iRequest (::std::find_if(
154 mpRequestQueue
->begin(),
155 mpRequestQueue
->end(),
156 PreviewCreationRequest::CompareToken(rpDescriptor
->maToken
)));
157 // When a request for the same token exists then the lowest of the
158 // two priorities is used.
159 if (HasRequest(rpDescriptor
->maToken
))
160 if (iRequest
->mnPriority
< nPriority
)
162 mpRequestQueue
->erase(iRequest
);
163 iRequest
= mpRequestQueue
->end();
166 // Add a new request when none exists (or has just been erased).
167 if (iRequest
== mpRequestQueue
->end())
169 mpRequestQueue
->insert(PreviewCreationRequest(rpDescriptor
,nPriority
));
170 maDelayedPreviewCreationTimer
.Start();
180 sal_Int32
MasterPageContainerQueue::CalculatePriority (
181 const SharedMasterPageDescriptor
& rpDescriptor
) const
185 // The cost is used as a starting value.
187 if (rpDescriptor
->mpPreviewProvider
.get() != NULL
)
189 nCost
= rpDescriptor
->mpPreviewProvider
->GetCostIndex();
190 if (rpDescriptor
->mpPreviewProvider
->NeedsPageObject())
191 if (rpDescriptor
->mpPageObjectProvider
.get() != NULL
)
192 nCost
+= rpDescriptor
->mpPageObjectProvider
->GetCostIndex();
195 // Its negative value is used so that requests with a low cost are
196 // preferred over those with high costs.
199 // Add a term that introduces an order based on the appearance in the
200 // AllMasterPagesSelector.
201 nPriority
-= rpDescriptor
->maToken
/ 3;
203 // Process requests for the CurrentMasterPagesSelector first.
204 if (rpDescriptor
->meOrigin
== MasterPageContainer::MASTERPAGE
)
205 nPriority
+= snMasterPagePriorityBoost
;
213 IMPL_LINK(MasterPageContainerQueue
, DelayedPreviewCreation
, Timer
*, pTimer
)
215 bool bIsShowingFullScreenShow (false);
216 bool bWaitForMoreRequests (false);
220 if (mpRequestQueue
->size() == 0)
223 // First check whether the system is idle.
224 sal_Int32
nIdleState (tools::IdleDetection::GetIdleState());
225 if (nIdleState
!= tools::IdleDetection::IDET_IDLE
)
227 if ((nIdleState
&tools::IdleDetection::IDET_FULL_SCREEN_SHOW_ACTIVE
) != 0)
228 bIsShowingFullScreenShow
= true;
232 PreviewCreationRequest
aRequest (*mpRequestQueue
->begin());
234 // Check if the request should really be processed right now.
235 // Reasons to not do it are when its cost is high and not many other
236 // requests have been inserted into the queue that would otherwise
237 // be processed first.
238 if (aRequest
.mnPriority
< snWaitForMoreRequestsPriorityThreshold
239 && (mnRequestsServedCount
+mpRequestQueue
->size() < snWaitForMoreRequestsCount
))
241 // Wait for more requests before this one is processed. Note
242 // that the queue processing is not started anew when this
243 // method is left. That is done when the next request is
245 bWaitForMoreRequests
= true;
249 mpRequestQueue
->erase(mpRequestQueue
->begin());
251 if (aRequest
.mpDescriptor
.get() != NULL
)
253 mnRequestsServedCount
+= 1;
254 if ( ! mpWeakContainer
.expired())
256 ::boost::shared_ptr
<ContainerAdapter
> pContainer (mpWeakContainer
);
257 if (pContainer
.get() != NULL
)
258 pContainer
->UpdateDescriptor(aRequest
.mpDescriptor
,false,true,true);
264 if (mpRequestQueue
->size() > 0 && ! bWaitForMoreRequests
)
266 int nTimeout (snDelayedCreationTimeout
);
267 if (bIsShowingFullScreenShow
)
268 nTimeout
= snDelayedCreationTimeoutWhenNotIdle
;
269 maDelayedPreviewCreationTimer
.SetTimeout(nTimeout
);
279 bool MasterPageContainerQueue::HasRequest (MasterPageContainer::Token aToken
) const
281 RequestQueue::iterator
iRequest (::std::find_if(
282 mpRequestQueue
->begin(),
283 mpRequestQueue
->end(),
284 PreviewCreationRequest::CompareToken(aToken
)));
285 return (iRequest
!= mpRequestQueue
->end());
291 bool MasterPageContainerQueue::IsEmpty (void) const
293 return mpRequestQueue
->empty();
299 void MasterPageContainerQueue::ProcessAllRequests (void)
301 snWaitForMoreRequestsCount
= 0;
302 if (mpRequestQueue
->size() > 0)
303 maDelayedPreviewCreationTimer
.Start();
307 } } } // end of namespace ::sd::toolpanel::controls