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