xref: /trunk/main/sfx2/source/control/querystatus.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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);
66 
67         // XStatusListener
68         virtual void SAL_CALL statusChanged(const ::com::sun::star::frame::FeatureStateEvent& Event);
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 {
109     ::vos::OGuard aGuard( Application::GetSolarMutex() );
110     m_xDispatch.clear();
111 }
112 
statusChanged(const FeatureStateEvent & rEvent)113 void SAL_CALL SfxQueryStatus_Impl::statusChanged( const FeatureStateEvent& rEvent)
114 {
115     ::vos::OGuard aGuard( Application::GetSolarMutex() );
116 
117     m_pItem  = NULL;
118     m_eState = SFX_ITEM_DISABLED;
119 
120     if ( rEvent.IsEnabled )
121     {
122         m_eState = SFX_ITEM_AVAILABLE;
123         ::com::sun::star::uno::Type pType = rEvent.State.getValueType();
124 
125         if ( pType == ::getBooleanCppuType() )
126         {
127             sal_Bool bTemp = false;
128             rEvent.State >>= bTemp ;
129             m_pItem = new SfxBoolItem( m_nSlotID, bTemp );
130         }
131         else if ( pType == ::getCppuType((const sal_uInt16*)0) )
132         {
133             sal_uInt16 nTemp = 0;
134             rEvent.State >>= nTemp ;
135             m_pItem = new SfxUInt16Item( m_nSlotID, nTemp );
136         }
137         else if ( pType == ::getCppuType((const sal_uInt32*)0) )
138         {
139             sal_uInt32 nTemp = 0;
140             rEvent.State >>= nTemp ;
141             m_pItem = new SfxUInt32Item( m_nSlotID, nTemp );
142         }
143         else if ( pType == ::getCppuType((const ::rtl::OUString*)0) )
144         {
145             ::rtl::OUString sTemp ;
146             rEvent.State >>= sTemp ;
147             m_pItem = new SfxStringItem( m_nSlotID, sTemp );
148         }
149         else if ( pType == ::getCppuType((const ::com::sun::star::frame::status::ItemStatus*)0) )
150         {
151             ItemStatus aItemStatus;
152             rEvent.State >>= aItemStatus;
153             m_eState = aItemStatus.State;
154             m_pItem = new SfxVoidItem( m_nSlotID );
155         }
156         else if ( pType == ::getCppuType((const ::com::sun::star::frame::status::Visibility*)0) )
157         {
158             Visibility aVisibilityStatus;
159             rEvent.State >>= aVisibilityStatus;
160             m_pItem = new SfxVisibilityItem( m_nSlotID, aVisibilityStatus.bVisible );
161         }
162         else
163         {
164             m_eState = SFX_ITEM_UNKNOWN;
165             m_pItem  = new SfxVoidItem( m_nSlotID );
166         }
167     }
168 
169     if ( m_pItem )
170         DeleteItemOnIdle( m_pItem );
171 
172     try
173     {
174         m_aCondition.set();
175         m_xDispatch->removeStatusListener( Reference< XStatusListener >( static_cast< cppu::OWeakObject* >( this ), UNO_QUERY ),
176                                            m_aCommand );
177     }
178     catch ( Exception& )
179     {
180     }
181 }
182 
183 // Query method
QueryState(SfxPoolItem * & rpPoolItem)184 SfxItemState SfxQueryStatus_Impl::QueryState( SfxPoolItem*& rpPoolItem )
185 {
186     ::vos::OGuard aGuard( Application::GetSolarMutex() );
187     if ( !m_bQueryInProgress )
188     {
189         m_pItem  = NULL;
190         m_eState = SFX_ITEM_DISABLED;
191 
192         if ( m_xDispatch.is() )
193         {
194             try
195             {
196                 m_aCondition.reset();
197                 m_bQueryInProgress = sal_True;
198                 m_xDispatch->addStatusListener( Reference< XStatusListener >( static_cast< cppu::OWeakObject* >( this ), UNO_QUERY ),
199                                                 m_aCommand );
200             }
201             catch ( Exception& )
202             {
203                 m_aCondition.set();
204             }
205         }
206         else
207             m_aCondition.set();
208     }
209 
210     m_aCondition.wait();
211 
212     m_bQueryInProgress = sal_False;
213     rpPoolItem = m_pItem;
214     return m_eState;
215 }
216 
217 //*************************************************************************
218 
SfxQueryStatus(const Reference<XDispatchProvider> & rDispatchProvider,sal_uInt16 nSlotId,const OUString & rCommand)219 SfxQueryStatus::SfxQueryStatus( const Reference< XDispatchProvider >& rDispatchProvider, sal_uInt16 nSlotId, const OUString& rCommand )
220 {
221     m_pSfxQueryStatusImpl = new SfxQueryStatus_Impl( rDispatchProvider, nSlotId, rCommand );
222     m_xStatusListener     = Reference< XStatusListener >(
223                                 static_cast< cppu::OWeakObject* >( m_pSfxQueryStatusImpl ),
224                                 UNO_QUERY );
225 }
226 
~SfxQueryStatus()227 SfxQueryStatus::~SfxQueryStatus()
228 {
229 }
230 
QueryState(SfxPoolItem * & rpPoolItem)231 SfxItemState SfxQueryStatus::QueryState( SfxPoolItem*& rpPoolItem )
232 {
233     ::vos::OGuard aGuard( Application::GetSolarMutex() );
234     return m_pSfxQueryStatusImpl->QueryState( rpPoolItem );
235 }
236