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: 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: 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; 67*02c50d82SAndre Fischer CompareToken(MasterPageContainer::Token aToken) : maToken(aToken) {} 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: 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 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 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 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 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 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 170*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 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 269*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 281*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 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