1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef SD_FRAMEWORK_CONFIGURATION_UPDATER_HXX
29 #define SD_FRAMEWORK_CONFIGURATION_UPDATER_HXX
30 
31 #include "ConfigurationControllerResourceManager.hxx"
32 #include <com/sun/star/drawing/framework/XResourceId.hpp>
33 #include <com/sun/star/drawing/framework/XConfiguration.hpp>
34 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
35 #include <vcl/timer.hxx>
36 #include <vector>
37 #include <boost/shared_ptr.hpp>
38 
39 namespace css = ::com::sun::star;
40 
41 namespace sd { namespace framework {
42 
43 class ConfigurationClassifier;
44 class ConfigurationUpdaterLock;
45 
46 /** This is a helper class for the ConfigurationController.  It handles the
47     update of the current configuration so that it looks like a requested
48     configuration.  An update is made by activating or deactivating drawing
49     framework resources.
50 
51     When an update is not successfull, i.e. after the update the current
52     configuration is not equivalent to the requested configuration, then a
53     timer is started to repeat the update after a short time.
54 */
55 class ConfigurationUpdater
56 {
57 public:
58     /** Create a new ConfigurationUpdater object that notifies configuration
59         changes and the start and end of updates via the given broadcaster.
60     */
61     ConfigurationUpdater (
62         const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster,
63         const ::boost::shared_ptr<ConfigurationControllerResourceManager>& rpResourceManager,
64         const css::uno::Reference<
65             css::drawing::framework::XControllerManager>& rxControllerManager);
66     ~ConfigurationUpdater (void);
67 
68     /** This method is typically called once, when the controller manager is
69         accessible to the caller.
70     */
71     void SetControllerManager(
72         const css::uno::Reference<
73             css::drawing::framework::XControllerManager>& rxControllerManager);
74 
75     /** Request an update of the current configuration so that it looks like
76         the given requested configuration.  It checks whether an update of
77         the current configuration can be done.  Calls UpdateConfiguration()
78         if that is the case.  Otherwise it schedules a later call to
79         UpdateConfiguration().
80     */
81     void RequestUpdate (const css::uno::Reference<
82         css::drawing::framework::XConfiguration>& rxRequestedConfiguration);
83 
84     css::uno::Reference<
85         css::drawing::framework::XConfiguration> GetCurrentConfiguration (void) const;
86 
87     friend class ConfigurationUpdaterLock;
88     /** Return a lock of the called ConfigurationUpdater.  While the
89         returned object exists no update of the current configuration is
90         made.
91     */
92     ::boost::shared_ptr<ConfigurationUpdaterLock> GetLock (void);
93 
94 private:
95     /** A reference to the XControllerManager is kept so that
96         UpdateConfiguration() has access to the other sub controllers.
97     */
98     css::uno::Reference<
99         css::drawing::framework::XControllerManager> mxControllerManager;
100 
101     ::boost::shared_ptr<ConfigurationControllerBroadcaster> mpBroadcaster;
102 
103     /** The current configuration holds the resources that are currently
104         active.  It is modified during an update.
105     */
106     css::uno::Reference<
107         css::drawing::framework::XConfiguration> mxCurrentConfiguration;
108 
109     /** The requested configuration holds the resources that have been
110         requested to activate or to deactivate since the last update.  It is
111         (usually) not modified during an update.  This configuration is
112         maintained by the ConfigurationController and given to the
113         ConfigurationUpdater in the RequestUpdate() method.
114     */
115     css::uno::Reference<
116         css::drawing::framework::XConfiguration> mxRequestedConfiguration;
117 
118     /** This flag is set to </sal_True> when an update of the current
119         configurtion was requested (because the last request in the queue
120         was processed) but could not be exected because the
121         ConfigurationController was locked.  A call to UpdateConfiguration()
122         resets the flag to </sal_False>.
123     */
124     bool mbUpdatePending;
125 
126     /** This flag is set to </sal_True> while the UpdateConfiguration() method
127         is running.  It is used to prevent reentrance problems with this
128         method.
129     */
130     bool mbUpdateBeingProcessed;
131 
132     /** The ConfigurationController is locked when this count has a value
133         larger then zero.  If the controller is locked then updates of the
134         current configuration are not made.
135     */
136     sal_Int32 mnLockCount;
137 
138     /** This timer is used to check from time to time whether the requested
139         configuration and the current configuration are identcal and request
140         an update when they are not.
141         This is used to overcome problems with resources that become
142         available asynchronously.
143     */
144     Timer maUpdateTimer;
145 
146     /** The number of failed updates (those after which the current
147         configuration is not equivalent to the requested configuration) is
148         used to determine how long to wait before another update is made.
149     */
150     sal_Int32 mnFailedUpdateCount;
151 
152     ::boost::shared_ptr<ConfigurationControllerResourceManager> mpResourceManager;
153 
154     /** This method does the main work of an update.  It calls the sub
155         controllers that are responsible for the various types of resources
156         and tells them to update their active resources.  It notifies
157         listeners about the start and end of the configuration update.
158     */
159     void UpdateConfiguration (void);
160 
161     /** Basically calls UpdaterStart() andUpdateEnd() and makes some debug
162         output.
163     */
164     void UpdateCore (const ConfigurationClassifier& rClassifier);
165 
166     /** Check for all pure anchors if they have at least one child.
167         Childless pure anchors are deactivated.
168         This affects only the current configuration.
169     */
170     void CheckPureAnchors (
171         const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration,
172         ::std::vector<css::uno::Reference<css::drawing::framework::XResourceId> >&
173             rResourcesToDeactivate);
174 
175     /** Remove from the requested configration all pure anchors that have no
176         child.  Requested but not yet activated anchors can not be removed
177         because without the actual resource the 'pureness' of an anchor can
178         not be determined.
179     */
180     void CleanRequestedConfiguration (void);
181 
182     /** Check the success of a recently executed configuration update.
183         When the update failed then start the timer.
184     */
185     void CheckUpdateSuccess (void);
186 
187     /** This method sets the mbUpdateBeingProcessed member that is used to
188         prevent reentrance problems.  This method allows function objects
189         easyly and safely to modify the variable.
190     */
191     void SetUpdateBeingProcessed (bool bValue);
192 
193     /** Return whether it is possible to do an update of the configuration.
194         This takes into account whether another update is currently being
195         executed, the lock count, and whether the configuration controller
196         is still valid.
197     */
198     bool IsUpdatePossible (void);
199 
200     /** Lock updates of the current configuration.  For intermediate requests
201         for updates mbUpdatePending is set to <TRUE/>.
202     */
203     void LockUpdates (void);
204 
205     /** When an update was requested since the last LockUpdates() call then
206         RequestUpdate() is called.
207     */
208     void UnlockUpdates (void);
209 
210     DECL_LINK(TimeoutHandler, Timer*);
211 };
212 
213 } } // end of namespace sd::framework
214 
215 #endif
216