1*d119d52dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*d119d52dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*d119d52dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*d119d52dSAndrew Rist  * distributed with this work for additional information
6*d119d52dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*d119d52dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*d119d52dSAndrew Rist  * "License"); you may not use this file except in compliance
9*d119d52dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*d119d52dSAndrew Rist  *
11*d119d52dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*d119d52dSAndrew Rist  *
13*d119d52dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*d119d52dSAndrew Rist  * software distributed under the License is distributed on an
15*d119d52dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*d119d52dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*d119d52dSAndrew Rist  * specific language governing permissions and limitations
18*d119d52dSAndrew Rist  * under the License.
19*d119d52dSAndrew Rist  *
20*d119d52dSAndrew Rist  *************************************************************/
21*d119d52dSAndrew Rist 
22*d119d52dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sfx2.hxx"
26cdf0e10cSrcweir #include <sfx2/querystatus.hxx>
27cdf0e10cSrcweir #include <svl/poolitem.hxx>
28cdf0e10cSrcweir #include <svl/eitem.hxx>
29cdf0e10cSrcweir #include <svl/stritem.hxx>
30cdf0e10cSrcweir #include <svl/intitem.hxx>
31cdf0e10cSrcweir #include <svl/itemset.hxx>
32cdf0e10cSrcweir #include <svtools/itemdel.hxx>
33cdf0e10cSrcweir #include <svl/visitem.hxx>
34cdf0e10cSrcweir #include <cppuhelper/weak.hxx>
35cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
36cdf0e10cSrcweir #include <vos/mutex.hxx>
37cdf0e10cSrcweir #include <vcl/svapp.hxx>
38cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp>
39cdf0e10cSrcweir #include <com/sun/star/frame/status/ItemStatus.hpp>
40cdf0e10cSrcweir #include <com/sun/star/frame/status/ItemState.hpp>
41cdf0e10cSrcweir #include <com/sun/star/frame/status/Visibility.hpp>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir using ::rtl::OUString;
44cdf0e10cSrcweir using namespace ::cppu;
45cdf0e10cSrcweir using namespace ::com::sun::star::uno;
46cdf0e10cSrcweir using namespace ::com::sun::star::frame;
47cdf0e10cSrcweir using namespace ::com::sun::star::frame::status;
48cdf0e10cSrcweir using namespace ::com::sun::star::lang;
49cdf0e10cSrcweir using namespace ::com::sun::star::util;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir class SfxQueryStatus_Impl : public ::com::sun::star::frame::XStatusListener	,
52cdf0e10cSrcweir 					        public ::com::sun::star::lang::XTypeProvider	,
53cdf0e10cSrcweir 					        public ::cppu::OWeakObject
54cdf0e10cSrcweir {
55cdf0e10cSrcweir     public:
56cdf0e10cSrcweir 	    SFX_DECL_XINTERFACE_XTYPEPROVIDER
57cdf0e10cSrcweir 
58cdf0e10cSrcweir         SfxQueryStatus_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& rDispatchProvider, sal_uInt16 nSlotId, const rtl::OUString& aCommand );
59cdf0e10cSrcweir         virtual ~SfxQueryStatus_Impl();
60cdf0e10cSrcweir 
61cdf0e10cSrcweir         // Query method
62cdf0e10cSrcweir         SfxItemState QueryState( SfxPoolItem*& pPoolItem );
63cdf0e10cSrcweir 
64cdf0e10cSrcweir         // XEventListener
65cdf0e10cSrcweir 	    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( ::com::sun::star::uno::RuntimeException );
66cdf0e10cSrcweir 
67cdf0e10cSrcweir         // XStatusListener
68cdf0e10cSrcweir 	    virtual void SAL_CALL statusChanged(const ::com::sun::star::frame::FeatureStateEvent& Event) throw( ::com::sun::star::uno::RuntimeException );
69cdf0e10cSrcweir 
70cdf0e10cSrcweir     private:
71cdf0e10cSrcweir         SfxQueryStatus_Impl( const SfxQueryStatus& );
72cdf0e10cSrcweir         SfxQueryStatus_Impl();
73cdf0e10cSrcweir         SfxQueryStatus_Impl& operator=( const SfxQueryStatus& );
74cdf0e10cSrcweir 
75cdf0e10cSrcweir         sal_Bool                                                                   m_bQueryInProgress;
76cdf0e10cSrcweir         SfxItemState                                                               m_eState;
77cdf0e10cSrcweir         SfxPoolItem*                                                               m_pItem;
78cdf0e10cSrcweir         sal_uInt16                                                                     m_nSlotID;
79cdf0e10cSrcweir         osl::Condition                                                             m_aCondition;
80cdf0e10cSrcweir         ::com::sun::star::util::URL                                                m_aCommand;
81cdf0e10cSrcweir         com::sun::star::uno::Reference< com::sun::star::frame::XDispatch >         m_xDispatch;
82cdf0e10cSrcweir };
83cdf0e10cSrcweir 
SFX_IMPL_XINTERFACE_2(SfxQueryStatus_Impl,OWeakObject,::com::sun::star::frame::XStatusListener,::com::sun::star::lang::XEventListener)84cdf0e10cSrcweir SFX_IMPL_XINTERFACE_2( SfxQueryStatus_Impl, OWeakObject, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
85cdf0e10cSrcweir SFX_IMPL_XTYPEPROVIDER_2( SfxQueryStatus_Impl, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
86cdf0e10cSrcweir 
87cdf0e10cSrcweir SfxQueryStatus_Impl::SfxQueryStatus_Impl( const Reference< XDispatchProvider >& rDispatchProvider, sal_uInt16 nSlotId, const OUString& rCommand ) :
88cdf0e10cSrcweir     cppu::OWeakObject(),
89cdf0e10cSrcweir     m_bQueryInProgress( sal_False ),
90cdf0e10cSrcweir     m_eState( SFX_ITEM_DISABLED ),
91cdf0e10cSrcweir     m_pItem( 0 ),
92cdf0e10cSrcweir     m_nSlotID( nSlotId )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir     m_aCommand.Complete = rCommand;
95cdf0e10cSrcweir     Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
96cdf0e10cSrcweir                                             rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
97cdf0e10cSrcweir     xTrans->parseStrict( m_aCommand );
98cdf0e10cSrcweir     if ( rDispatchProvider.is() )
99cdf0e10cSrcweir         m_xDispatch = rDispatchProvider->queryDispatch( m_aCommand, rtl::OUString(), 0 );
100cdf0e10cSrcweir     m_aCondition.reset();
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
~SfxQueryStatus_Impl()103cdf0e10cSrcweir SfxQueryStatus_Impl::~SfxQueryStatus_Impl()
104cdf0e10cSrcweir {
105cdf0e10cSrcweir }
106cdf0e10cSrcweir 
disposing(const EventObject &)107cdf0e10cSrcweir void SAL_CALL SfxQueryStatus_Impl::disposing( const EventObject& )
108cdf0e10cSrcweir throw( RuntimeException )
109cdf0e10cSrcweir {
110cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
111cdf0e10cSrcweir     m_xDispatch.clear();
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
statusChanged(const FeatureStateEvent & rEvent)114cdf0e10cSrcweir void SAL_CALL SfxQueryStatus_Impl::statusChanged( const FeatureStateEvent& rEvent)
115cdf0e10cSrcweir throw( RuntimeException )
116cdf0e10cSrcweir {
117cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     m_pItem  = NULL;
120cdf0e10cSrcweir     m_eState = SFX_ITEM_DISABLED;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     if ( rEvent.IsEnabled )
123cdf0e10cSrcweir 	{
124cdf0e10cSrcweir 		m_eState = SFX_ITEM_AVAILABLE;
125cdf0e10cSrcweir 		::com::sun::star::uno::Type pType =	rEvent.State.getValueType();
126cdf0e10cSrcweir 
127cdf0e10cSrcweir 		if ( pType == ::getBooleanCppuType() )
128cdf0e10cSrcweir 		{
129cdf0e10cSrcweir 			sal_Bool bTemp = false;
130cdf0e10cSrcweir 			rEvent.State >>= bTemp ;
131cdf0e10cSrcweir 			m_pItem = new SfxBoolItem( m_nSlotID, bTemp );
132cdf0e10cSrcweir 		}
133cdf0e10cSrcweir 		else if ( pType == ::getCppuType((const sal_uInt16*)0) )
134cdf0e10cSrcweir 		{
135cdf0e10cSrcweir 			sal_uInt16 nTemp = 0;
136cdf0e10cSrcweir 			rEvent.State >>= nTemp ;
137cdf0e10cSrcweir 			m_pItem = new SfxUInt16Item( m_nSlotID, nTemp );
138cdf0e10cSrcweir 		}
139cdf0e10cSrcweir 		else if ( pType == ::getCppuType((const sal_uInt32*)0) )
140cdf0e10cSrcweir 		{
141cdf0e10cSrcweir 			sal_uInt32 nTemp = 0;
142cdf0e10cSrcweir 			rEvent.State >>= nTemp ;
143cdf0e10cSrcweir 			m_pItem = new SfxUInt32Item( m_nSlotID, nTemp );
144cdf0e10cSrcweir 		}
145cdf0e10cSrcweir 		else if ( pType == ::getCppuType((const ::rtl::OUString*)0) )
146cdf0e10cSrcweir 		{
147cdf0e10cSrcweir 			::rtl::OUString sTemp ;
148cdf0e10cSrcweir 			rEvent.State >>= sTemp ;
149cdf0e10cSrcweir 			m_pItem = new SfxStringItem( m_nSlotID, sTemp );
150cdf0e10cSrcweir 		}
151cdf0e10cSrcweir         else if ( pType == ::getCppuType((const ::com::sun::star::frame::status::ItemStatus*)0) )
152cdf0e10cSrcweir         {
153cdf0e10cSrcweir             ItemStatus aItemStatus;
154cdf0e10cSrcweir             rEvent.State >>= aItemStatus;
155cdf0e10cSrcweir             m_eState = aItemStatus.State;
156cdf0e10cSrcweir             m_pItem = new SfxVoidItem( m_nSlotID );
157cdf0e10cSrcweir         }
158cdf0e10cSrcweir         else if ( pType == ::getCppuType((const ::com::sun::star::frame::status::Visibility*)0) )
159cdf0e10cSrcweir         {
160cdf0e10cSrcweir             Visibility aVisibilityStatus;
161cdf0e10cSrcweir             rEvent.State >>= aVisibilityStatus;
162cdf0e10cSrcweir             m_pItem = new SfxVisibilityItem( m_nSlotID, aVisibilityStatus.bVisible );
163cdf0e10cSrcweir         }
164cdf0e10cSrcweir 		else
165cdf0e10cSrcweir         {
166cdf0e10cSrcweir             m_eState = SFX_ITEM_UNKNOWN;
167cdf0e10cSrcweir 			m_pItem  = new SfxVoidItem( m_nSlotID );
168cdf0e10cSrcweir         }
169cdf0e10cSrcweir 	}
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 	if ( m_pItem )
172cdf0e10cSrcweir         DeleteItemOnIdle( m_pItem );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir     try
175cdf0e10cSrcweir     {
176cdf0e10cSrcweir         m_aCondition.set();
177cdf0e10cSrcweir         m_xDispatch->removeStatusListener( Reference< XStatusListener >( static_cast< cppu::OWeakObject* >( this ), UNO_QUERY ),
178cdf0e10cSrcweir                                            m_aCommand );
179cdf0e10cSrcweir     }
180cdf0e10cSrcweir     catch ( Exception& )
181cdf0e10cSrcweir     {
182cdf0e10cSrcweir     }
183cdf0e10cSrcweir }
184cdf0e10cSrcweir 
185cdf0e10cSrcweir // Query method
QueryState(SfxPoolItem * & rpPoolItem)186cdf0e10cSrcweir SfxItemState SfxQueryStatus_Impl::QueryState( SfxPoolItem*& rpPoolItem )
187cdf0e10cSrcweir {
188cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
189cdf0e10cSrcweir     if ( !m_bQueryInProgress )
190cdf0e10cSrcweir     {
191cdf0e10cSrcweir         m_pItem  = NULL;
192cdf0e10cSrcweir         m_eState = SFX_ITEM_DISABLED;
193cdf0e10cSrcweir 
194cdf0e10cSrcweir         if ( m_xDispatch.is() )
195cdf0e10cSrcweir         {
196cdf0e10cSrcweir             try
197cdf0e10cSrcweir             {
198cdf0e10cSrcweir                 m_aCondition.reset();
199cdf0e10cSrcweir                 m_bQueryInProgress = sal_True;
200cdf0e10cSrcweir                 m_xDispatch->addStatusListener( Reference< XStatusListener >( static_cast< cppu::OWeakObject* >( this ), UNO_QUERY ),
201cdf0e10cSrcweir                                                 m_aCommand );
202cdf0e10cSrcweir             }
203cdf0e10cSrcweir             catch ( Exception& )
204cdf0e10cSrcweir             {
205cdf0e10cSrcweir                 m_aCondition.set();
206cdf0e10cSrcweir             }
207cdf0e10cSrcweir         }
208cdf0e10cSrcweir         else
209cdf0e10cSrcweir             m_aCondition.set();
210cdf0e10cSrcweir     }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir     m_aCondition.wait();
213cdf0e10cSrcweir 
214cdf0e10cSrcweir     m_bQueryInProgress = sal_False;
215cdf0e10cSrcweir     rpPoolItem = m_pItem;
216cdf0e10cSrcweir     return m_eState;
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
219cdf0e10cSrcweir //*************************************************************************
220cdf0e10cSrcweir 
SfxQueryStatus(const Reference<XDispatchProvider> & rDispatchProvider,sal_uInt16 nSlotId,const OUString & rCommand)221cdf0e10cSrcweir SfxQueryStatus::SfxQueryStatus( const Reference< XDispatchProvider >& rDispatchProvider, sal_uInt16 nSlotId, const OUString& rCommand )
222cdf0e10cSrcweir {
223cdf0e10cSrcweir     m_pSfxQueryStatusImpl = new SfxQueryStatus_Impl( rDispatchProvider, nSlotId, rCommand );
224cdf0e10cSrcweir     m_xStatusListener     = Reference< XStatusListener >(
225cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject* >( m_pSfxQueryStatusImpl ),
226cdf0e10cSrcweir                                 UNO_QUERY );
227cdf0e10cSrcweir }
228cdf0e10cSrcweir 
~SfxQueryStatus()229cdf0e10cSrcweir SfxQueryStatus::~SfxQueryStatus()
230cdf0e10cSrcweir {
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
QueryState(SfxPoolItem * & rpPoolItem)233cdf0e10cSrcweir SfxItemState SfxQueryStatus::QueryState( SfxPoolItem*& rpPoolItem )
234cdf0e10cSrcweir {
235cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
236cdf0e10cSrcweir     return m_pSfxQueryStatusImpl->QueryState( rpPoolItem );
237cdf0e10cSrcweir }
238