xref: /AOO41X/main/sfx2/source/control/querystatus.cxx (revision d119d52d53d0b2180f2ae51341d882123be2af2b)
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/querystatus.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/frame/status/ItemStatus.hpp>
40 #include <com/sun/star/frame/status/ItemState.hpp>
41 #include <com/sun/star/frame/status/Visibility.hpp>
42 
43 using ::rtl::OUString;
44 using namespace ::cppu;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::frame;
47 using namespace ::com::sun::star::frame::status;
48 using namespace ::com::sun::star::lang;
49 using namespace ::com::sun::star::util;
50 
51 class SfxQueryStatus_Impl : public ::com::sun::star::frame::XStatusListener ,
52                             public ::com::sun::star::lang::XTypeProvider    ,
53                             public ::cppu::OWeakObject
54 {
55     public:
56         SFX_DECL_XINTERFACE_XTYPEPROVIDER
57 
58         SfxQueryStatus_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& rDispatchProvider, sal_uInt16 nSlotId, const rtl::OUString& aCommand );
59         virtual ~SfxQueryStatus_Impl();
60 
61         // Query method
62         SfxItemState QueryState( SfxPoolItem*& pPoolItem );
63 
64         // XEventListener
65         virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( ::com::sun::star::uno::RuntimeException );
66 
67         // XStatusListener
68         virtual void SAL_CALL statusChanged(const ::com::sun::star::frame::FeatureStateEvent& Event) throw( ::com::sun::star::uno::RuntimeException );
69 
70     private:
71         SfxQueryStatus_Impl( const SfxQueryStatus& );
72         SfxQueryStatus_Impl();
73         SfxQueryStatus_Impl& operator=( const SfxQueryStatus& );
74 
75         sal_Bool                                                                   m_bQueryInProgress;
76         SfxItemState                                                               m_eState;
77         SfxPoolItem*                                                               m_pItem;
78         sal_uInt16                                                                     m_nSlotID;
79         osl::Condition                                                             m_aCondition;
80         ::com::sun::star::util::URL                                                m_aCommand;
81         com::sun::star::uno::Reference< com::sun::star::frame::XDispatch >         m_xDispatch;
82 };
83 
SFX_IMPL_XINTERFACE_2(SfxQueryStatus_Impl,OWeakObject,::com::sun::star::frame::XStatusListener,::com::sun::star::lang::XEventListener)84 SFX_IMPL_XINTERFACE_2( SfxQueryStatus_Impl, OWeakObject, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
85 SFX_IMPL_XTYPEPROVIDER_2( SfxQueryStatus_Impl, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
86 
87 SfxQueryStatus_Impl::SfxQueryStatus_Impl( const Reference< XDispatchProvider >& rDispatchProvider, sal_uInt16 nSlotId, const OUString& rCommand ) :
88     cppu::OWeakObject(),
89     m_bQueryInProgress( sal_False ),
90     m_eState( SFX_ITEM_DISABLED ),
91     m_pItem( 0 ),
92     m_nSlotID( nSlotId )
93 {
94     m_aCommand.Complete = rCommand;
95     Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
96                                             rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
97     xTrans->parseStrict( m_aCommand );
98     if ( rDispatchProvider.is() )
99         m_xDispatch = rDispatchProvider->queryDispatch( m_aCommand, rtl::OUString(), 0 );
100     m_aCondition.reset();
101 }
102 
~SfxQueryStatus_Impl()103 SfxQueryStatus_Impl::~SfxQueryStatus_Impl()
104 {
105 }
106 
disposing(const EventObject &)107 void SAL_CALL SfxQueryStatus_Impl::disposing( const EventObject& )
108 throw( RuntimeException )
109 {
110     ::vos::OGuard aGuard( Application::GetSolarMutex() );
111     m_xDispatch.clear();
112 }
113 
statusChanged(const FeatureStateEvent & rEvent)114 void SAL_CALL SfxQueryStatus_Impl::statusChanged( const FeatureStateEvent& rEvent)
115 throw( RuntimeException )
116 {
117     ::vos::OGuard aGuard( Application::GetSolarMutex() );
118 
119     m_pItem  = NULL;
120     m_eState = SFX_ITEM_DISABLED;
121 
122     if ( rEvent.IsEnabled )
123     {
124         m_eState = SFX_ITEM_AVAILABLE;
125         ::com::sun::star::uno::Type pType = rEvent.State.getValueType();
126 
127         if ( pType == ::getBooleanCppuType() )
128         {
129             sal_Bool bTemp = false;
130             rEvent.State >>= bTemp ;
131             m_pItem = new SfxBoolItem( m_nSlotID, bTemp );
132         }
133         else if ( pType == ::getCppuType((const sal_uInt16*)0) )
134         {
135             sal_uInt16 nTemp = 0;
136             rEvent.State >>= nTemp ;
137             m_pItem = new SfxUInt16Item( m_nSlotID, nTemp );
138         }
139         else if ( pType == ::getCppuType((const sal_uInt32*)0) )
140         {
141             sal_uInt32 nTemp = 0;
142             rEvent.State >>= nTemp ;
143             m_pItem = new SfxUInt32Item( m_nSlotID, nTemp );
144         }
145         else if ( pType == ::getCppuType((const ::rtl::OUString*)0) )
146         {
147             ::rtl::OUString sTemp ;
148             rEvent.State >>= sTemp ;
149             m_pItem = new SfxStringItem( m_nSlotID, sTemp );
150         }
151         else if ( pType == ::getCppuType((const ::com::sun::star::frame::status::ItemStatus*)0) )
152         {
153             ItemStatus aItemStatus;
154             rEvent.State >>= aItemStatus;
155             m_eState = aItemStatus.State;
156             m_pItem = new SfxVoidItem( m_nSlotID );
157         }
158         else if ( pType == ::getCppuType((const ::com::sun::star::frame::status::Visibility*)0) )
159         {
160             Visibility aVisibilityStatus;
161             rEvent.State >>= aVisibilityStatus;
162             m_pItem = new SfxVisibilityItem( m_nSlotID, aVisibilityStatus.bVisible );
163         }
164         else
165         {
166             m_eState = SFX_ITEM_UNKNOWN;
167             m_pItem  = new SfxVoidItem( m_nSlotID );
168         }
169     }
170 
171     if ( m_pItem )
172         DeleteItemOnIdle( m_pItem );
173 
174     try
175     {
176         m_aCondition.set();
177         m_xDispatch->removeStatusListener( Reference< XStatusListener >( static_cast< cppu::OWeakObject* >( this ), UNO_QUERY ),
178                                            m_aCommand );
179     }
180     catch ( Exception& )
181     {
182     }
183 }
184 
185 // Query method
QueryState(SfxPoolItem * & rpPoolItem)186 SfxItemState SfxQueryStatus_Impl::QueryState( SfxPoolItem*& rpPoolItem )
187 {
188     ::vos::OGuard aGuard( Application::GetSolarMutex() );
189     if ( !m_bQueryInProgress )
190     {
191         m_pItem  = NULL;
192         m_eState = SFX_ITEM_DISABLED;
193 
194         if ( m_xDispatch.is() )
195         {
196             try
197             {
198                 m_aCondition.reset();
199                 m_bQueryInProgress = sal_True;
200                 m_xDispatch->addStatusListener( Reference< XStatusListener >( static_cast< cppu::OWeakObject* >( this ), UNO_QUERY ),
201                                                 m_aCommand );
202             }
203             catch ( Exception& )
204             {
205                 m_aCondition.set();
206             }
207         }
208         else
209             m_aCondition.set();
210     }
211 
212     m_aCondition.wait();
213 
214     m_bQueryInProgress = sal_False;
215     rpPoolItem = m_pItem;
216     return m_eState;
217 }
218 
219 //*************************************************************************
220 
SfxQueryStatus(const Reference<XDispatchProvider> & rDispatchProvider,sal_uInt16 nSlotId,const OUString & rCommand)221 SfxQueryStatus::SfxQueryStatus( const Reference< XDispatchProvider >& rDispatchProvider, sal_uInt16 nSlotId, const OUString& rCommand )
222 {
223     m_pSfxQueryStatusImpl = new SfxQueryStatus_Impl( rDispatchProvider, nSlotId, rCommand );
224     m_xStatusListener     = Reference< XStatusListener >(
225                                 static_cast< cppu::OWeakObject* >( m_pSfxQueryStatusImpl ),
226                                 UNO_QUERY );
227 }
228 
~SfxQueryStatus()229 SfxQueryStatus::~SfxQueryStatus()
230 {
231 }
232 
QueryState(SfxPoolItem * & rpPoolItem)233 SfxItemState SfxQueryStatus::QueryState( SfxPoolItem*& rpPoolItem )
234 {
235     ::vos::OGuard aGuard( Application::GetSolarMutex() );
236     return m_pSfxQueryStatusImpl->QueryState( rpPoolItem );
237 }
238