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