1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "precompiled_sd.hxx"
25
26 #include "ReadOnlyModeObserver.hxx"
27
28 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
29 #include <com/sun/star/lang/DisposedException.hpp>
30 #include <com/sun/star/util/XURLTransformer.hpp>
31 #include <comphelper/processfactory.hxx>
32 #include <cppuhelper/interfacecontainer.hxx>
33
34 #include "tools/SlotStateListener.hxx"
35 #include "framework/FrameworkHelper.hxx"
36
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::drawing::framework;
40 using ::rtl::OUString;
41
42 namespace sd { namespace framework {
43
44 class ReadOnlyModeObserver::ModifyBroadcaster
45 : public ::cppu::OBroadcastHelper
46 {
47 public:
ModifyBroadcaster(::osl::Mutex & rOslMutex)48 explicit ModifyBroadcaster (::osl::Mutex& rOslMutex) : ::cppu::OBroadcastHelper(rOslMutex) {}
49 };
50
51
52
53
ReadOnlyModeObserver(const Reference<frame::XController> & rxController)54 ReadOnlyModeObserver::ReadOnlyModeObserver (
55 const Reference<frame::XController>& rxController)
56 : ReadOnlyModeObserverInterfaceBase(maMutex),
57 maSlotNameURL(),
58 mxController(rxController),
59 mxConfigurationController(NULL),
60 mxDispatch(NULL),
61 mpBroadcaster(new ModifyBroadcaster(maMutex))
62 {
63 // Create a URL object for the slot name.
64 maSlotNameURL.Complete = OUString::createFromAscii(".uno:EditDoc");
65 uno::Reference<lang::XMultiServiceFactory> xServiceManager (
66 ::comphelper::getProcessServiceFactory());
67 if (xServiceManager.is())
68 {
69 Reference<util::XURLTransformer> xTransformer(xServiceManager->createInstance(
70 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))),
71 UNO_QUERY);
72 if (xTransformer.is())
73 xTransformer->parseStrict(maSlotNameURL);
74 }
75
76 if ( ! ConnectToDispatch())
77 {
78 // The controller is not yet connected to a frame. This means that
79 // the dispatcher is not yet set up. We wait for this to happen by
80 // waiting for configuration updates and try again.
81 Reference<XControllerManager> xControllerManager (rxController, UNO_QUERY);
82 if (xControllerManager.is())
83 {
84 mxConfigurationController = xControllerManager->getConfigurationController();
85 if (mxConfigurationController.is())
86 {
87 mxConfigurationController->addConfigurationChangeListener(
88 this,
89 FrameworkHelper::msConfigurationUpdateStartEvent,
90 Any());
91 }
92 }
93 }
94 }
95
96
97
98
~ReadOnlyModeObserver(void)99 ReadOnlyModeObserver::~ReadOnlyModeObserver (void)
100 {
101 }
102
103
104
105
disposing(void)106 void SAL_CALL ReadOnlyModeObserver::disposing (void)
107 {
108 if (mxController.is())
109 {
110 mxController = NULL;
111 }
112 if (mxConfigurationController.is())
113 {
114 mxConfigurationController->removeConfigurationChangeListener(this);
115 mxConfigurationController = NULL;
116 }
117 if (mxDispatch.is())
118 {
119 mxDispatch->removeStatusListener(this, maSlotNameURL);
120 mxDispatch = NULL;
121 }
122
123 lang::EventObject aEvent;
124 aEvent.Source = static_cast<XWeak*>(this);
125 ::cppu::OInterfaceContainerHelper* pIterator
126 = mpBroadcaster->getContainer(getCppuType((Reference<frame::XStatusListener>*)NULL));
127 pIterator->disposeAndClear(aEvent);
128 }
129
130
131
132
AddStatusListener(const Reference<frame::XStatusListener> & rxListener)133 void ReadOnlyModeObserver::AddStatusListener (
134 const Reference<frame::XStatusListener>& rxListener)
135 {
136 mpBroadcaster->addListener(
137 getCppuType((Reference<frame::XStatusListener>*)NULL),
138 rxListener);
139 }
140
141
142
143
ConnectToDispatch(void)144 bool ReadOnlyModeObserver::ConnectToDispatch (void)
145 {
146 if ( ! mxDispatch.is())
147 {
148 // Get the dispatch object.
149 Reference<frame::XDispatchProvider> xProvider (mxController->getFrame(), UNO_QUERY);
150 if (xProvider.is())
151 {
152 mxDispatch = xProvider->queryDispatch(maSlotNameURL, OUString(), 0);
153 if (mxDispatch.is())
154 {
155 mxDispatch->addStatusListener(this, maSlotNameURL);
156 }
157 }
158 }
159
160 return mxDispatch.is();
161 }
162
163
164
165
statusChanged(const frame::FeatureStateEvent & rEvent)166 void ReadOnlyModeObserver::statusChanged (const frame::FeatureStateEvent& rEvent)
167 throw (RuntimeException)
168 {
169 ::cppu::OInterfaceContainerHelper* pIterator
170 = mpBroadcaster->getContainer(getCppuType((Reference<frame::XStatusListener>*)NULL));
171 if (pIterator != NULL)
172 {
173 pIterator->notifyEach(&frame::XStatusListener::statusChanged, rEvent);
174 }
175 }
176
177
178
179
180 //----- XEventListener --------------------------------------------------------
181
disposing(const lang::EventObject & rEvent)182 void SAL_CALL ReadOnlyModeObserver::disposing (
183 const lang::EventObject& rEvent)
184 throw (RuntimeException)
185 {
186 if (rEvent.Source == mxConfigurationController)
187 mxConfigurationController = NULL;
188 else if (rEvent.Source == mxDispatch)
189 mxDispatch = NULL;
190
191 dispose();
192 }
193
194
195
196
notifyConfigurationChange(const ConfigurationChangeEvent & rEvent)197 void SAL_CALL ReadOnlyModeObserver::notifyConfigurationChange (
198 const ConfigurationChangeEvent& rEvent)
199 throw (RuntimeException)
200 {
201 if (rEvent.Type.equals(FrameworkHelper::msConfigurationUpdateStartEvent))
202 {
203 if (mxController.is() && mxController->getFrame().is())
204 {
205 if (ConnectToDispatch())
206 {
207 // We have connected successfully to the dispatcher and
208 // therefore can disconnect from the configuration controller.
209 mxConfigurationController->removeConfigurationChangeListener(this);
210 mxConfigurationController = NULL;
211 }
212 }
213 }
214 }
215
216 } } // end of namespace sd::framework
217