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_sfx2.hxx"
26 #include <sfx2/sfxstatuslistener.hxx>
27 #include <svl/poolitem.hxx>
28 #include <svl/eitem.hxx>
29 #include <svl/stritem.hxx>
30 #include <svl/intitem.hxx>
31 #include <svl/itemset.hxx>
32 #include <svtools/itemdel.hxx>
33 #include <svl/visitem.hxx>
34 #include <cppuhelper/weak.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <vos/mutex.hxx>
37 #include <vcl/svapp.hxx>
38 #include <com/sun/star/util/XURLTransformer.hpp>
39 #include <com/sun/star/lang/XUnoTunnel.hpp>
40 #include <com/sun/star/frame/status/ItemStatus.hpp>
41 #include <com/sun/star/frame/status/ItemState.hpp>
42 #include <com/sun/star/frame/status/Visibility.hpp>
43
44 #include <sfx2/viewfrm.hxx>
45 #include <sfx2/dispatch.hxx>
46 #include <sfx2/unoctitm.hxx>
47 #include <sfx2/msgpool.hxx>
48
49 using ::rtl::OUString;
50 using namespace ::cppu;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::frame;
53 using namespace ::com::sun::star::frame::status;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::util;
56
SFX_IMPL_XINTERFACE_3(SfxStatusListener,OWeakObject,::com::sun::star::lang::XComponent,::com::sun::star::frame::XStatusListener,::com::sun::star::lang::XEventListener)57 SFX_IMPL_XINTERFACE_3( SfxStatusListener, OWeakObject, ::com::sun::star::lang::XComponent, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
58 SFX_IMPL_XTYPEPROVIDER_3( SfxStatusListener, ::com::sun::star::lang::XComponent, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
59
60 SfxStatusListener::SfxStatusListener( const Reference< XDispatchProvider >& rDispatchProvider, sal_uInt16 nSlotId, const OUString& rCommand ) :
61 cppu::OWeakObject(),
62 m_nSlotID( nSlotId ),
63 m_xDispatchProvider( rDispatchProvider )
64 {
65 m_aCommand.Complete = rCommand;
66 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
67 rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
68 xTrans->parseStrict( m_aCommand );
69 if ( rDispatchProvider.is() )
70 m_xDispatch = rDispatchProvider->queryDispatch( m_aCommand, rtl::OUString(), 0 );
71 }
72
~SfxStatusListener()73 SfxStatusListener::~SfxStatusListener()
74 {
75 }
76
77 // old sfx controller item C++ API
StateChanged(sal_uInt16,SfxItemState,const SfxPoolItem *)78 void SfxStatusListener::StateChanged( sal_uInt16, SfxItemState, const SfxPoolItem* )
79 {
80 // must be implemented by sub class
81 }
82
Bind()83 void SfxStatusListener::Bind()
84 {
85 if ( !m_xDispatch.is() && m_xDispatchProvider.is() )
86 {
87 m_xDispatch = m_xDispatchProvider->queryDispatch( m_aCommand, rtl::OUString(), 0 );
88 try
89 {
90 Reference< XStatusListener > aStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
91 m_xDispatch->addStatusListener( aStatusListener, m_aCommand );
92 }
93 catch( Exception& )
94 {
95 }
96 }
97 }
98
Bind(sal_uInt16 nSlotId,const rtl::OUString & rNewCommand)99 void SfxStatusListener::Bind( sal_uInt16 nSlotId, const rtl::OUString& rNewCommand )
100 {
101 // first remove old listener, if we have a dispatch object
102 Reference< XStatusListener > aStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
103 if ( m_xDispatch.is() )
104 m_xDispatch->removeStatusListener( aStatusListener, m_aCommand );
105 if ( m_xDispatchProvider.is() )
106 {
107 // Store new command data and query for new dispatch
108 m_nSlotID = nSlotId;
109 m_aCommand.Complete = rNewCommand;
110 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
111 rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
112 xTrans->parseStrict( m_aCommand );
113
114 m_xDispatch = m_xDispatchProvider->queryDispatch( m_aCommand, rtl::OUString(), 0 );
115
116 try
117 {
118 m_xDispatch->addStatusListener( aStatusListener, m_aCommand );
119 }
120 catch( Exception& )
121 {
122 }
123 }
124 }
125
UnBind()126 void SfxStatusListener::UnBind()
127 {
128 if ( m_xDispatch.is() )
129 {
130 Reference< XStatusListener > aStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
131 m_xDispatch->removeStatusListener( aStatusListener, m_aCommand );
132 m_xDispatch.clear();
133 }
134 }
135
ReBind()136 void SfxStatusListener::ReBind()
137 {
138 Reference< XStatusListener > aStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
139 if ( m_xDispatch.is() )
140 m_xDispatch->removeStatusListener( aStatusListener, m_aCommand );
141 if ( m_xDispatchProvider.is() )
142 {
143 try
144 {
145 m_xDispatch = m_xDispatchProvider->queryDispatch( m_aCommand, rtl::OUString(), 0 );
146 if ( m_xDispatch.is() )
147 m_xDispatch->addStatusListener( aStatusListener, m_aCommand );
148 }
149 catch( Exception& )
150 {
151 }
152 }
153 }
154
155 // new UNO API
dispose()156 void SAL_CALL SfxStatusListener::dispose() throw( ::com::sun::star::uno::RuntimeException )
157 {
158 if ( m_xDispatch.is() && m_aCommand.Complete.getLength() > 0 )
159 {
160 try
161 {
162 Reference< XStatusListener > aStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
163 m_xDispatch->removeStatusListener( aStatusListener, m_aCommand );
164 }
165 catch ( Exception& )
166 {
167 }
168 }
169
170 m_xDispatch.clear();
171 m_xDispatchProvider.clear();
172 }
173
addEventListener(const Reference<XEventListener> &)174 void SAL_CALL SfxStatusListener::addEventListener( const Reference< XEventListener >& )
175 throw ( RuntimeException )
176 {
177 // do nothing - this is a wrapper class which does not support listeners
178 }
179
removeEventListener(const Reference<XEventListener> &)180 void SAL_CALL SfxStatusListener::removeEventListener( const Reference< XEventListener >& )
181 throw ( RuntimeException )
182 {
183 // do nothing - this is a wrapper class which does not support listeners
184 }
185
disposing(const EventObject & Source)186 void SAL_CALL SfxStatusListener::disposing( const EventObject& Source )
187 throw( RuntimeException )
188 {
189 ::vos::OGuard aGuard( Application::GetSolarMutex() );
190
191 if ( Source.Source == Reference< XInterface >( m_xDispatch, UNO_QUERY ))
192 m_xDispatch.clear();
193 else if ( Source.Source == Reference< XInterface >( m_xDispatchProvider, UNO_QUERY ))
194 m_xDispatchProvider.clear();
195 }
196
statusChanged(const FeatureStateEvent & rEvent)197 void SAL_CALL SfxStatusListener::statusChanged( const FeatureStateEvent& rEvent)
198 throw( RuntimeException )
199 {
200 ::vos::OGuard aGuard( Application::GetSolarMutex() );
201
202 SfxViewFrame* pViewFrame = NULL;
203 if ( m_xDispatch.is() )
204 {
205 Reference< XUnoTunnel > xTunnel( m_xDispatch, UNO_QUERY );
206 SfxOfficeDispatch* pDisp = NULL;
207 if ( xTunnel.is() )
208 {
209 sal_Int64 nImplementation = xTunnel->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier());
210 pDisp = reinterpret_cast< SfxOfficeDispatch* >(sal::static_int_cast< sal_IntPtr >( nImplementation ));
211 }
212
213 if ( pDisp )
214 pViewFrame = pDisp->GetDispatcher_Impl()->GetFrame();
215 }
216
217 SfxSlotPool& rPool = SfxSlotPool::GetSlotPool( pViewFrame );
218 const SfxSlot* pSlot = rPool.GetSlot( m_nSlotID );
219
220 SfxItemState eState = SFX_ITEM_DISABLED;
221 SfxPoolItem* pItem = NULL;
222 if ( rEvent.IsEnabled )
223 {
224 eState = SFX_ITEM_AVAILABLE;
225 ::com::sun::star::uno::Type pType = rEvent.State.getValueType();
226
227 if ( pType == ::getVoidCppuType() )
228 {
229 pItem = new SfxVoidItem( m_nSlotID );
230 eState = SFX_ITEM_UNKNOWN;
231 }
232 else if ( pType == ::getBooleanCppuType() )
233 {
234 sal_Bool bTemp = false;
235 rEvent.State >>= bTemp ;
236 pItem = new SfxBoolItem( m_nSlotID, bTemp );
237 }
238 else if ( pType == ::getCppuType((const sal_uInt16*)0) )
239 {
240 sal_uInt16 nTemp = 0;
241 rEvent.State >>= nTemp ;
242 pItem = new SfxUInt16Item( m_nSlotID, nTemp );
243 }
244 else if ( pType == ::getCppuType((const sal_uInt32*)0) )
245 {
246 sal_uInt32 nTemp = 0;
247 rEvent.State >>= nTemp ;
248 pItem = new SfxUInt32Item( m_nSlotID, nTemp );
249 }
250 else if ( pType == ::getCppuType((const ::rtl::OUString*)0) )
251 {
252 ::rtl::OUString sTemp ;
253 rEvent.State >>= sTemp ;
254 pItem = new SfxStringItem( m_nSlotID, sTemp );
255 }
256 else if ( pType == ::getCppuType((const ::com::sun::star::frame::status::ItemStatus*)0) )
257 {
258 ItemStatus aItemStatus;
259 rEvent.State >>= aItemStatus;
260 eState = aItemStatus.State;
261 pItem = new SfxVoidItem( m_nSlotID );
262 }
263 else if ( pType == ::getCppuType((const ::com::sun::star::frame::status::Visibility*)0) )
264 {
265 Visibility aVisibilityStatus;
266 rEvent.State >>= aVisibilityStatus;
267 pItem = new SfxVisibilityItem( m_nSlotID, aVisibilityStatus.bVisible );
268 }
269 else
270 {
271 if ( pSlot )
272 pItem = pSlot->GetType()->CreateItem();
273 if ( pItem )
274 {
275 pItem->SetWhich( m_nSlotID );
276 pItem->PutValue( rEvent.State );
277 }
278 else
279 pItem = new SfxVoidItem( m_nSlotID );
280 }
281 }
282
283 StateChanged( m_nSlotID, eState, pItem );
284 delete pItem;
285 }
286
287