xref: /aoo41x/main/sfx2/source/control/unoctitm.cxx (revision d119d52d)
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 
27cdf0e10cSrcweir #include <tools/debug.hxx>
28cdf0e10cSrcweir #include <svl/eitem.hxx>
29cdf0e10cSrcweir #include <svl/stritem.hxx>
30cdf0e10cSrcweir #include <svl/intitem.hxx>
31cdf0e10cSrcweir #include <svl/itemset.hxx>
32cdf0e10cSrcweir #include <svl/visitem.hxx>
33cdf0e10cSrcweir #include <svtools/javacontext.hxx>
34cdf0e10cSrcweir #include <svl/itempool.hxx>
35cdf0e10cSrcweir #include <tools/urlobj.hxx>
36cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp>
37cdf0e10cSrcweir #include <com/sun/star/frame/XController.hpp>
38cdf0e10cSrcweir #include <com/sun/star/frame/XFrameActionListener.hpp>
39cdf0e10cSrcweir #include <com/sun/star/frame/XComponentLoader.hpp>
40cdf0e10cSrcweir #include <com/sun/star/frame/XFrame.hpp>
41cdf0e10cSrcweir #include <com/sun/star/frame/FrameActionEvent.hpp>
42cdf0e10cSrcweir #include <com/sun/star/frame/FrameAction.hpp>
43cdf0e10cSrcweir #include <com/sun/star/frame/status/ItemStatus.hpp>
44cdf0e10cSrcweir #include <com/sun/star/frame/status/ItemState.hpp>
45cdf0e10cSrcweir #include <com/sun/star/frame/DispatchResultState.hpp>
46cdf0e10cSrcweir #include <com/sun/star/frame/status/Visibility.hpp>
47cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
48cdf0e10cSrcweir #include <comphelper/sequence.hxx>
49cdf0e10cSrcweir #include <vos/mutex.hxx>
50cdf0e10cSrcweir #include <uno/current_context.hxx>
51cdf0e10cSrcweir #include <vcl/svapp.hxx>
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #include <sfx2/app.hxx>
54cdf0e10cSrcweir #include <sfx2/unoctitm.hxx>
55cdf0e10cSrcweir #include <sfx2/viewfrm.hxx>
56cdf0e10cSrcweir #include <sfx2/frame.hxx>
57cdf0e10cSrcweir #include <sfx2/ctrlitem.hxx>
58cdf0e10cSrcweir #include <sfx2/sfxuno.hxx>
59cdf0e10cSrcweir #include <sfx2/bindings.hxx>
60cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
61cdf0e10cSrcweir #include <sfx2/sfxsids.hrc>
62cdf0e10cSrcweir #include <sfx2/request.hxx>
63cdf0e10cSrcweir #include "statcach.hxx"
64cdf0e10cSrcweir #include <sfx2/msgpool.hxx>
65cdf0e10cSrcweir #include <sfx2/objsh.hxx>
66cdf0e10cSrcweir 
67cdf0e10cSrcweir namespace css = ::com::sun::star;
68cdf0e10cSrcweir using namespace ::com::sun::star::uno;
69cdf0e10cSrcweir using namespace ::com::sun::star::util;
70cdf0e10cSrcweir //long nOfficeDispatchCount = 0;
71cdf0e10cSrcweir 
72cdf0e10cSrcweir enum URLTypeId
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     URLType_BOOL,
75cdf0e10cSrcweir     URLType_BYTE,
76cdf0e10cSrcweir     URLType_SHORT,
77cdf0e10cSrcweir     URLType_LONG,
78cdf0e10cSrcweir     URLType_HYPER,
79cdf0e10cSrcweir     URLType_STRING,
80cdf0e10cSrcweir     URLType_FLOAT,
81cdf0e10cSrcweir     URLType_DOUBLE,
82cdf0e10cSrcweir     URLType_COUNT
83cdf0e10cSrcweir };
84cdf0e10cSrcweir 
85cdf0e10cSrcweir const char* URLTypeNames[URLType_COUNT] =
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     "bool",
88cdf0e10cSrcweir     "byte",
89cdf0e10cSrcweir     "short",
90cdf0e10cSrcweir     "long",
91cdf0e10cSrcweir     "hyper",
92cdf0e10cSrcweir     "string",
93cdf0e10cSrcweir     "float",
94cdf0e10cSrcweir     "double"
95cdf0e10cSrcweir };
96cdf0e10cSrcweir 
SFX_IMPL_XINTERFACE_2(SfxUnoControllerItem,OWeakObject,::com::sun::star::frame::XStatusListener,::com::sun::star::lang::XEventListener)97cdf0e10cSrcweir SFX_IMPL_XINTERFACE_2( SfxUnoControllerItem, OWeakObject, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
98cdf0e10cSrcweir SFX_IMPL_XTYPEPROVIDER_2( SfxUnoControllerItem, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
99cdf0e10cSrcweir 
100cdf0e10cSrcweir SfxUnoControllerItem::SfxUnoControllerItem( SfxControllerItem *pItem, SfxBindings& rBind, const String& rCmd )
101cdf0e10cSrcweir 	: pCtrlItem( pItem )
102cdf0e10cSrcweir     , pBindings( &rBind )
103cdf0e10cSrcweir {
104cdf0e10cSrcweir 	DBG_ASSERT( !pCtrlItem || !pCtrlItem->IsBound(), "ControllerItem fehlerhaft!" );
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 	aCommand.Complete = rCmd;
107cdf0e10cSrcweir     Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
108cdf0e10cSrcweir     xTrans->parseStrict( aCommand );
109cdf0e10cSrcweir 	pBindings->RegisterUnoController_Impl( this );
110cdf0e10cSrcweir }
111cdf0e10cSrcweir 
~SfxUnoControllerItem()112cdf0e10cSrcweir SfxUnoControllerItem::~SfxUnoControllerItem()
113cdf0e10cSrcweir {
114cdf0e10cSrcweir 	// tell bindings to forget this controller ( if still connected )
115cdf0e10cSrcweir 	if ( pBindings )
116cdf0e10cSrcweir 		pBindings->ReleaseUnoController_Impl( this );
117cdf0e10cSrcweir }
118cdf0e10cSrcweir 
UnBind()119cdf0e10cSrcweir void SfxUnoControllerItem::UnBind()
120cdf0e10cSrcweir {
121cdf0e10cSrcweir 	// connection to SfxControllerItem is lost
122cdf0e10cSrcweir 	pCtrlItem = NULL;
123cdf0e10cSrcweir 	::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >  aRef( (::cppu::OWeakObject*)this, ::com::sun::star::uno::UNO_QUERY );
124cdf0e10cSrcweir 	ReleaseDispatch();
125cdf0e10cSrcweir }
126cdf0e10cSrcweir 
statusChanged(const::com::sun::star::frame::FeatureStateEvent & rEvent)127cdf0e10cSrcweir void SAL_CALL SfxUnoControllerItem::statusChanged(const ::com::sun::star::frame::FeatureStateEvent& rEvent) throw ( ::com::sun::star::uno::RuntimeException )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
130cdf0e10cSrcweir 	DBG_ASSERT( pCtrlItem, "dispatch implementation didn't respect our previous removeStatusListener call!" );
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 	if ( rEvent.Requery )
133cdf0e10cSrcweir 	{
134cdf0e10cSrcweir 		// Fehler kann nur passieren, wenn das alte Dispatch fehlerhaft implementiert
135cdf0e10cSrcweir 		// ist, also removeStatusListener nicht gefunzt hat. Aber sowas soll
136cdf0e10cSrcweir 		// ja vorkommen ...
137cdf0e10cSrcweir 		// Also besser vor ReleaseDispatch gegen Abflug sch"utzen!
138cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >  aRef( (::cppu::OWeakObject*)this, ::com::sun::star::uno::UNO_QUERY  );
139cdf0e10cSrcweir 		ReleaseDispatch();
140cdf0e10cSrcweir 		if ( pCtrlItem )
141cdf0e10cSrcweir 			GetNewDispatch(); 		// asynchron ??
142cdf0e10cSrcweir 	}
143cdf0e10cSrcweir 	else if ( pCtrlItem )
144cdf0e10cSrcweir 	{
145cdf0e10cSrcweir 		SfxItemState eState = SFX_ITEM_DISABLED;
146cdf0e10cSrcweir 		SfxPoolItem* pItem = NULL;
147cdf0e10cSrcweir 		if ( rEvent.IsEnabled )
148cdf0e10cSrcweir 		{
149cdf0e10cSrcweir 			eState = SFX_ITEM_AVAILABLE;
150cdf0e10cSrcweir 			::com::sun::star::uno::Type pType =	rEvent.State.getValueType();
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 			if ( pType == ::getBooleanCppuType() )
153cdf0e10cSrcweir 			{
154cdf0e10cSrcweir 				sal_Bool bTemp = false;
155cdf0e10cSrcweir 				rEvent.State >>= bTemp ;
156cdf0e10cSrcweir 				pItem = new SfxBoolItem( pCtrlItem->GetId(), bTemp );
157cdf0e10cSrcweir 			}
158cdf0e10cSrcweir 			else if ( pType == ::getCppuType((const sal_uInt16*)0) )
159cdf0e10cSrcweir 			{
160cdf0e10cSrcweir 				sal_uInt16 nTemp = 0;
161cdf0e10cSrcweir 				rEvent.State >>= nTemp ;
162cdf0e10cSrcweir 				pItem = new SfxUInt16Item( pCtrlItem->GetId(), nTemp );
163cdf0e10cSrcweir 			}
164cdf0e10cSrcweir 			else if ( pType == ::getCppuType((const sal_uInt32*)0) )
165cdf0e10cSrcweir 			{
166cdf0e10cSrcweir 				sal_uInt32 nTemp = 0;
167cdf0e10cSrcweir 				rEvent.State >>= nTemp ;
168cdf0e10cSrcweir 				pItem = new SfxUInt32Item( pCtrlItem->GetId(), nTemp );
169cdf0e10cSrcweir 			}
170cdf0e10cSrcweir 			else if ( pType == ::getCppuType((const ::rtl::OUString*)0) )
171cdf0e10cSrcweir 			{
172cdf0e10cSrcweir 				::rtl::OUString sTemp ;
173cdf0e10cSrcweir 				rEvent.State >>= sTemp ;
174cdf0e10cSrcweir 				pItem = new SfxStringItem( pCtrlItem->GetId(), sTemp );
175cdf0e10cSrcweir 			}
176cdf0e10cSrcweir 			else
177cdf0e10cSrcweir 				pItem = new SfxVoidItem( pCtrlItem->GetId() );
178cdf0e10cSrcweir 		}
179cdf0e10cSrcweir 
180cdf0e10cSrcweir 		pCtrlItem->StateChanged( pCtrlItem->GetId(), eState, pItem );
181cdf0e10cSrcweir 		delete pItem;
182cdf0e10cSrcweir 	}
183cdf0e10cSrcweir }
184cdf0e10cSrcweir 
disposing(const::com::sun::star::lang::EventObject &)185cdf0e10cSrcweir void  SAL_CALL SfxUnoControllerItem::disposing( const ::com::sun::star::lang::EventObject& ) throw ( ::com::sun::star::uno::RuntimeException )
186cdf0e10cSrcweir {
187cdf0e10cSrcweir 	::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >  aRef( (::cppu::OWeakObject*)this, ::com::sun::star::uno::UNO_QUERY );
188cdf0e10cSrcweir 	ReleaseDispatch();
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
ReleaseDispatch()191cdf0e10cSrcweir void SfxUnoControllerItem::ReleaseDispatch()
192cdf0e10cSrcweir {
193cdf0e10cSrcweir 	if ( xDispatch.is() )
194cdf0e10cSrcweir 	{
195cdf0e10cSrcweir 		xDispatch->removeStatusListener( (::com::sun::star::frame::XStatusListener*) this, aCommand );
196cdf0e10cSrcweir 		xDispatch = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > ();
197cdf0e10cSrcweir 	}
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
GetNewDispatch()200cdf0e10cSrcweir void SfxUnoControllerItem::GetNewDispatch()
201cdf0e10cSrcweir {
202cdf0e10cSrcweir 	if ( !pBindings )
203cdf0e10cSrcweir 	{
204cdf0e10cSrcweir 		// Bindings released
205cdf0e10cSrcweir 		DBG_ERROR( "Tried to get dispatch, but no Bindings!" );
206cdf0e10cSrcweir 		return;
207cdf0e10cSrcweir 	}
208cdf0e10cSrcweir 
209cdf0e10cSrcweir 	// forget old dispatch
210cdf0e10cSrcweir 	xDispatch = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > ();
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 	// no arms, no cookies !
213cdf0e10cSrcweir 	if ( !pBindings->GetDispatcher_Impl() || !pBindings->GetDispatcher_Impl()->GetFrame() )
214cdf0e10cSrcweir 		return;
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 	SfxFrame& rFrame = pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame();
217cdf0e10cSrcweir 	SfxFrame *pParent = rFrame.GetParentFrame();
218cdf0e10cSrcweir 	if ( pParent )
219cdf0e10cSrcweir 		// parent may intercept
220cdf0e10cSrcweir 		xDispatch = TryGetDispatch( pParent );
221cdf0e10cSrcweir 
222cdf0e10cSrcweir 	if ( !xDispatch.is() )
223cdf0e10cSrcweir 	{
224cdf0e10cSrcweir 		// no interception
225cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >  xFrame = rFrame.GetFrameInterface();
226cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >  xProv( xFrame, ::com::sun::star::uno::UNO_QUERY );
227cdf0e10cSrcweir 		if ( xProv.is() )
228cdf0e10cSrcweir 			xDispatch = xProv->queryDispatch( aCommand, ::rtl::OUString(), 0 );
229cdf0e10cSrcweir 	}
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 	if ( xDispatch.is() )
232cdf0e10cSrcweir 		xDispatch->addStatusListener( (::com::sun::star::frame::XStatusListener*) this, aCommand );
233cdf0e10cSrcweir 	else if ( pCtrlItem )
234cdf0e10cSrcweir 		pCtrlItem->StateChanged( pCtrlItem->GetId(), SFX_ITEM_DISABLED, NULL );
235cdf0e10cSrcweir }
236cdf0e10cSrcweir 
TryGetDispatch(SfxFrame * pFrame)237cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >  SfxUnoControllerItem::TryGetDispatch( SfxFrame *pFrame )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir 	::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >  xDisp;
240cdf0e10cSrcweir 	SfxFrame *pParent = pFrame->GetParentFrame();
241cdf0e10cSrcweir 	if ( pParent )
242cdf0e10cSrcweir 		// parent may intercept
243cdf0e10cSrcweir 		xDisp = TryGetDispatch( pParent );
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 	// only components may intercept
246cdf0e10cSrcweir 	if ( !xDisp.is() && pFrame->HasComponent() )
247cdf0e10cSrcweir 	{
248cdf0e10cSrcweir 		// no interception
249cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame = pFrame->GetFrameInterface();
250cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >  xProv( xFrame, ::com::sun::star::uno::UNO_QUERY );
251cdf0e10cSrcweir 		if ( xProv.is() )
252cdf0e10cSrcweir 			xDisp = xProv->queryDispatch( aCommand, ::rtl::OUString(), 0 );
253cdf0e10cSrcweir 	}
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	return xDisp;
256cdf0e10cSrcweir }
257cdf0e10cSrcweir 
Execute()258cdf0e10cSrcweir void SfxUnoControllerItem::Execute()
259cdf0e10cSrcweir {
260cdf0e10cSrcweir 	// dispatch the resource
261cdf0e10cSrcweir     ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aSeq(1);
262cdf0e10cSrcweir     aSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Referer") );
263cdf0e10cSrcweir     aSeq[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("private:select") );
264cdf0e10cSrcweir 	if ( xDispatch.is() )
265cdf0e10cSrcweir         xDispatch->dispatch( aCommand, aSeq );
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
ReleaseBindings()268cdf0e10cSrcweir void SfxUnoControllerItem::ReleaseBindings()
269cdf0e10cSrcweir {
270cdf0e10cSrcweir 	// connection to binding is lost; so forget the binding and the dispatch
271cdf0e10cSrcweir 	::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >  aRef( (::cppu::OWeakObject*)this, ::com::sun::star::uno::UNO_QUERY );
272cdf0e10cSrcweir 	ReleaseDispatch();
273cdf0e10cSrcweir 	if ( pBindings )
274cdf0e10cSrcweir 		pBindings->ReleaseUnoController_Impl( this );
275cdf0e10cSrcweir 	pBindings = NULL;
276cdf0e10cSrcweir }
277cdf0e10cSrcweir 
ReleaseAll()278cdf0e10cSrcweir void SfxStatusDispatcher::ReleaseAll()
279cdf0e10cSrcweir {
280cdf0e10cSrcweir 	::com::sun::star::lang::EventObject aObject;
281cdf0e10cSrcweir 	aObject.Source = (::cppu::OWeakObject*) this;
282cdf0e10cSrcweir 	aListeners.disposeAndClear( aObject );
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
dispatch(const::com::sun::star::util::URL &,const::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> &)285cdf0e10cSrcweir void SAL_CALL SfxStatusDispatcher::dispatch( const ::com::sun::star::util::URL&, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& ) throw ( ::com::sun::star::uno::RuntimeException )
286cdf0e10cSrcweir {
287cdf0e10cSrcweir }
288cdf0e10cSrcweir 
dispatchWithNotification(const::com::sun::star::util::URL &,const::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> &,const::com::sun::star::uno::Reference<::com::sun::star::frame::XDispatchResultListener> &)289cdf0e10cSrcweir void SAL_CALL SfxStatusDispatcher::dispatchWithNotification(
290cdf0e10cSrcweir     const ::com::sun::star::util::URL&,
291cdf0e10cSrcweir     const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >&,
292cdf0e10cSrcweir     const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchResultListener >& ) throw( ::com::sun::star::uno::RuntimeException )
293cdf0e10cSrcweir {
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
SFX_IMPL_XINTERFACE_2(SfxStatusDispatcher,OWeakObject,::com::sun::star::frame::XNotifyingDispatch,::com::sun::star::frame::XDispatch)296cdf0e10cSrcweir SFX_IMPL_XINTERFACE_2( SfxStatusDispatcher, OWeakObject, ::com::sun::star::frame::XNotifyingDispatch, ::com::sun::star::frame::XDispatch )
297cdf0e10cSrcweir SFX_IMPL_XTYPEPROVIDER_2( SfxStatusDispatcher, ::com::sun::star::frame::XNotifyingDispatch, ::com::sun::star::frame::XDispatch )
298cdf0e10cSrcweir //IMPLNAME "com.sun.star.comp.sfx2.StatusDispatcher",
299cdf0e10cSrcweir 
300cdf0e10cSrcweir SfxStatusDispatcher::SfxStatusDispatcher()
301cdf0e10cSrcweir 	: aListeners( aMutex )
302cdf0e10cSrcweir {
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
addStatusListener(const::com::sun::star::uno::Reference<::com::sun::star::frame::XStatusListener> & aListener,const::com::sun::star::util::URL & aURL)305cdf0e10cSrcweir void SAL_CALL SfxStatusDispatcher::addStatusListener(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > & aListener, const ::com::sun::star::util::URL& aURL) throw ( ::com::sun::star::uno::RuntimeException )
306cdf0e10cSrcweir {
307cdf0e10cSrcweir 	aListeners.addInterface( aURL.Complete, aListener );
308cdf0e10cSrcweir 	if ( aURL.Complete.compareToAscii(".uno:LifeTime")==0 )
309cdf0e10cSrcweir 	{
310cdf0e10cSrcweir 		::com::sun::star::frame::FeatureStateEvent aEvent;
311cdf0e10cSrcweir 		aEvent.FeatureURL = aURL;
312cdf0e10cSrcweir 		aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
313cdf0e10cSrcweir 		aEvent.IsEnabled = sal_True;
314cdf0e10cSrcweir 		aEvent.Requery = sal_False;
315cdf0e10cSrcweir 		aListener->statusChanged( aEvent );
316cdf0e10cSrcweir 	}
317cdf0e10cSrcweir }
318cdf0e10cSrcweir 
removeStatusListener(const::com::sun::star::uno::Reference<::com::sun::star::frame::XStatusListener> & aListener,const::com::sun::star::util::URL & aURL)319cdf0e10cSrcweir void SAL_CALL SfxStatusDispatcher::removeStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > & aListener, const ::com::sun::star::util::URL& aURL ) throw ( ::com::sun::star::uno::RuntimeException )
320cdf0e10cSrcweir {
321cdf0e10cSrcweir 	aListeners.removeInterface( aURL.Complete, aListener );
322cdf0e10cSrcweir }
323cdf0e10cSrcweir 
SFX_IMPL_XINTERFACE_1(SfxOfficeDispatch,SfxStatusDispatcher,::com::sun::star::lang::XUnoTunnel)324cdf0e10cSrcweir SFX_IMPL_XINTERFACE_1( SfxOfficeDispatch, SfxStatusDispatcher, ::com::sun::star::lang::XUnoTunnel )
325cdf0e10cSrcweir SFX_IMPL_XTYPEPROVIDER_2( SfxOfficeDispatch, ::com::sun::star::frame::XNotifyingDispatch, ::com::sun::star::lang::XUnoTunnel )
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 
328cdf0e10cSrcweir //-------------------------------------------------------------------------
329cdf0e10cSrcweir // XUnoTunnel
330cdf0e10cSrcweir sal_Int64 SAL_CALL SfxOfficeDispatch::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException)
331cdf0e10cSrcweir {
332cdf0e10cSrcweir     if ( aIdentifier == impl_getStaticIdentifier() )
333cdf0e10cSrcweir         return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
334cdf0e10cSrcweir     else
335cdf0e10cSrcweir         return 0;
336cdf0e10cSrcweir }
337cdf0e10cSrcweir 
338cdf0e10cSrcweir /* ASDBG
339cdf0e10cSrcweir void* SfxOfficeDispatch::getImplementation(Reflection *p)
340cdf0e10cSrcweir {
341cdf0e10cSrcweir 	if( p == ::getCppuType((const SfxOfficeDispatch*)0) )
342cdf0e10cSrcweir 		return this;
343cdf0e10cSrcweir 	else
344cdf0e10cSrcweir 		return ::cppu::OWeakObject::getImplementation(p);
345cdf0e10cSrcweir 
346cdf0e10cSrcweir }
347cdf0e10cSrcweir 
348cdf0e10cSrcweir Reflection* ::getCppuType((const SfxOfficeDispatch*)0)
349cdf0e10cSrcweir {
350cdf0e10cSrcweir 	static StandardClassReflection aRefl(
351cdf0e10cSrcweir 		0,
352cdf0e10cSrcweir 		createStandardClass(
353cdf0e10cSrcweir 			"SfxOfficeDispatch", ::cppu::OWeakObject::get::cppu::OWeakObjectIdlClass(),
354cdf0e10cSrcweir 			1,
355cdf0e10cSrcweir 			::getCppuType((const ::com::sun::star::frame::XDispatch*)0) ) );
356cdf0e10cSrcweir 	return &aRefl;
357cdf0e10cSrcweir }
358cdf0e10cSrcweir */
359cdf0e10cSrcweir 
SfxOfficeDispatch(SfxBindings & rBindings,SfxDispatcher * pDispat,const SfxSlot * pSlot,const::com::sun::star::util::URL & rURL)360cdf0e10cSrcweir SfxOfficeDispatch::SfxOfficeDispatch( SfxBindings& rBindings, SfxDispatcher* pDispat, const SfxSlot* pSlot, const ::com::sun::star::util::URL& rURL )
361cdf0e10cSrcweir {
362cdf0e10cSrcweir //    nOfficeDispatchCount++;
363cdf0e10cSrcweir 
364cdf0e10cSrcweir     // this object is an adapter that shows a ::com::sun::star::frame::XDispatch-Interface to the outside and uses a SfxControllerItem to monitor a state
365cdf0e10cSrcweir     pControllerItem = new SfxDispatchController_Impl( this, &rBindings, pDispat, pSlot, rURL );
366cdf0e10cSrcweir }
367cdf0e10cSrcweir 
SfxOfficeDispatch(SfxDispatcher * pDispat,const SfxSlot * pSlot,const::com::sun::star::util::URL & rURL)368cdf0e10cSrcweir SfxOfficeDispatch::SfxOfficeDispatch( SfxDispatcher* pDispat, const SfxSlot* pSlot, const ::com::sun::star::util::URL& rURL )
369cdf0e10cSrcweir {
370cdf0e10cSrcweir //    nOfficeDispatchCount++;
371cdf0e10cSrcweir 
372cdf0e10cSrcweir     // this object is an adapter that shows a ::com::sun::star::frame::XDispatch-Interface to the outside and uses a SfxControllerItem to monitor a state
373cdf0e10cSrcweir     pControllerItem = new SfxDispatchController_Impl( this, NULL, pDispat, pSlot, rURL );
374cdf0e10cSrcweir }
375cdf0e10cSrcweir 
~SfxOfficeDispatch()376cdf0e10cSrcweir SfxOfficeDispatch::~SfxOfficeDispatch()
377cdf0e10cSrcweir {
378cdf0e10cSrcweir //    --nOfficeDispatchCount;
379cdf0e10cSrcweir 
380cdf0e10cSrcweir     if ( pControllerItem )
381cdf0e10cSrcweir     {
382cdf0e10cSrcweir         // when dispatch object is released, destroy its connection to this object and destroy it
383cdf0e10cSrcweir         pControllerItem->UnBindController();
384cdf0e10cSrcweir         delete pControllerItem;
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir }
387cdf0e10cSrcweir 
impl_getStaticIdentifier()388cdf0e10cSrcweir const ::com::sun::star::uno::Sequence< sal_Int8 >& SfxOfficeDispatch::impl_getStaticIdentifier()
389cdf0e10cSrcweir {
390cdf0e10cSrcweir     // {38 57 CA 80 09 36 11 d4 83 FE 00 50 04 52 6B 21}
391cdf0e10cSrcweir     static sal_uInt8 pGUID[16] = { 0x38, 0x57, 0xCA, 0x80, 0x09, 0x36, 0x11, 0xd4, 0x83, 0xFE, 0x00, 0x50, 0x04, 0x52, 0x6B, 0x21 };
392cdf0e10cSrcweir     static ::com::sun::star::uno::Sequence< sal_Int8 > seqID((sal_Int8*)pGUID,16) ;
393cdf0e10cSrcweir     return seqID ;
394cdf0e10cSrcweir }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 
dispatch(const::com::sun::star::util::URL & aURL,const::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & aArgs)397cdf0e10cSrcweir void SAL_CALL SfxOfficeDispatch::dispatch( const ::com::sun::star::util::URL& aURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) throw ( ::com::sun::star::uno::RuntimeException )
398cdf0e10cSrcweir {
399cdf0e10cSrcweir     // ControllerItem is the Impl class
400cdf0e10cSrcweir     if ( pControllerItem )
401cdf0e10cSrcweir     {
402cdf0e10cSrcweir         // The JavaContext contains an interaction handler which is used when
403cdf0e10cSrcweir         // the creation of a Java Virtual Machine fails. The second parameter
404cdf0e10cSrcweir         // indicates, that there shall only be one user notification (message box)
405cdf0e10cSrcweir         // even if the same error (interaction) reoccurs. The effect is, that if a
406cdf0e10cSrcweir         // user selects a menu entry than they may get only one notification that
407cdf0e10cSrcweir         // a JRE is not selected.
408cdf0e10cSrcweir         com::sun::star::uno::ContextLayer layer(
409cdf0e10cSrcweir             new svt::JavaContext( com::sun::star::uno::getCurrentContext(),
410cdf0e10cSrcweir                                   true) );
411cdf0e10cSrcweir 
412cdf0e10cSrcweir         pControllerItem->dispatch( aURL, aArgs, ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchResultListener >() );
413cdf0e10cSrcweir     }
414cdf0e10cSrcweir }
415cdf0e10cSrcweir 
dispatchWithNotification(const::com::sun::star::util::URL & aURL,const::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & aArgs,const::com::sun::star::uno::Reference<::com::sun::star::frame::XDispatchResultListener> & rListener)416cdf0e10cSrcweir void SAL_CALL SfxOfficeDispatch::dispatchWithNotification( const ::com::sun::star::util::URL& aURL,
417cdf0e10cSrcweir         const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs,
418cdf0e10cSrcweir         const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchResultListener >& rListener ) throw( ::com::sun::star::uno::RuntimeException )
419cdf0e10cSrcweir {
420cdf0e10cSrcweir     // ControllerItem is the Impl class
421cdf0e10cSrcweir     if ( pControllerItem )
422cdf0e10cSrcweir     {
423cdf0e10cSrcweir         // see comment for SfxOfficeDispatch::dispatch
424cdf0e10cSrcweir         com::sun::star::uno::ContextLayer layer(
425cdf0e10cSrcweir             new svt::JavaContext( com::sun::star::uno::getCurrentContext(),
426cdf0e10cSrcweir                                   true) );
427cdf0e10cSrcweir 
428cdf0e10cSrcweir         pControllerItem->dispatch( aURL, aArgs, rListener );
429cdf0e10cSrcweir     }
430cdf0e10cSrcweir }
431cdf0e10cSrcweir 
addStatusListener(const::com::sun::star::uno::Reference<::com::sun::star::frame::XStatusListener> & aListener,const::com::sun::star::util::URL & aURL)432cdf0e10cSrcweir void SAL_CALL SfxOfficeDispatch::addStatusListener(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > & aListener, const ::com::sun::star::util::URL& aURL) throw ( ::com::sun::star::uno::RuntimeException )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir     GetListeners().addInterface( aURL.Complete, aListener );
435cdf0e10cSrcweir     if ( pControllerItem )
436cdf0e10cSrcweir     {
437cdf0e10cSrcweir         // ControllerItem is the Impl class
438cdf0e10cSrcweir         pControllerItem->addStatusListener( aListener, aURL );
439cdf0e10cSrcweir     }
440cdf0e10cSrcweir }
441cdf0e10cSrcweir 
GetDispatcher_Impl()442cdf0e10cSrcweir SfxDispatcher* SfxOfficeDispatch::GetDispatcher_Impl()
443cdf0e10cSrcweir {
444cdf0e10cSrcweir     return pControllerItem->GetDispatcher();
445cdf0e10cSrcweir }
446cdf0e10cSrcweir 
SetFrame(const::com::sun::star::uno::Reference<::com::sun::star::frame::XFrame> & xFrame)447cdf0e10cSrcweir void SfxOfficeDispatch::SetFrame(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
448cdf0e10cSrcweir {
449cdf0e10cSrcweir     if ( pControllerItem )
450cdf0e10cSrcweir         pControllerItem->SetFrame( xFrame );
451cdf0e10cSrcweir }
452cdf0e10cSrcweir 
SetMasterUnoCommand(sal_Bool bSet)453cdf0e10cSrcweir void SfxOfficeDispatch::SetMasterUnoCommand( sal_Bool bSet )
454cdf0e10cSrcweir {
455cdf0e10cSrcweir     if ( pControllerItem )
456cdf0e10cSrcweir         pControllerItem->setMasterSlaveCommand( bSet );
457cdf0e10cSrcweir }
458cdf0e10cSrcweir 
IsMasterUnoCommand() const459cdf0e10cSrcweir sal_Bool SfxOfficeDispatch::IsMasterUnoCommand() const
460cdf0e10cSrcweir {
461cdf0e10cSrcweir     if ( pControllerItem )
462cdf0e10cSrcweir         return pControllerItem->isMasterSlaveCommand();
463cdf0e10cSrcweir     return sal_False;
464cdf0e10cSrcweir }
465cdf0e10cSrcweir 
466cdf0e10cSrcweir // Determine if URL contains a master/slave command which must be handled a little bit different
IsMasterUnoCommand(const::com::sun::star::util::URL & aURL)467cdf0e10cSrcweir sal_Bool SfxOfficeDispatch::IsMasterUnoCommand( const ::com::sun::star::util::URL& aURL )
468cdf0e10cSrcweir {
469cdf0e10cSrcweir     if ( aURL.Protocol.equalsAscii( ".uno:" ) &&
470cdf0e10cSrcweir          ( aURL.Path.indexOf( '.' ) > 0 ))
471cdf0e10cSrcweir         return sal_True;
472cdf0e10cSrcweir 
473cdf0e10cSrcweir     return sal_False;
474cdf0e10cSrcweir }
475cdf0e10cSrcweir 
GetMasterUnoCommand(const::com::sun::star::util::URL & aURL)476cdf0e10cSrcweir rtl::OUString SfxOfficeDispatch::GetMasterUnoCommand( const ::com::sun::star::util::URL& aURL )
477cdf0e10cSrcweir {
478cdf0e10cSrcweir     rtl::OUString aMasterCommand;
479cdf0e10cSrcweir     if ( IsMasterUnoCommand( aURL ))
480cdf0e10cSrcweir     {
481cdf0e10cSrcweir         sal_Int32 nIndex = aURL.Path.indexOf( '.' );
482cdf0e10cSrcweir         if ( nIndex > 0 )
483cdf0e10cSrcweir             aMasterCommand = aURL.Path.copy( 0, nIndex );
484cdf0e10cSrcweir     }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir     return aMasterCommand;
487cdf0e10cSrcweir }
488cdf0e10cSrcweir 
SfxDispatchController_Impl(SfxOfficeDispatch * pDisp,SfxBindings * pBind,SfxDispatcher * pDispat,const SfxSlot * pSlot,const::com::sun::star::util::URL & rURL)489cdf0e10cSrcweir SfxDispatchController_Impl::SfxDispatchController_Impl(
490cdf0e10cSrcweir     SfxOfficeDispatch*                 pDisp,
491cdf0e10cSrcweir     SfxBindings*                       pBind,
492cdf0e10cSrcweir     SfxDispatcher*                     pDispat,
493cdf0e10cSrcweir     const SfxSlot*                     pSlot,
494cdf0e10cSrcweir     const ::com::sun::star::util::URL& rURL )
495cdf0e10cSrcweir     : aDispatchURL( rURL )
496cdf0e10cSrcweir     , pDispatcher( pDispat )
497cdf0e10cSrcweir     , pBindings( pBind )
498cdf0e10cSrcweir     , pLastState( 0 )
499cdf0e10cSrcweir     , nSlot( pSlot->GetSlotId() )
500cdf0e10cSrcweir     , pDispatch( pDisp )
501cdf0e10cSrcweir     , bMasterSlave( sal_False )
502cdf0e10cSrcweir     , bVisible( sal_True )
503cdf0e10cSrcweir     , pUnoName( pSlot->pUnoName )
504cdf0e10cSrcweir {
505cdf0e10cSrcweir     if ( aDispatchURL.Protocol.equalsAscii("slot:") && pUnoName )
506cdf0e10cSrcweir     {
507cdf0e10cSrcweir         ByteString aTmp(".uno:");
508cdf0e10cSrcweir         aTmp += pUnoName;
509cdf0e10cSrcweir         aDispatchURL.Complete = ::rtl::OUString::createFromAscii( aTmp.GetBuffer() );
510cdf0e10cSrcweir         Reference < ::com::sun::star::util::XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
511cdf0e10cSrcweir         xTrans->parseStrict( aDispatchURL );
512cdf0e10cSrcweir     }
513cdf0e10cSrcweir 
514cdf0e10cSrcweir     SetId( nSlot );
515cdf0e10cSrcweir     if ( pBindings )
516cdf0e10cSrcweir     {
517cdf0e10cSrcweir         // Bind immediately to enable the cache to recycle dispatches when asked for the same command
518cdf0e10cSrcweir         // a command in "slot" or in ".uno" notation must be treated as identical commands!
519cdf0e10cSrcweir         pBindings->ENTERREGISTRATIONS();
520cdf0e10cSrcweir         BindInternal_Impl( nSlot, pBindings );
521cdf0e10cSrcweir         pBindings->LEAVEREGISTRATIONS();
522cdf0e10cSrcweir     }
523cdf0e10cSrcweir }
524cdf0e10cSrcweir 
~SfxDispatchController_Impl()525cdf0e10cSrcweir SfxDispatchController_Impl::~SfxDispatchController_Impl()
526cdf0e10cSrcweir {
527cdf0e10cSrcweir 	if ( pLastState && !IsInvalidItem( pLastState ) )
528cdf0e10cSrcweir 		delete pLastState;
529cdf0e10cSrcweir 
530cdf0e10cSrcweir     if ( pDispatch )
531cdf0e10cSrcweir     {
532cdf0e10cSrcweir         // disconnect
533cdf0e10cSrcweir         pDispatch->pControllerItem = NULL;
534cdf0e10cSrcweir 
535cdf0e10cSrcweir         // force all listeners to release the dispatch object
536cdf0e10cSrcweir         ::com::sun::star::lang::EventObject aObject;
537cdf0e10cSrcweir         aObject.Source = (::cppu::OWeakObject*) pDispatch;
538cdf0e10cSrcweir         pDispatch->GetListeners().disposeAndClear( aObject );
539cdf0e10cSrcweir     }
540cdf0e10cSrcweir }
541cdf0e10cSrcweir 
SetFrame(const::com::sun::star::uno::Reference<::com::sun::star::frame::XFrame> & _xFrame)542cdf0e10cSrcweir void SfxDispatchController_Impl::SetFrame(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& _xFrame)
543cdf0e10cSrcweir {
544cdf0e10cSrcweir     xFrame = _xFrame;
545cdf0e10cSrcweir }
546cdf0e10cSrcweir 
setMasterSlaveCommand(sal_Bool bSet)547cdf0e10cSrcweir void SfxDispatchController_Impl::setMasterSlaveCommand( sal_Bool bSet )
548cdf0e10cSrcweir {
549cdf0e10cSrcweir     bMasterSlave = bSet;
550cdf0e10cSrcweir }
551cdf0e10cSrcweir 
isMasterSlaveCommand() const552cdf0e10cSrcweir sal_Bool SfxDispatchController_Impl::isMasterSlaveCommand() const
553cdf0e10cSrcweir {
554cdf0e10cSrcweir     return bMasterSlave;
555cdf0e10cSrcweir }
556cdf0e10cSrcweir 
UnBindController()557cdf0e10cSrcweir void SfxDispatchController_Impl::UnBindController()
558cdf0e10cSrcweir {
559cdf0e10cSrcweir     pDispatch = NULL;
560cdf0e10cSrcweir     if ( IsBound() )
561cdf0e10cSrcweir     {
562cdf0e10cSrcweir         GetBindings().ENTERREGISTRATIONS();
563cdf0e10cSrcweir         SfxControllerItem::UnBind();
564cdf0e10cSrcweir         GetBindings().LEAVEREGISTRATIONS();
565cdf0e10cSrcweir     }
566cdf0e10cSrcweir }
567cdf0e10cSrcweir 
addParametersToArgs(const com::sun::star::util::URL & aURL,::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & rArgs) const568cdf0e10cSrcweir void SfxDispatchController_Impl::addParametersToArgs( const com::sun::star::util::URL& aURL, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs ) const
569cdf0e10cSrcweir {
570cdf0e10cSrcweir     // Extract the parameter from the URL and put them into the property value sequence
571cdf0e10cSrcweir     sal_Int32 nQueryIndex = aURL.Complete.indexOf( '?' );
572cdf0e10cSrcweir     if ( nQueryIndex > 0 )
573cdf0e10cSrcweir     {
574cdf0e10cSrcweir         rtl::OUString aParamString( aURL.Complete.copy( nQueryIndex+1 ));
575cdf0e10cSrcweir         sal_Int32 nIndex = 0;
576cdf0e10cSrcweir         do
577cdf0e10cSrcweir         {
578cdf0e10cSrcweir             rtl::OUString aToken = aParamString.getToken( 0, '&', nIndex );
579cdf0e10cSrcweir 
580cdf0e10cSrcweir             sal_Int32 nParmIndex = 0;
581cdf0e10cSrcweir             rtl::OUString aParamType;
582cdf0e10cSrcweir             rtl::OUString aParamName = aToken.getToken( 0, '=', nParmIndex );
583cdf0e10cSrcweir             rtl::OUString aValue     = (nParmIndex!=-1) ? aToken.getToken( 0, '=', nParmIndex ) : ::rtl::OUString();
584cdf0e10cSrcweir 
585cdf0e10cSrcweir             if ( aParamName.getLength() > 0 )
586cdf0e10cSrcweir             {
587cdf0e10cSrcweir                 nParmIndex = 0;
588cdf0e10cSrcweir                 aToken = aParamName;
589cdf0e10cSrcweir                 aParamName = (nParmIndex!=-1) ? aToken.getToken( 0, ':', nParmIndex ) : ::rtl::OUString();
590cdf0e10cSrcweir                 aParamType = (nParmIndex!=-1) ? aToken.getToken( 0, ':', nParmIndex ) : ::rtl::OUString();
591cdf0e10cSrcweir             }
592cdf0e10cSrcweir 
593cdf0e10cSrcweir             sal_Int32 nLen = rArgs.getLength();
594cdf0e10cSrcweir             rArgs.realloc( nLen+1 );
595cdf0e10cSrcweir             rArgs[nLen].Name = aParamName;
596cdf0e10cSrcweir 
597cdf0e10cSrcweir             if ( aParamType.getLength() == 0 )
598cdf0e10cSrcweir             {
599cdf0e10cSrcweir                 // Default: LONG
600cdf0e10cSrcweir                 rArgs[nLen].Value <<= aValue.toInt32();
601cdf0e10cSrcweir             }
602cdf0e10cSrcweir             else if ( aParamType.equalsAsciiL( URLTypeNames[URLType_BOOL], 4 ))
603cdf0e10cSrcweir             {
604cdf0e10cSrcweir                 // sal_Bool support
605cdf0e10cSrcweir                 rArgs[nLen].Value <<= aValue.toBoolean();
606cdf0e10cSrcweir             }
607cdf0e10cSrcweir             else if ( aParamType.equalsAsciiL( URLTypeNames[URLType_BYTE], 4 ))
608cdf0e10cSrcweir             {
609cdf0e10cSrcweir                 // sal_uInt8 support
610cdf0e10cSrcweir                 rArgs[nLen].Value <<= sal_Int8( aValue.toInt32() );
611cdf0e10cSrcweir             }
612cdf0e10cSrcweir             else if ( aParamType.equalsAsciiL( URLTypeNames[URLType_LONG], 4 ))
613cdf0e10cSrcweir             {
614cdf0e10cSrcweir                 // LONG support
615cdf0e10cSrcweir                 rArgs[nLen].Value <<= aValue.toInt32();
616cdf0e10cSrcweir             }
617cdf0e10cSrcweir             else if ( aParamType.equalsAsciiL( URLTypeNames[URLType_SHORT], 5 ))
618cdf0e10cSrcweir             {
619cdf0e10cSrcweir                 // SHORT support
620cdf0e10cSrcweir                 rArgs[nLen].Value <<= sal_Int8( aValue.toInt32() );
621cdf0e10cSrcweir             }
622cdf0e10cSrcweir             else if ( aParamType.equalsAsciiL( URLTypeNames[URLType_HYPER], 5 ))
623cdf0e10cSrcweir             {
624cdf0e10cSrcweir                 // HYPER support
625cdf0e10cSrcweir                 rArgs[nLen].Value <<= aValue.toInt64();
626cdf0e10cSrcweir             }
627cdf0e10cSrcweir             else if ( aParamType.equalsAsciiL( URLTypeNames[URLType_FLOAT], 5 ))
628cdf0e10cSrcweir             {
629cdf0e10cSrcweir                 // FLOAT support
630cdf0e10cSrcweir                 rArgs[nLen].Value <<= aValue.toFloat();
631cdf0e10cSrcweir             }
632cdf0e10cSrcweir             else if ( aParamType.equalsAsciiL( URLTypeNames[URLType_STRING], 6 ))
633cdf0e10cSrcweir             {
634cdf0e10cSrcweir                 // STRING support
635cdf0e10cSrcweir                 rArgs[nLen].Value <<= rtl::OUString( INetURLObject::decode( aValue, '%', INetURLObject::DECODE_WITH_CHARSET ));
636cdf0e10cSrcweir             }
637cdf0e10cSrcweir             else if ( aParamType.equalsAsciiL( URLTypeNames[URLType_DOUBLE], 6))
638cdf0e10cSrcweir             {
639cdf0e10cSrcweir                 // DOUBLE support
640cdf0e10cSrcweir                 rArgs[nLen].Value <<= aValue.toDouble();
641cdf0e10cSrcweir             }
642cdf0e10cSrcweir         }
643cdf0e10cSrcweir         while ( nIndex >= 0 );
644cdf0e10cSrcweir     }
645cdf0e10cSrcweir }
646cdf0e10cSrcweir 
GetCoreMetric(SfxItemPool & rPool,sal_uInt16 nSlotId)647cdf0e10cSrcweir SfxMapUnit SfxDispatchController_Impl::GetCoreMetric( SfxItemPool& rPool, sal_uInt16 nSlotId )
648cdf0e10cSrcweir {
649cdf0e10cSrcweir     sal_uInt16 nWhich = rPool.GetWhich( nSlotId );
650cdf0e10cSrcweir     return rPool.GetMetric( nWhich );
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
getSlaveCommand(const::com::sun::star::util::URL & rURL)653cdf0e10cSrcweir rtl::OUString SfxDispatchController_Impl::getSlaveCommand( const ::com::sun::star::util::URL& rURL )
654cdf0e10cSrcweir {
655cdf0e10cSrcweir     rtl::OUString   aSlaveCommand;
656cdf0e10cSrcweir     sal_Int32       nIndex = rURL.Path.indexOf( '.' );
657cdf0e10cSrcweir     if (( nIndex > 0 ) && ( nIndex < rURL.Path.getLength() ))
658cdf0e10cSrcweir         aSlaveCommand = rURL.Path.copy( nIndex+1 );
659cdf0e10cSrcweir     return aSlaveCommand;
660cdf0e10cSrcweir }
661cdf0e10cSrcweir 
dispatch(const::com::sun::star::util::URL & aURL,const::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & aArgs,const::com::sun::star::uno::Reference<::com::sun::star::frame::XDispatchResultListener> & rListener)662cdf0e10cSrcweir void SAL_CALL SfxDispatchController_Impl::dispatch( const ::com::sun::star::util::URL& aURL,
663cdf0e10cSrcweir         const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs,
664cdf0e10cSrcweir         const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchResultListener >& rListener ) throw( ::com::sun::star::uno::RuntimeException )
665cdf0e10cSrcweir {
666cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
667cdf0e10cSrcweir     if (
668cdf0e10cSrcweir         pDispatch &&
669cdf0e10cSrcweir         (
670cdf0e10cSrcweir          (aURL.Protocol.equalsAsciiL( ".uno:", 5 ) && aURL.Path == aDispatchURL.Path) ||
671cdf0e10cSrcweir          (aURL.Protocol.equalsAsciiL( "slot:", 5 ) && aURL.Path.toInt32() == GetId())
672cdf0e10cSrcweir         )
673cdf0e10cSrcweir        )
674cdf0e10cSrcweir 	{
675cdf0e10cSrcweir         /*
676cdf0e10cSrcweir         if ( !IsBound() && pBindings )
677cdf0e10cSrcweir         {
678cdf0e10cSrcweir             pBindings->ENTERREGISTRATIONS();
679cdf0e10cSrcweir             BindInternal_Impl( nSlot, pBindings );
680cdf0e10cSrcweir             pBindings->LEAVEREGISTRATIONS();
681cdf0e10cSrcweir         } */
682cdf0e10cSrcweir 
683cdf0e10cSrcweir         if ( !pDispatcher && pBindings )
684cdf0e10cSrcweir             pDispatcher = GetBindings().GetDispatcher_Impl();
685cdf0e10cSrcweir 
686cdf0e10cSrcweir         ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > lNewArgs;
687cdf0e10cSrcweir         sal_Int32 nCount = aArgs.getLength();
688cdf0e10cSrcweir 
689cdf0e10cSrcweir         // Support for URL based arguments
690cdf0e10cSrcweir         INetURLObject aURLObj( aURL.Complete );
691cdf0e10cSrcweir         if ( aURLObj.HasParam() )
692cdf0e10cSrcweir             addParametersToArgs( aURL, lNewArgs );
693cdf0e10cSrcweir 
694cdf0e10cSrcweir         // Try to find call mode and frame name inside given arguments...
695cdf0e10cSrcweir         SfxCallMode nCall = SFX_CALLMODE_STANDARD;
696cdf0e10cSrcweir         sal_Int32   nMarkArg = -1;
697cdf0e10cSrcweir 
698cdf0e10cSrcweir         // Filter arguments which shouldn't be part of the sequence property value
699cdf0e10cSrcweir         sal_Bool    bTemp = sal_Bool();
700cdf0e10cSrcweir         sal_uInt16  nModifier(0);
701cdf0e10cSrcweir         std::vector< ::com::sun::star::beans::PropertyValue > aAddArgs;
702cdf0e10cSrcweir         for( sal_Int32 n=0; n<nCount; n++ )
703cdf0e10cSrcweir         {
704cdf0e10cSrcweir             const ::com::sun::star::beans::PropertyValue& rProp = aArgs[n];
705cdf0e10cSrcweir             if( rProp.Name.equalsAsciiL("SynchronMode",12))
706cdf0e10cSrcweir             {
707cdf0e10cSrcweir 				if( rProp.Value >>=bTemp )
708cdf0e10cSrcweir                 	nCall = bTemp ? SFX_CALLMODE_SYNCHRON : SFX_CALLMODE_ASYNCHRON;
709cdf0e10cSrcweir             }
710cdf0e10cSrcweir             else if( rProp.Name.equalsAsciiL("Bookmark",8))
711cdf0e10cSrcweir             {
712cdf0e10cSrcweir                 nMarkArg = n;
713cdf0e10cSrcweir                 aAddArgs.push_back( aArgs[n] );
714cdf0e10cSrcweir             }
715cdf0e10cSrcweir             else if( rProp.Name.equalsAsciiL("KeyModifier",11))
716cdf0e10cSrcweir                 rProp.Value >>= nModifier;
717cdf0e10cSrcweir             else
718cdf0e10cSrcweir                 aAddArgs.push_back( aArgs[n] );
719cdf0e10cSrcweir         }
720cdf0e10cSrcweir 
721cdf0e10cSrcweir         // Add needed arguments to sequence property value
722cdf0e10cSrcweir         sal_uInt32 nAddArgs = aAddArgs.size();
723cdf0e10cSrcweir         if ( nAddArgs > 0 )
724cdf0e10cSrcweir         {
725cdf0e10cSrcweir             sal_uInt32 nIndex( lNewArgs.getLength() );
726cdf0e10cSrcweir 
727cdf0e10cSrcweir             lNewArgs.realloc( lNewArgs.getLength()+aAddArgs.size() );
728cdf0e10cSrcweir             for ( sal_uInt32 i = 0; i < nAddArgs; i++ )
729cdf0e10cSrcweir                 lNewArgs[nIndex++] = aAddArgs[i];
730cdf0e10cSrcweir         }
731cdf0e10cSrcweir 
732cdf0e10cSrcweir         // Overwrite possible detected sychron argument, if real listener exists (currently no other way)
733cdf0e10cSrcweir         if ( rListener.is() )
734cdf0e10cSrcweir             nCall = SFX_CALLMODE_SYNCHRON;
735cdf0e10cSrcweir 
736cdf0e10cSrcweir         if( GetId() == SID_JUMPTOMARK && nMarkArg == - 1 )
737cdf0e10cSrcweir         {
738cdf0e10cSrcweir 			// we offer dispatches for SID_JUMPTOMARK if the URL points to a bookmark inside the document
739cdf0e10cSrcweir 			// so we must retrieve this as an argument from the parsed URL
740cdf0e10cSrcweir             lNewArgs.realloc( lNewArgs.getLength()+1 );
741cdf0e10cSrcweir             nMarkArg = lNewArgs.getLength()-1;
742cdf0e10cSrcweir 	        lNewArgs[nMarkArg].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Bookmark"));
743cdf0e10cSrcweir 	        lNewArgs[nMarkArg].Value <<= aURL.Mark;
744cdf0e10cSrcweir         }
745cdf0e10cSrcweir 
746cdf0e10cSrcweir         css::uno::Reference< css::frame::XFrame > xFrameRef(xFrame.get(), css::uno::UNO_QUERY);
747cdf0e10cSrcweir         if (! xFrameRef.is() && pDispatcher)
748cdf0e10cSrcweir         {
749cdf0e10cSrcweir             SfxViewFrame* pViewFrame = pDispatcher->GetFrame();
750cdf0e10cSrcweir             if (pViewFrame)
751cdf0e10cSrcweir                 xFrameRef = pViewFrame->GetFrame().GetFrameInterface();
752cdf0e10cSrcweir         }
753cdf0e10cSrcweir         SfxAllItemSet aInternalSet( SFX_APP()->GetPool() );
754cdf0e10cSrcweir         if (xFrameRef.is()) // an empty set is no problem ... but an empty frame reference can be a problem !
755cdf0e10cSrcweir             aInternalSet.Put( SfxUnoFrameItem( SID_FILLFRAME, xFrameRef ) );
756cdf0e10cSrcweir 
757cdf0e10cSrcweir         sal_Bool bSuccess = sal_False;
758cdf0e10cSrcweir         sal_Bool bFailure = sal_False;
759cdf0e10cSrcweir         const SfxPoolItem* pItem = NULL;
760cdf0e10cSrcweir         SfxShell* pShell( 0 );
761cdf0e10cSrcweir         // #i102619# Retrieve metric from shell before execution - the shell could be destroyed after execution
762cdf0e10cSrcweir         SfxMapUnit eMapUnit( SFX_MAPUNIT_100TH_MM );
763cdf0e10cSrcweir         if ( pDispatcher->GetBindings() )
764cdf0e10cSrcweir         {
765cdf0e10cSrcweir             if ( !pDispatcher->IsLocked( GetId() ) )
766cdf0e10cSrcweir             {
767cdf0e10cSrcweir                 const SfxSlot *pSlot = 0;
768cdf0e10cSrcweir                 if ( pDispatcher->GetShellAndSlot_Impl( GetId(), &pShell, &pSlot, sal_False,
769cdf0e10cSrcweir                         SFX_CALLMODE_MODAL==(nCall&SFX_CALLMODE_MODAL), sal_False ) )
770cdf0e10cSrcweir                 {
771cdf0e10cSrcweir                     if ( bMasterSlave )
772cdf0e10cSrcweir                     {
773cdf0e10cSrcweir                         // Extract slave command and add argument to the args list. Master slot MUST
774cdf0e10cSrcweir                         // have a argument that has the same name as the master slot and type is SfxStringItem.
775cdf0e10cSrcweir                         sal_Int32 nIndex = lNewArgs.getLength();
776cdf0e10cSrcweir                         lNewArgs.realloc( nIndex+1 );
777cdf0e10cSrcweir                         lNewArgs[nIndex].Name   = rtl::OUString::createFromAscii( pSlot->pUnoName );
778cdf0e10cSrcweir                         lNewArgs[nIndex].Value  = makeAny( SfxDispatchController_Impl::getSlaveCommand( aDispatchURL ));
779cdf0e10cSrcweir                     }
780cdf0e10cSrcweir 
781cdf0e10cSrcweir                     eMapUnit = GetCoreMetric( pShell->GetPool(), GetId() );
782cdf0e10cSrcweir                     SfxAllItemSet aSet( pShell->GetPool() );
783cdf0e10cSrcweir                     TransformParameters( GetId(), lNewArgs, aSet, pSlot );
784cdf0e10cSrcweir                     if ( aSet.Count() )
785cdf0e10cSrcweir                     {
786cdf0e10cSrcweir                         // execute with arguments - call directly
787cdf0e10cSrcweir                         pItem = pDispatcher->Execute( GetId(), nCall, &aSet, &aInternalSet, nModifier );
788cdf0e10cSrcweir                         bSuccess = (pItem != NULL);
789cdf0e10cSrcweir                     }
790cdf0e10cSrcweir                     else
791cdf0e10cSrcweir                     {
792cdf0e10cSrcweir                         // execute using bindings, enables support for toggle/enum etc.
793cdf0e10cSrcweir                         SfxRequest aReq( GetId(), nCall, pShell->GetPool() );
794cdf0e10cSrcweir                         aReq.SetModifier( nModifier );
795cdf0e10cSrcweir                         aReq.SetInternalArgs_Impl(aInternalSet);
796cdf0e10cSrcweir                         pDispatcher->GetBindings()->Execute_Impl( aReq, pSlot, pShell );
797cdf0e10cSrcweir                         pItem = aReq.GetReturnValue();
798cdf0e10cSrcweir                         bSuccess = aReq.IsDone() || pItem != NULL;
799cdf0e10cSrcweir                         bFailure = aReq.IsCancelled();
800cdf0e10cSrcweir                     }
801cdf0e10cSrcweir                 }
802cdf0e10cSrcweir #ifdef DBG_UTIL
803cdf0e10cSrcweir                 else
804cdf0e10cSrcweir                     DBG_WARNING("MacroPlayer: Unknown slot dispatched!");
805cdf0e10cSrcweir #endif
806cdf0e10cSrcweir             }
807cdf0e10cSrcweir         }
808cdf0e10cSrcweir         else
809cdf0e10cSrcweir         {
810cdf0e10cSrcweir             eMapUnit = GetCoreMetric( SFX_APP()->GetPool(), GetId() );
811cdf0e10cSrcweir             // AppDispatcher
812cdf0e10cSrcweir             SfxAllItemSet aSet( SFX_APP()->GetPool() );
813cdf0e10cSrcweir             TransformParameters( GetId(), lNewArgs, aSet );
814cdf0e10cSrcweir 
815cdf0e10cSrcweir             if ( aSet.Count() )
816cdf0e10cSrcweir                 pItem = pDispatcher->Execute( GetId(), nCall, &aSet, &aInternalSet, nModifier );
817cdf0e10cSrcweir             else
818cdf0e10cSrcweir                 // SfxRequests take empty sets as argument sets, GetArgs() returning non-zero!
819cdf0e10cSrcweir                 pItem = pDispatcher->Execute( GetId(), nCall, 0, &aInternalSet, nModifier );
820cdf0e10cSrcweir 
821cdf0e10cSrcweir             // no bindings, no invalidate ( usually done in SfxDispatcher::Call_Impl()! )
822cdf0e10cSrcweir 			if ( SfxApplication::Get() )
823cdf0e10cSrcweir 			{
824cdf0e10cSrcweir             	SfxDispatcher* pAppDispat = SFX_APP()->GetAppDispatcher_Impl();
825cdf0e10cSrcweir             	if ( pAppDispat )
826cdf0e10cSrcweir             	{
827cdf0e10cSrcweir                 	const SfxPoolItem* pState=0;
828cdf0e10cSrcweir                  	SfxItemState eState = pDispatcher->QueryState( GetId(), pState );
829cdf0e10cSrcweir                 	StateChanged( GetId(), eState, pState );
830cdf0e10cSrcweir             	}
831cdf0e10cSrcweir 			}
832cdf0e10cSrcweir 
833cdf0e10cSrcweir             bSuccess = (pItem != NULL);
834cdf0e10cSrcweir         }
835cdf0e10cSrcweir 
836cdf0e10cSrcweir         if ( rListener.is() )
837cdf0e10cSrcweir         {
838cdf0e10cSrcweir             ::com::sun::star::frame::DispatchResultEvent aEvent;
839cdf0e10cSrcweir             if ( bSuccess )
840cdf0e10cSrcweir                 aEvent.State = com::sun::star::frame::DispatchResultState::SUCCESS;
841cdf0e10cSrcweir //            else if ( bFailure )
842cdf0e10cSrcweir             else
843cdf0e10cSrcweir                 aEvent.State = com::sun::star::frame::DispatchResultState::FAILURE;
844cdf0e10cSrcweir //            else
845cdf0e10cSrcweir //                aEvent.State = com::sun::star::frame::DispatchResultState::DONTKNOW;
846cdf0e10cSrcweir 
847cdf0e10cSrcweir             aEvent.Source = (::com::sun::star::frame::XDispatch*) pDispatch;
848cdf0e10cSrcweir             if ( bSuccess && pItem && !pItem->ISA(SfxVoidItem) )
849cdf0e10cSrcweir             {
850cdf0e10cSrcweir                 sal_uInt16 nSubId( 0 );
851cdf0e10cSrcweir                 if ( eMapUnit == SFX_MAPUNIT_TWIP )
852cdf0e10cSrcweir                     nSubId |= CONVERT_TWIPS;
853cdf0e10cSrcweir                 pItem->QueryValue( aEvent.Result, (sal_uInt8)nSubId );
854cdf0e10cSrcweir             }
855cdf0e10cSrcweir 
856cdf0e10cSrcweir             rListener->dispatchFinished( aEvent );
857cdf0e10cSrcweir         }
858cdf0e10cSrcweir 	}
859cdf0e10cSrcweir }
860cdf0e10cSrcweir 
GetDispatcher()861cdf0e10cSrcweir SfxDispatcher* SfxDispatchController_Impl::GetDispatcher()
862cdf0e10cSrcweir {
863cdf0e10cSrcweir     if ( !pDispatcher && pBindings )
864cdf0e10cSrcweir         pDispatcher = GetBindings().GetDispatcher_Impl();
865cdf0e10cSrcweir     return pDispatcher;
866cdf0e10cSrcweir }
867cdf0e10cSrcweir 
addStatusListener(const::com::sun::star::uno::Reference<::com::sun::star::frame::XStatusListener> & aListener,const::com::sun::star::util::URL & aURL)868cdf0e10cSrcweir void SAL_CALL SfxDispatchController_Impl::addStatusListener(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > & aListener, const ::com::sun::star::util::URL& aURL) throw ( ::com::sun::star::uno::RuntimeException )
869cdf0e10cSrcweir {
870cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
871cdf0e10cSrcweir     if ( !pDispatch )
872cdf0e10cSrcweir         return;
873cdf0e10cSrcweir 
874cdf0e10cSrcweir     /*if ( !IsBound() && pBindings )
875cdf0e10cSrcweir     {
876cdf0e10cSrcweir         pBindings->ENTERREGISTRATIONS();
877cdf0e10cSrcweir         BindInternal_Impl( nSlot, pBindings );
878cdf0e10cSrcweir         pBindings->LEAVEREGISTRATIONS();
879cdf0e10cSrcweir     } */
880cdf0e10cSrcweir 
881cdf0e10cSrcweir     // Use alternative QueryState call to have a valid UNO representation of the state.
882cdf0e10cSrcweir     ::com::sun::star::uno::Any aState;
883cdf0e10cSrcweir     if ( !pDispatcher && pBindings )
884cdf0e10cSrcweir         pDispatcher = GetBindings().GetDispatcher_Impl();
885cdf0e10cSrcweir     SfxItemState eState = pDispatcher->QueryState( GetId(), aState );
886cdf0e10cSrcweir 
887cdf0e10cSrcweir     if ( eState == SFX_ITEM_DONTCARE )
888cdf0e10cSrcweir     {
889cdf0e10cSrcweir         // Use special uno struct to transport don't care state
890cdf0e10cSrcweir         ::com::sun::star::frame::status::ItemStatus aItemStatus;
891cdf0e10cSrcweir         aItemStatus.State = ::com::sun::star::frame::status::ItemState::dont_care;
892cdf0e10cSrcweir         aState = makeAny( aItemStatus );
893cdf0e10cSrcweir     }
894cdf0e10cSrcweir 
895cdf0e10cSrcweir     ::com::sun::star::frame::FeatureStateEvent  aEvent;
896cdf0e10cSrcweir     aEvent.FeatureURL = aURL;
897cdf0e10cSrcweir     aEvent.Source     = (::com::sun::star::frame::XDispatch*) pDispatch;
898cdf0e10cSrcweir     aEvent.Requery    = sal_False;
899cdf0e10cSrcweir     if ( bVisible )
900cdf0e10cSrcweir     {
901cdf0e10cSrcweir 	    aEvent.IsEnabled  = eState != SFX_ITEM_DISABLED;
902cdf0e10cSrcweir 	    aEvent.State      = aState;
903cdf0e10cSrcweir     }
904cdf0e10cSrcweir     else
905cdf0e10cSrcweir     {
906cdf0e10cSrcweir         ::com::sun::star::frame::status::Visibility aVisibilityStatus;
907cdf0e10cSrcweir         aVisibilityStatus.bVisible = sal_False;
908cdf0e10cSrcweir 
909cdf0e10cSrcweir         // MBA: we might decide to *not* disable "invisible" slots, but this would be
910cdf0e10cSrcweir         // a change that needs to adjust at least the testtool
911cdf0e10cSrcweir         aEvent.IsEnabled           = sal_False;
912cdf0e10cSrcweir         aEvent.State               = makeAny( aVisibilityStatus );
913cdf0e10cSrcweir     }
914cdf0e10cSrcweir 
915cdf0e10cSrcweir     aListener->statusChanged( aEvent );
916cdf0e10cSrcweir }
917cdf0e10cSrcweir 
StateChanged(sal_uInt16 nSID,SfxItemState eState,const SfxPoolItem * pState,SfxSlotServer * pSlotServ)918cdf0e10cSrcweir void SfxDispatchController_Impl::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState, SfxSlotServer* pSlotServ )
919cdf0e10cSrcweir {
920cdf0e10cSrcweir     if ( !pDispatch )
921cdf0e10cSrcweir         return;
922cdf0e10cSrcweir 
923cdf0e10cSrcweir     // Bindings instance notifies controller about a state change, listeners must be notified also
924cdf0e10cSrcweir     // Don't cache visibility state changes as they are volatile. We need our real state to send it
925cdf0e10cSrcweir     // to our controllers after visibility is set to true.
926cdf0e10cSrcweir 	sal_Bool bNotify = sal_True;
927cdf0e10cSrcweir     if ( pState && !IsInvalidItem( pState ) )
928cdf0e10cSrcweir     {
929cdf0e10cSrcweir         if ( !pState->ISA( SfxVisibilityItem ) )
930cdf0e10cSrcweir         {
931cdf0e10cSrcweir             sal_Bool bBothAvailable = pLastState && !IsInvalidItem(pLastState);
932cdf0e10cSrcweir             if ( bBothAvailable )
933cdf0e10cSrcweir                 bNotify = pState->Type() != pLastState->Type() || *pState != *pLastState;
934cdf0e10cSrcweir             if ( pLastState && !IsInvalidItem( pLastState ) )
935cdf0e10cSrcweir                 delete pLastState;
936cdf0e10cSrcweir             pLastState = !IsInvalidItem(pState) ? pState->Clone() : pState;
937cdf0e10cSrcweir             bVisible = sal_True;
938cdf0e10cSrcweir         }
939cdf0e10cSrcweir         else
940cdf0e10cSrcweir             bVisible = ((SfxVisibilityItem *)pState)->GetValue();
941cdf0e10cSrcweir     }
942cdf0e10cSrcweir     else
943cdf0e10cSrcweir     {
944cdf0e10cSrcweir         if ( pLastState && !IsInvalidItem( pLastState ) )
945cdf0e10cSrcweir             delete pLastState;
946cdf0e10cSrcweir         pLastState = pState;
947cdf0e10cSrcweir     }
948cdf0e10cSrcweir 
949cdf0e10cSrcweir     ::cppu::OInterfaceContainerHelper* pContnr = pDispatch->GetListeners().getContainer ( aDispatchURL.Complete );
950cdf0e10cSrcweir 	if ( bNotify && pContnr )
951cdf0e10cSrcweir 	{
952cdf0e10cSrcweir         ::com::sun::star::uno::Any aState;
953cdf0e10cSrcweir         if ( ( eState >= SFX_ITEM_AVAILABLE ) && pState && !IsInvalidItem( pState ) && !pState->ISA(SfxVoidItem) )
954cdf0e10cSrcweir         {
955cdf0e10cSrcweir             // Retrieve metric from pool to have correct sub ID when calling QueryValue
956cdf0e10cSrcweir             sal_uInt16     nSubId( 0 );
957cdf0e10cSrcweir             SfxMapUnit eMapUnit( SFX_MAPUNIT_100TH_MM );
958cdf0e10cSrcweir 
959cdf0e10cSrcweir             // retrieve the core metric
960cdf0e10cSrcweir             // it's enough to check the objectshell, the only shell that does not use the pool of the document
961cdf0e10cSrcweir             // is SfxViewFrame, but it hasn't any metric parameters
962cdf0e10cSrcweir             // TODO/LATER: what about the FormShell? Does it use any metric data?! Perhaps it should use the Pool of the document!
963cdf0e10cSrcweir             if ( pSlotServ && pDispatcher )
964cdf0e10cSrcweir             {
965cdf0e10cSrcweir                 SfxShell* pShell = pDispatcher->GetShell( pSlotServ->GetShellLevel() );
966cdf0e10cSrcweir                 DBG_ASSERT( pShell, "Can't get core metric without shell!" );
967cdf0e10cSrcweir                 if ( pShell )
968cdf0e10cSrcweir                     eMapUnit = GetCoreMetric( pShell->GetPool(), nSID );
969cdf0e10cSrcweir             }
970cdf0e10cSrcweir 
971cdf0e10cSrcweir             if ( eMapUnit == SFX_MAPUNIT_TWIP )
972cdf0e10cSrcweir                 nSubId |= CONVERT_TWIPS;
973cdf0e10cSrcweir 
974cdf0e10cSrcweir             pState->QueryValue( aState, (sal_uInt8)nSubId );
975cdf0e10cSrcweir         }
976cdf0e10cSrcweir         else if ( eState == SFX_ITEM_DONTCARE )
977cdf0e10cSrcweir         {
978cdf0e10cSrcweir             // Use special uno struct to transport don't care state
979cdf0e10cSrcweir             ::com::sun::star::frame::status::ItemStatus aItemStatus;
980cdf0e10cSrcweir             aItemStatus.State = ::com::sun::star::frame::status::ItemState::dont_care;
981cdf0e10cSrcweir             aState = makeAny( aItemStatus );
982cdf0e10cSrcweir         }
983cdf0e10cSrcweir 
984cdf0e10cSrcweir 		::com::sun::star::frame::FeatureStateEvent aEvent;
985cdf0e10cSrcweir 		aEvent.FeatureURL = aDispatchURL;
986cdf0e10cSrcweir         aEvent.Source = (::com::sun::star::frame::XDispatch*) pDispatch;
987cdf0e10cSrcweir 		aEvent.IsEnabled = eState != SFX_ITEM_DISABLED;
988cdf0e10cSrcweir 		aEvent.Requery = sal_False;
989cdf0e10cSrcweir 		aEvent.State = aState;
990cdf0e10cSrcweir 
991cdf0e10cSrcweir 		::cppu::OInterfaceIteratorHelper aIt( *pContnr );
992cdf0e10cSrcweir 		while( aIt.hasMoreElements() )
993cdf0e10cSrcweir         {
994cdf0e10cSrcweir             try
995cdf0e10cSrcweir             {
996cdf0e10cSrcweir                 ((::com::sun::star::frame::XStatusListener *)aIt.next())->statusChanged( aEvent );
997cdf0e10cSrcweir             }
998cdf0e10cSrcweir             catch( ::com::sun::star::uno::RuntimeException& )
999cdf0e10cSrcweir             {
1000cdf0e10cSrcweir                 aIt.remove();
1001cdf0e10cSrcweir             }
1002cdf0e10cSrcweir         }
1003cdf0e10cSrcweir 	}
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir 
StateChanged(sal_uInt16 nSID,SfxItemState eState,const SfxPoolItem * pState)1006cdf0e10cSrcweir void SfxDispatchController_Impl::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
1007cdf0e10cSrcweir {
1008cdf0e10cSrcweir     StateChanged( nSID, eState, pState, 0 );
1009cdf0e10cSrcweir }
1010