1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #pragma once 21 22 #include <com/sun/star/uno/Reference.hxx> 23 #include <vcl/timer.hxx> 24 #include <memory> 25 #include <vector> 26 27 namespace com::sun::star::drawing::framework 28 { 29 class XConfiguration; 30 } 31 namespace com::sun::star::drawing::framework 32 { 33 class XControllerManager; 34 } 35 namespace com::sun::star::drawing::framework 36 { 37 class XResourceId; 38 } 39 40 namespace sd::framework 41 { 42 class ConfigurationClassifier; 43 class ConfigurationUpdaterLock; 44 class ConfigurationControllerResourceManager; 45 class ConfigurationControllerBroadcaster; 46 47 /** This is a helper class for the ConfigurationController. It handles the 48 update of the current configuration so that it looks like a requested 49 configuration. An update is made by activating or deactivating drawing 50 framework resources. 51 52 When an update is not successful, i.e. after the update the current 53 configuration is not equivalent to the requested configuration, then a 54 timer is started to repeat the update after a short time. 55 */ 56 class ConfigurationUpdater 57 { 58 public: 59 /** Create a new ConfigurationUpdater object that notifies configuration 60 changes and the start and end of updates via the given broadcaster. 61 */ 62 ConfigurationUpdater( 63 const std::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster, 64 const std::shared_ptr<ConfigurationControllerResourceManager>& rpResourceManager, 65 const css::uno::Reference<css::drawing::framework::XControllerManager>& 66 rxControllerManager); 67 ~ConfigurationUpdater(); 68 69 /** Request an update of the current configuration so that it looks like 70 the given requested configuration. It checks whether an update of 71 the current configuration can be done. Calls UpdateConfiguration() 72 if that is the case. Otherwise it schedules a later call to 73 UpdateConfiguration(). 74 */ 75 void RequestUpdate(const css::uno::Reference<css::drawing::framework::XConfiguration>& 76 rxRequestedConfiguration); 77 78 const css::uno::Reference<css::drawing::framework::XConfiguration>& GetCurrentConfiguration() const79 GetCurrentConfiguration() const 80 { 81 return mxCurrentConfiguration; 82 } 83 84 friend class ConfigurationUpdaterLock; 85 /** Return a lock of the called ConfigurationUpdater. While the 86 returned object exists no update of the current configuration is 87 made. 88 */ 89 std::shared_ptr<ConfigurationUpdaterLock> GetLock(); 90 91 private: 92 /** A reference to the XControllerManager is kept so that 93 UpdateConfiguration() has access to the other sub controllers. 94 */ 95 css::uno::Reference<css::drawing::framework::XControllerManager> mxControllerManager; 96 97 std::shared_ptr<ConfigurationControllerBroadcaster> mpBroadcaster; 98 99 /** The current configuration holds the resources that are currently 100 active. It is modified during an update. 101 */ 102 css::uno::Reference<css::drawing::framework::XConfiguration> mxCurrentConfiguration; 103 104 /** The requested configuration holds the resources that have been 105 requested to activate or to deactivate since the last update. It is 106 (usually) not modified during an update. This configuration is 107 maintained by the ConfigurationController and given to the 108 ConfigurationUpdater in the RequestUpdate() method. 109 */ 110 css::uno::Reference<css::drawing::framework::XConfiguration> mxRequestedConfiguration; 111 112 /** This flag is set to </sal_True> when an update of the current 113 configuration was requested (because the last request in the queue 114 was processed) but could not be executed because the 115 ConfigurationController was locked. A call to UpdateConfiguration() 116 resets the flag to </sal_False>. 117 */ 118 bool mbUpdatePending; 119 120 /** This flag is set to </sal_True> while the UpdateConfiguration() method 121 is running. It is used to prevent reentrance problems with this 122 method. 123 */ 124 bool mbUpdateBeingProcessed; 125 126 /** The ConfigurationController is locked when this count has a value 127 larger then zero. If the controller is locked then updates of the 128 current configuration are not made. 129 */ 130 sal_Int32 mnLockCount; 131 132 /** This timer is used to check from time to time whether the requested 133 configuration and the current configuration are identical and request 134 an update when they are not. 135 This is used to overcome problems with resources that become 136 available asynchronously. 137 */ 138 Timer maUpdateTimer; 139 140 /** The number of failed updates (those after which the current 141 configuration is not equivalent to the requested configuration) is 142 used to determine how long to wait before another update is made. 143 */ 144 sal_Int32 mnFailedUpdateCount; 145 146 std::shared_ptr<ConfigurationControllerResourceManager> mpResourceManager; 147 148 /** This method does the main work of an update. It calls the sub 149 controllers that are responsible for the various types of resources 150 and tells them to update their active resources. It notifies 151 listeners about the start and end of the configuration update. 152 */ 153 void UpdateConfiguration(); 154 155 /** Basically calls UpdaterStart() andUpdateEnd() and makes some debug 156 output. 157 */ 158 void UpdateCore(const ConfigurationClassifier& rClassifier); 159 160 /** Check for all pure anchors if they have at least one child. 161 Childless pure anchors are deactivated. 162 This affects only the current configuration. 163 */ 164 void CheckPureAnchors( 165 const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration, 166 ::std::vector<css::uno::Reference<css::drawing::framework::XResourceId>>& 167 rResourcesToDeactivate); 168 169 /** Remove from the requested configuration all pure anchors that have no 170 child. Requested but not yet activated anchors can not be removed 171 because without the actual resource the 'pureness' of an anchor can 172 not be determined. 173 */ 174 void CleanRequestedConfiguration(); 175 176 /** Check the success of a recently executed configuration update. 177 When the update failed then start the timer. 178 */ 179 void CheckUpdateSuccess(); 180 181 /** This method sets the mbUpdateBeingProcessed member that is used to 182 prevent reentrance problems. This method allows function objects 183 easily and safely to modify the variable. 184 */ 185 void SetUpdateBeingProcessed(bool bValue); 186 187 /** Return whether it is possible to do an update of the configuration. 188 This takes into account whether another update is currently being 189 executed, the lock count, and whether the configuration controller 190 is still valid. 191 */ 192 bool IsUpdatePossible() const; 193 194 /** Lock updates of the current configuration. For intermediate requests 195 for updates mbUpdatePending is set to <TRUE/>. 196 */ 197 void LockUpdates(); 198 199 /** When an update was requested since the last LockUpdates() call then 200 RequestUpdate() is called. 201 */ 202 void UnlockUpdates(); 203 204 DECL_LINK(TimeoutHandler, Timer*, void); 205 }; 206 207 } // end of namespace sd::framework 208 209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 210