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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 
27 #include "tools/SlotStateListener.hxx"
28 #include <com/sun/star/frame/XStatusListener.hpp>
29 #include <com/sun/star/frame/XDispatchProvider.hpp>
30 #ifndef _COM_SUN_STAR_FRAME_XDISPATCHP_HPP_
31 #include <com/sun/star/frame/XDispatch.hpp>
32 #endif
33 #include <com/sun/star/util/XURLTransformer.hpp>
34 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
35 
36 #include <comphelper/processfactory.hxx>
37 
38 using namespace ::com::sun::star;
39 using namespace ::rtl;
40 
41 namespace sd { namespace tools {
42 
43 
SlotStateListener(Link & rCallback,const uno::Reference<frame::XDispatchProvider> & rxDispatchProvider,const::rtl::OUString & rSlotName)44 SlotStateListener::SlotStateListener (
45     Link& rCallback,
46     const uno::Reference<frame::XDispatchProvider>& rxDispatchProvider,
47     const ::rtl::OUString& rSlotName)
48     : SlotStateListenerInterfaceBase(maMutex),
49       maCallback(),
50       mxDispatchProviderWeak(NULL)
51 {
52     SetCallback(rCallback);
53     ConnectToDispatchProvider(rxDispatchProvider);
54     ObserveSlot(rSlotName);
55 }
56 
57 
58 
59 
~SlotStateListener(void)60 SlotStateListener::~SlotStateListener (void)
61 {
62     ReleaseListeners();
63 }
64 
65 
66 
67 
SetCallback(const Link & rCallback)68 void SlotStateListener::SetCallback (const Link& rCallback)
69 {
70     ThrowIfDisposed();
71 
72     maCallback = rCallback;
73 }
74 
75 
76 
77 
ConnectToDispatchProvider(const uno::Reference<frame::XDispatchProvider> & rxDispatchProvider)78 void SlotStateListener::ConnectToDispatchProvider (
79     const uno::Reference<frame::XDispatchProvider>& rxDispatchProvider)
80 {
81     ThrowIfDisposed();
82 
83     // When we are listening to state changes of slots of another frame then
84     // release these listeners first.
85     if ( ! maRegisteredURLList.empty())
86         ReleaseListeners();
87 
88     mxDispatchProviderWeak = rxDispatchProvider;
89 }
90 
91 
92 
93 
ObserveSlot(const::rtl::OUString & rSlotName)94 void SlotStateListener::ObserveSlot (const ::rtl::OUString& rSlotName)
95 {
96     ThrowIfDisposed();
97 
98     if (maCallback.IsSet())
99     {
100         // Connect the state change listener.
101         util::URL aURL (MakeURL(rSlotName));
102         uno::Reference<frame::XDispatch> xDispatch (GetDispatch(aURL));
103         if (xDispatch.is())
104         {
105             maRegisteredURLList.push_back(aURL);
106             xDispatch->addStatusListener(this,aURL);
107         }
108     }
109 }
110 
111 
112 
113 
disposing(void)114 void SlotStateListener::disposing (void)
115 {
116     ReleaseListeners();
117     mxDispatchProviderWeak = uno::WeakReference<frame::XDispatchProvider>(NULL);
118     maCallback = Link();
119 }
120 
121 
122 
123 
MakeURL(const OUString & rSlotName) const124 util::URL SlotStateListener::MakeURL (const OUString& rSlotName) const
125 {
126     util::URL aURL;
127 
128     aURL.Complete = rSlotName;
129 
130     uno::Reference<lang::XMultiServiceFactory> xServiceManager (
131         ::comphelper::getProcessServiceFactory());
132 	if (xServiceManager.is())
133     {
134         uno::Reference<util::XURLTransformer> xTransformer(xServiceManager->createInstance(
135             OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))),
136             uno::UNO_QUERY);
137         if (xTransformer.is())
138             xTransformer->parseStrict(aURL);
139     }
140 
141     return aURL;
142 }
143 
144 
145 
146 
147 uno::Reference<frame::XDispatch>
GetDispatch(const util::URL & rURL) const148     SlotStateListener::GetDispatch (const util::URL& rURL) const
149 {
150     uno::Reference<frame::XDispatch> xDispatch;
151 
152     uno::Reference<frame::XDispatchProvider> xDispatchProvider (mxDispatchProviderWeak);
153     if (xDispatchProvider.is())
154         xDispatch = xDispatchProvider->queryDispatch(rURL, OUString(), 0);
155 
156     return xDispatch;
157 }
158 
159 
160 
161 
statusChanged(const frame::FeatureStateEvent & rState)162 void SlotStateListener::statusChanged (
163     const frame::FeatureStateEvent& rState)
164     throw (uno::RuntimeException)
165 {
166     ThrowIfDisposed();
167     OUString sSlotName (rState.FeatureURL.Complete);
168     if (maCallback.IsSet())
169         maCallback.Call(&sSlotName);
170 }
171 
172 
173 
174 
ReleaseListeners(void)175 void SlotStateListener::ReleaseListeners (void)
176 {
177     if ( ! maRegisteredURLList.empty())
178     {
179         RegisteredURLList::iterator iURL (maRegisteredURLList.begin());
180         RegisteredURLList::iterator iEnd (maRegisteredURLList.end());
181         for (; iURL!=iEnd; ++iURL)
182         {
183             uno::Reference<frame::XDispatch> xDispatch (GetDispatch(*iURL));
184             if (xDispatch.is())
185             {
186                 xDispatch->removeStatusListener(this,*iURL);
187             }
188         }
189     }
190 }
191 
192 
193 
194 
195 //=====  lang::XEventListener  ================================================
196 
disposing(const lang::EventObject &)197 void SAL_CALL SlotStateListener::disposing (
198     const lang::EventObject& )
199     throw (uno::RuntimeException)
200 {
201 }
202 
203 
204 
205 
ThrowIfDisposed(void)206 void SlotStateListener::ThrowIfDisposed (void)
207     throw (lang::DisposedException)
208 {
209 	if (rBHelper.bDisposed || rBHelper.bInDispose)
210 	{
211         throw lang::DisposedException (
212             OUString(RTL_CONSTASCII_USTRINGPARAM(
213                 "SlideSorterController object has already been disposed")),
214             static_cast<uno::XWeak*>(this));
215     }
216 }
217 
218 
219 
220 
221 } } // end of namespace ::sd::tools
222