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 #include "precompiled_sd.hxx"
29 
30 #include "ResourceManager.hxx"
31 
32 #include "framework/FrameworkHelper.hxx"
33 #include "framework/ConfigurationController.hxx"
34 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
35 
36 #include <comphelper/stl_types.hxx>
37 #include <set>
38 
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::drawing::framework;
42 
43 using ::rtl::OUString;
44 using ::sd::framework::FrameworkHelper;
45 
46 namespace {
47     static const sal_Int32 ResourceActivationRequestEvent = 0;
48     static const sal_Int32 ResourceDeactivationRequestEvent = 1;
49 }
50 
51 
52 
53 
54 namespace sd { namespace framework {
55 
56 class ResourceManager::MainViewContainer
57     : public ::std::set<OUString, ::comphelper::UStringLess>
58 {
59 public:
60     MainViewContainer (void) {}
61 };
62 
63 
64 
65 
66 //===== ResourceManager =======================================================
67 
68 ResourceManager::ResourceManager (
69     const Reference<frame::XController>& rxController,
70     const Reference<XResourceId>& rxResourceId)
71     : ResourceManagerInterfaceBase(MutexOwner::maMutex),
72       mxConfigurationController(),
73       mpActiveMainViewContainer(new MainViewContainer()),
74       mxResourceId(rxResourceId),
75       mxMainViewAnchorId(FrameworkHelper::Instance(rxController)->CreateResourceId(
76           FrameworkHelper::msCenterPaneURL)),
77       msCurrentMainViewURL(),
78       mbIsEnabled(true)
79 {
80     Reference<XControllerManager> xControllerManager (rxController, UNO_QUERY);
81     if (xControllerManager.is())
82     {
83         mxConfigurationController = xControllerManager->getConfigurationController();
84 
85         if (mxConfigurationController.is())
86         {
87             mxConfigurationController->addConfigurationChangeListener(
88                 this,
89                 FrameworkHelper::msResourceActivationRequestEvent,
90                 makeAny(ResourceActivationRequestEvent));
91             mxConfigurationController->addConfigurationChangeListener(
92                 this,
93                 FrameworkHelper::msResourceDeactivationRequestEvent,
94                 makeAny(ResourceDeactivationRequestEvent));
95         }
96     }
97 }
98 
99 
100 
101 
102 ResourceManager::~ResourceManager (void)
103 {
104 }
105 
106 
107 
108 
109 void ResourceManager::AddActiveMainView (
110     const OUString& rsMainViewURL)
111 {
112     mpActiveMainViewContainer->insert(rsMainViewURL);
113 }
114 
115 
116 
117 
118 void SAL_CALL ResourceManager::disposing (void)
119 {
120     if (mxConfigurationController.is())
121     {
122         mxConfigurationController->removeConfigurationChangeListener(this);
123         mxConfigurationController = NULL;
124     }
125 }
126 
127 
128 
129 
130 void ResourceManager::Enable (void)
131 {
132     mbIsEnabled = true;
133     UpdateForMainViewShell();
134 }
135 
136 
137 
138 
139 void ResourceManager::Disable (void)
140 {
141     mbIsEnabled = false;
142     UpdateForMainViewShell();
143 }
144 
145 
146 
147 
148 void SAL_CALL ResourceManager::notifyConfigurationChange (
149     const ConfigurationChangeEvent& rEvent)
150     throw (RuntimeException)
151 {
152     OSL_ASSERT(rEvent.ResourceId.is());
153 
154     sal_Int32 nEventType = 0;
155     rEvent.UserData >>= nEventType;
156     switch (nEventType)
157     {
158         case ResourceActivationRequestEvent:
159             if (rEvent.ResourceId->isBoundToURL(
160                 FrameworkHelper::msCenterPaneURL,
161                 AnchorBindingMode_DIRECT))
162             {
163                 // A resource directly bound to the center pane has been
164                 // requested.
165                 if (rEvent.ResourceId->getResourceTypePrefix().equals(
166                     FrameworkHelper::msViewURLPrefix))
167                 {
168                     // The requested resource is a view.  Show or hide the
169                     // resource managed by this ResourceManager accordingly.
170                     HandleMainViewSwitch(
171                         rEvent.ResourceId->getResourceURL(),
172                         rEvent.Configuration,
173                         true);
174                 }
175             }
176             else if (rEvent.ResourceId->compareTo(mxResourceId) == 0)
177             {
178                 // The resource managed by this ResourceManager has been
179                 // explicitly been requested (maybe by us).  Remember this
180                 // setting.
181                 HandleResourceRequest(true, rEvent.Configuration);
182             }
183             break;
184 
185         case ResourceDeactivationRequestEvent:
186             if (rEvent.ResourceId->compareTo(mxMainViewAnchorId) == 0)
187             {
188                 HandleMainViewSwitch(
189                     OUString(),
190                     rEvent.Configuration,
191                     false);
192             }
193             else if (rEvent.ResourceId->compareTo(mxResourceId) == 0)
194             {
195                 // The resource managed by this ResourceManager has been
196                 // explicitly been requested to be hidden (maybe by us).
197                 // Remember this setting.
198                 HandleResourceRequest(false, rEvent.Configuration);
199             }
200             break;
201     }
202 }
203 
204 
205 
206 
207 void ResourceManager::UpdateForMainViewShell (void)
208 {
209     if (mxConfigurationController.is())
210     {
211         ConfigurationController::Lock aLock (mxConfigurationController);
212 
213         if (mbIsEnabled
214             && mpActiveMainViewContainer->find(msCurrentMainViewURL)
215                != mpActiveMainViewContainer->end())
216         {
217             // Activate resource.
218             mxConfigurationController->requestResourceActivation(
219                 mxResourceId->getAnchor(),
220                 ResourceActivationMode_ADD);
221             mxConfigurationController->requestResourceActivation(
222                 mxResourceId,
223                 ResourceActivationMode_REPLACE);
224         }
225         else
226         {
227             mxConfigurationController->requestResourceDeactivation(mxResourceId);
228         }
229     }
230 }
231 
232 
233 
234 
235 void ResourceManager::HandleMainViewSwitch (
236     const OUString& rsViewURL,
237     const Reference<XConfiguration>& rxConfiguration,
238     const bool bIsActivated)
239 {
240     (void)rxConfiguration;
241     if (bIsActivated)
242         msCurrentMainViewURL = rsViewURL;
243     else
244         msCurrentMainViewURL = OUString();
245     UpdateForMainViewShell();
246 }
247 
248 
249 
250 
251 void ResourceManager::HandleResourceRequest(
252     bool bActivation,
253     const Reference<XConfiguration>& rxConfiguration)
254 {
255     if (mbIsEnabled)
256     {
257         Sequence<Reference<XResourceId> > aCenterViews = rxConfiguration->getResources(
258             FrameworkHelper::CreateResourceId(FrameworkHelper::msCenterPaneURL),
259             FrameworkHelper::msViewURLPrefix,
260             AnchorBindingMode_DIRECT);
261         if (aCenterViews.getLength() == 1)
262         {
263             if (bActivation)
264             {
265                 mpActiveMainViewContainer->insert(aCenterViews[0]->getResourceURL());
266             }
267             else
268             {
269                 MainViewContainer::iterator iElement (
270                     mpActiveMainViewContainer->find(aCenterViews[0]->getResourceURL()));
271                 if (iElement != mpActiveMainViewContainer->end())
272                     mpActiveMainViewContainer->erase(iElement);
273             }
274         }
275     }
276 }
277 
278 
279 
280 
281 void SAL_CALL ResourceManager::disposing (
282     const lang::EventObject& rEvent)
283     throw (RuntimeException)
284 {
285     if (mxConfigurationController.is()
286         && rEvent.Source == mxConfigurationController)
287     {
288         // Without the configuration controller this class can do nothing.
289         mxConfigurationController = NULL;
290         dispose();
291     }
292 }
293 
294 } } // end of namespace sd::framework
295