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 #ifdef SOLARIS
28cdf0e10cSrcweir // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
29cdf0e10cSrcweir #include <ctime>
30cdf0e10cSrcweir #endif
31cdf0e10cSrcweir
32cdf0e10cSrcweir #include <string> // HACK: prevent conflict between STLPORT and Workshop headers
33cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp>
34cdf0e10cSrcweir #include <com/sun/star/frame/XController.hpp>
35cdf0e10cSrcweir #include <com/sun/star/frame/XFrameActionListener.hpp>
36cdf0e10cSrcweir #include <com/sun/star/frame/XComponentLoader.hpp>
37cdf0e10cSrcweir #include <com/sun/star/frame/XFrame.hpp>
38cdf0e10cSrcweir #include <com/sun/star/frame/FrameActionEvent.hpp>
39cdf0e10cSrcweir #include <com/sun/star/frame/FrameAction.hpp>
40cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
41cdf0e10cSrcweir #include <cppuhelper/weak.hxx>
42cdf0e10cSrcweir #include <svl/eitem.hxx>
43cdf0e10cSrcweir #include <svl/intitem.hxx>
44cdf0e10cSrcweir #include <svl/stritem.hxx>
45cdf0e10cSrcweir #include <svl/visitem.hxx>
46cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
47cdf0e10cSrcweir
48cdf0e10cSrcweir #ifndef GCC
49cdf0e10cSrcweir #endif
50cdf0e10cSrcweir
51cdf0e10cSrcweir #include <sfx2/app.hxx>
52cdf0e10cSrcweir #include <sfx2/appuno.hxx>
53cdf0e10cSrcweir #include "statcach.hxx"
54cdf0e10cSrcweir #include <sfx2/msg.hxx>
55cdf0e10cSrcweir #include <sfx2/ctrlitem.hxx>
56cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
57cdf0e10cSrcweir #include "sfxtypes.hxx"
58cdf0e10cSrcweir #include <sfx2/sfxuno.hxx>
59cdf0e10cSrcweir #include <sfx2/unoctitm.hxx>
60cdf0e10cSrcweir #include <sfx2/msgpool.hxx>
61cdf0e10cSrcweir #include <sfx2/viewfrm.hxx>
62cdf0e10cSrcweir
63cdf0e10cSrcweir using namespace ::com::sun::star;
64cdf0e10cSrcweir using namespace ::com::sun::star::uno;
65cdf0e10cSrcweir using namespace ::com::sun::star::util;
66cdf0e10cSrcweir
67cdf0e10cSrcweir //====================================================================
68cdf0e10cSrcweir
69cdf0e10cSrcweir DBG_NAME(SfxStateCache)
DBG_NAME(SfxStateCacheSetState)70cdf0e10cSrcweir DBG_NAME(SfxStateCacheSetState)
71cdf0e10cSrcweir
72cdf0e10cSrcweir SFX_IMPL_XINTERFACE_2( BindDispatch_Impl, OWeakObject, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
73cdf0e10cSrcweir SFX_IMPL_XTYPEPROVIDER_2( BindDispatch_Impl, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
74cdf0e10cSrcweir
75cdf0e10cSrcweir //-----------------------------------------------------------------------------
76cdf0e10cSrcweir BindDispatch_Impl::BindDispatch_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > & rDisp, const ::com::sun::star::util::URL& rURL, SfxStateCache *pStateCache, const SfxSlot* pS )
77cdf0e10cSrcweir : xDisp( rDisp )
78cdf0e10cSrcweir , aURL( rURL )
79cdf0e10cSrcweir , pCache( pStateCache )
80cdf0e10cSrcweir , pSlot( pS )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir DBG_ASSERT( pCache && pSlot, "Invalid BindDispatch!");
83cdf0e10cSrcweir aStatus.IsEnabled = sal_True;
84cdf0e10cSrcweir }
85cdf0e10cSrcweir
disposing(const::com::sun::star::lang::EventObject &)86cdf0e10cSrcweir void SAL_CALL BindDispatch_Impl::disposing( const ::com::sun::star::lang::EventObject& ) throw( ::com::sun::star::uno::RuntimeException )
87cdf0e10cSrcweir {
88cdf0e10cSrcweir if ( xDisp.is() )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir xDisp->removeStatusListener( (::com::sun::star::frame::XStatusListener*) this, aURL );
91cdf0e10cSrcweir xDisp = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > ();
92cdf0e10cSrcweir }
93cdf0e10cSrcweir }
94cdf0e10cSrcweir
statusChanged(const::com::sun::star::frame::FeatureStateEvent & rEvent)95cdf0e10cSrcweir void SAL_CALL BindDispatch_Impl::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& rEvent ) throw( ::com::sun::star::uno::RuntimeException )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir aStatus = rEvent;
98cdf0e10cSrcweir if ( !pCache )
99cdf0e10cSrcweir return;
100cdf0e10cSrcweir
101cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > xRef( (::cppu::OWeakObject*)this, ::com::sun::star::uno::UNO_QUERY );
102cdf0e10cSrcweir if ( aStatus.Requery )
103cdf0e10cSrcweir pCache->Invalidate( sal_True );
104cdf0e10cSrcweir else
105cdf0e10cSrcweir {
106cdf0e10cSrcweir SfxPoolItem *pItem=NULL;
107cdf0e10cSrcweir sal_uInt16 nId = pCache->GetId();
108cdf0e10cSrcweir SfxItemState eState = SFX_ITEM_DISABLED;
109cdf0e10cSrcweir // pCache->Invalidate( sal_False );
110cdf0e10cSrcweir if ( !aStatus.IsEnabled )
111cdf0e10cSrcweir {
112cdf0e10cSrcweir // default
113cdf0e10cSrcweir }
114cdf0e10cSrcweir else if (aStatus.State.hasValue())
115cdf0e10cSrcweir {
116cdf0e10cSrcweir eState = SFX_ITEM_AVAILABLE;
117cdf0e10cSrcweir ::com::sun::star::uno::Any aAny = aStatus.State;
118cdf0e10cSrcweir
119cdf0e10cSrcweir ::com::sun::star::uno::Type pType = aAny.getValueType();
120cdf0e10cSrcweir if ( pType == ::getBooleanCppuType() )
121cdf0e10cSrcweir {
122cdf0e10cSrcweir sal_Bool bTemp = false;
123cdf0e10cSrcweir aAny >>= bTemp ;
124cdf0e10cSrcweir pItem = new SfxBoolItem( nId, bTemp );
125cdf0e10cSrcweir }
126cdf0e10cSrcweir else if ( pType == ::getCppuType((const sal_uInt16*)0) )
127cdf0e10cSrcweir {
128cdf0e10cSrcweir sal_uInt16 nTemp = 0;
129cdf0e10cSrcweir aAny >>= nTemp ;
130cdf0e10cSrcweir pItem = new SfxUInt16Item( nId, nTemp );
131cdf0e10cSrcweir }
132cdf0e10cSrcweir else if ( pType == ::getCppuType((const sal_uInt32*)0) )
133cdf0e10cSrcweir {
134cdf0e10cSrcweir sal_uInt32 nTemp = 0;
135cdf0e10cSrcweir aAny >>= nTemp ;
136cdf0e10cSrcweir pItem = new SfxUInt32Item( nId, nTemp );
137cdf0e10cSrcweir }
138cdf0e10cSrcweir else if ( pType == ::getCppuType((const ::rtl::OUString*)0) )
139cdf0e10cSrcweir {
140cdf0e10cSrcweir ::rtl::OUString sTemp ;
141cdf0e10cSrcweir aAny >>= sTemp ;
142cdf0e10cSrcweir pItem = new SfxStringItem( nId, sTemp );
143cdf0e10cSrcweir }
144cdf0e10cSrcweir else
145cdf0e10cSrcweir {
146cdf0e10cSrcweir if ( pSlot )
147cdf0e10cSrcweir pItem = pSlot->GetType()->CreateItem();
148cdf0e10cSrcweir if ( pItem )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir pItem->SetWhich( nId );
151cdf0e10cSrcweir pItem->PutValue( aAny );
152cdf0e10cSrcweir }
153cdf0e10cSrcweir else
154cdf0e10cSrcweir pItem = new SfxVoidItem( nId );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir }
157cdf0e10cSrcweir else
158cdf0e10cSrcweir {
159cdf0e10cSrcweir // DONTCARE status
160cdf0e10cSrcweir pItem = new SfxVoidItem(0);
161cdf0e10cSrcweir eState = SFX_ITEM_UNKNOWN;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir
164cdf0e10cSrcweir for ( SfxControllerItem *pCtrl = pCache->GetItemLink();
165cdf0e10cSrcweir pCtrl;
166cdf0e10cSrcweir pCtrl = pCtrl->GetItemLink() )
167cdf0e10cSrcweir pCtrl->StateChanged( nId, eState, pItem );
168cdf0e10cSrcweir
169cdf0e10cSrcweir delete pItem;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir }
172cdf0e10cSrcweir
Release()173cdf0e10cSrcweir void BindDispatch_Impl::Release()
174cdf0e10cSrcweir {
175cdf0e10cSrcweir if ( xDisp.is() )
176cdf0e10cSrcweir {
177cdf0e10cSrcweir xDisp->removeStatusListener( (::com::sun::star::frame::XStatusListener*) this, aURL );
178cdf0e10cSrcweir xDisp = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > ();
179cdf0e10cSrcweir }
180cdf0e10cSrcweir
181cdf0e10cSrcweir pCache = NULL;
182cdf0e10cSrcweir release();
183cdf0e10cSrcweir }
184cdf0e10cSrcweir
GetStatus() const185cdf0e10cSrcweir const ::com::sun::star::frame::FeatureStateEvent& BindDispatch_Impl::GetStatus() const
186cdf0e10cSrcweir {
187cdf0e10cSrcweir return aStatus;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir
Dispatch(uno::Sequence<beans::PropertyValue> aProps,sal_Bool bForceSynchron)190cdf0e10cSrcweir void BindDispatch_Impl::Dispatch( uno::Sequence < beans::PropertyValue > aProps, sal_Bool bForceSynchron )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir if ( xDisp.is() && aStatus.IsEnabled )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir sal_Int32 nLength = aProps.getLength();
195cdf0e10cSrcweir aProps.realloc(nLength+1);
196cdf0e10cSrcweir aProps[nLength].Name = DEFINE_CONST_UNICODE("SynchronMode");
197cdf0e10cSrcweir aProps[nLength].Value <<= bForceSynchron ;
198cdf0e10cSrcweir xDisp->dispatch( aURL, aProps );
199cdf0e10cSrcweir }
200cdf0e10cSrcweir }
201cdf0e10cSrcweir
202cdf0e10cSrcweir //--------------------------------------------------------------------
203cdf0e10cSrcweir
204cdf0e10cSrcweir /* Dieser Konstruktor fuer einen ungueltigen Cache, der sich also
205cdf0e10cSrcweir bei der ersten Anfrage zun"achst updated.
206cdf0e10cSrcweir */
207cdf0e10cSrcweir
SfxStateCache(sal_uInt16 nFuncId)208cdf0e10cSrcweir SfxStateCache::SfxStateCache( sal_uInt16 nFuncId ):
209cdf0e10cSrcweir pDispatch( 0 ),
210cdf0e10cSrcweir nId(nFuncId),
211cdf0e10cSrcweir pInternalController(0),
212cdf0e10cSrcweir pController(0),
213cdf0e10cSrcweir pLastItem( 0 ),
214cdf0e10cSrcweir eLastState( 0 ),
215cdf0e10cSrcweir bItemVisible( sal_True )
216cdf0e10cSrcweir {
217cdf0e10cSrcweir DBG_MEMTEST();
218cdf0e10cSrcweir DBG_CTOR(SfxStateCache, 0);
219cdf0e10cSrcweir bCtrlDirty = sal_True;
220cdf0e10cSrcweir bSlotDirty = sal_True;
221cdf0e10cSrcweir bItemDirty = sal_True;
222cdf0e10cSrcweir }
223cdf0e10cSrcweir
224cdf0e10cSrcweir //--------------------------------------------------------------------
225cdf0e10cSrcweir
226cdf0e10cSrcweir /* Der Destruktor pr"uft per Assertion, ob noch Controller angemeldet
227cdf0e10cSrcweir sind.
228cdf0e10cSrcweir */
229cdf0e10cSrcweir
~SfxStateCache()230cdf0e10cSrcweir SfxStateCache::~SfxStateCache()
231cdf0e10cSrcweir {
232cdf0e10cSrcweir DBG_MEMTEST();
233cdf0e10cSrcweir DBG_DTOR(SfxStateCache, 0);
234cdf0e10cSrcweir DBG_ASSERT( pController == 0 && pInternalController == 0, "es sind noch Controller angemeldet" );
235cdf0e10cSrcweir if ( !IsInvalidItem(pLastItem) )
236cdf0e10cSrcweir delete pLastItem;
237cdf0e10cSrcweir if ( pDispatch )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir pDispatch->Release();
240cdf0e10cSrcweir pDispatch = NULL;
241cdf0e10cSrcweir }
242cdf0e10cSrcweir }
243cdf0e10cSrcweir
244cdf0e10cSrcweir //--------------------------------------------------------------------
245cdf0e10cSrcweir // invalidates the cache (next request will force update)
Invalidate(sal_Bool bWithMsg)246cdf0e10cSrcweir void SfxStateCache::Invalidate( sal_Bool bWithMsg )
247cdf0e10cSrcweir {
248cdf0e10cSrcweir bCtrlDirty = sal_True;
249cdf0e10cSrcweir if ( bWithMsg )
250cdf0e10cSrcweir {
251cdf0e10cSrcweir bSlotDirty = sal_True;
252cdf0e10cSrcweir aSlotServ.SetSlot( 0 );
253cdf0e10cSrcweir if ( pDispatch )
254cdf0e10cSrcweir {
255cdf0e10cSrcweir pDispatch->Release();
256cdf0e10cSrcweir pDispatch = NULL;
257cdf0e10cSrcweir }
258cdf0e10cSrcweir }
259cdf0e10cSrcweir }
260cdf0e10cSrcweir
261cdf0e10cSrcweir //--------------------------------------------------------------------
262cdf0e10cSrcweir
263cdf0e10cSrcweir // gets the corresponding function from the dispatcher or the cache
264cdf0e10cSrcweir
GetSlotServer(SfxDispatcher & rDispat,const::com::sun::star::uno::Reference<::com::sun::star::frame::XDispatchProvider> & xProv)265cdf0e10cSrcweir const SfxSlotServer* SfxStateCache::GetSlotServer( SfxDispatcher &rDispat , const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > & xProv )
266cdf0e10cSrcweir {
267cdf0e10cSrcweir DBG_MEMTEST();
268cdf0e10cSrcweir DBG_CHKTHIS(SfxStateCache, 0);
269cdf0e10cSrcweir
270cdf0e10cSrcweir if ( bSlotDirty )
271cdf0e10cSrcweir {
272cdf0e10cSrcweir // get the SlotServer; we need it for internal controllers anyway, but also in most cases
273cdf0e10cSrcweir rDispat._FindServer( nId, aSlotServ, sal_False );
274cdf0e10cSrcweir
275cdf0e10cSrcweir DBG_ASSERT( !pDispatch, "Old Dispatch not removed!" );
276cdf0e10cSrcweir
277cdf0e10cSrcweir // we don't need to check the dispatch provider if we only have an internal controller
278cdf0e10cSrcweir if ( xProv.is() )
279cdf0e10cSrcweir {
280cdf0e10cSrcweir const SfxSlot* pSlot = aSlotServ.GetSlot();
281cdf0e10cSrcweir if ( !pSlot )
282cdf0e10cSrcweir // get the slot - even if it is disabled on the dispatcher
283cdf0e10cSrcweir pSlot = SfxSlotPool::GetSlotPool( rDispat.GetFrame() ).GetSlot( nId );
284cdf0e10cSrcweir
285cdf0e10cSrcweir if ( !pSlot || !pSlot->pUnoName )
286cdf0e10cSrcweir {
287cdf0e10cSrcweir bSlotDirty = sal_False;
288cdf0e10cSrcweir bCtrlDirty = sal_True;
289cdf0e10cSrcweir return aSlotServ.GetSlot()? &aSlotServ: 0;
290cdf0e10cSrcweir }
291cdf0e10cSrcweir
292cdf0e10cSrcweir // create the dispatch URL from the slot data
293cdf0e10cSrcweir ::com::sun::star::util::URL aURL;
294cdf0e10cSrcweir ::rtl::OUString aCmd = DEFINE_CONST_UNICODE(".uno:");
295cdf0e10cSrcweir aURL.Protocol = aCmd;
296cdf0e10cSrcweir aURL.Path = ::rtl::OUString::createFromAscii( pSlot->GetUnoName() );
297cdf0e10cSrcweir aCmd += aURL.Path;
298cdf0e10cSrcweir aURL.Complete = aCmd;
299cdf0e10cSrcweir aURL.Main = aCmd;
300cdf0e10cSrcweir
301cdf0e10cSrcweir // try to get a dispatch object for this command
302cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
303cdf0e10cSrcweir if ( xDisp.is() )
304cdf0e10cSrcweir {
305cdf0e10cSrcweir // test the dispatch object if it is just a wrapper for a SfxDispatcher
306cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel( xDisp, ::com::sun::star::uno::UNO_QUERY );
307cdf0e10cSrcweir SfxOfficeDispatch* pDisp = NULL;
308cdf0e10cSrcweir if ( xTunnel.is() )
309cdf0e10cSrcweir {
310cdf0e10cSrcweir sal_Int64 nImplementation = xTunnel->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier());
311cdf0e10cSrcweir pDisp = reinterpret_cast< SfxOfficeDispatch* >(sal::static_int_cast< sal_IntPtr >( nImplementation ));
312cdf0e10cSrcweir }
313cdf0e10cSrcweir
314cdf0e10cSrcweir if ( pDisp )
315cdf0e10cSrcweir {
316cdf0e10cSrcweir // The intercepting object is an SFX component
317cdf0e10cSrcweir // If this dispatch object does not use the wanted dispatcher or the AppDispatcher, it's treated like any other UNO component
318cdf0e10cSrcweir // (intercepting by internal dispatches)
319cdf0e10cSrcweir SfxDispatcher *pDispatcher = pDisp->GetDispatcher_Impl();
320cdf0e10cSrcweir if ( pDispatcher == &rDispat || pDispatcher == SFX_APP()->GetAppDispatcher_Impl() )
321cdf0e10cSrcweir {
322cdf0e10cSrcweir // so we can use it directly
323cdf0e10cSrcweir bSlotDirty = sal_False;
324cdf0e10cSrcweir bCtrlDirty = sal_True;
325cdf0e10cSrcweir return aSlotServ.GetSlot()? &aSlotServ: 0;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir }
328cdf0e10cSrcweir
329cdf0e10cSrcweir // so the dispatch object isn't a SfxDispatcher wrapper or it is one, but it uses another dispatcher, but not rDispat
330cdf0e10cSrcweir pDispatch = new BindDispatch_Impl( xDisp, aURL, this, pSlot );
331cdf0e10cSrcweir pDispatch->acquire();
332cdf0e10cSrcweir
333cdf0e10cSrcweir // flags must be set before adding StatusListener because the dispatch object will set the state
334cdf0e10cSrcweir bSlotDirty = sal_False;
335cdf0e10cSrcweir bCtrlDirty = sal_True;
336cdf0e10cSrcweir xDisp->addStatusListener( pDispatch, aURL );
337cdf0e10cSrcweir }
338cdf0e10cSrcweir else if ( rDispat.GetFrame() )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchProvider > xFrameProv(
341cdf0e10cSrcweir rDispat.GetFrame()->GetFrame().GetFrameInterface(), ::com::sun::star::uno::UNO_QUERY );
342cdf0e10cSrcweir if ( xFrameProv != xProv )
343cdf0e10cSrcweir return GetSlotServer( rDispat, xFrameProv );
344cdf0e10cSrcweir }
345cdf0e10cSrcweir }
346cdf0e10cSrcweir
347cdf0e10cSrcweir bSlotDirty = sal_False;
348cdf0e10cSrcweir bCtrlDirty = sal_True;
349cdf0e10cSrcweir }
350cdf0e10cSrcweir
351cdf0e10cSrcweir // we *always* return a SlotServer (if there is one); but in case of an external dispatch we might not use it
352cdf0e10cSrcweir // for the "real" (non internal) controllers
353cdf0e10cSrcweir return aSlotServ.GetSlot()? &aSlotServ: 0;
354cdf0e10cSrcweir }
355cdf0e10cSrcweir
356cdf0e10cSrcweir
357cdf0e10cSrcweir //--------------------------------------------------------------------
358cdf0e10cSrcweir
359cdf0e10cSrcweir // Status setzen in allen Controllern
360cdf0e10cSrcweir
SetState(SfxItemState eState,const SfxPoolItem * pState,sal_Bool bMaybeDirty)361cdf0e10cSrcweir void SfxStateCache::SetState
362cdf0e10cSrcweir (
363cdf0e10cSrcweir SfxItemState eState, // <SfxItemState> von 'pState'
364cdf0e10cSrcweir const SfxPoolItem* pState, // Status des Slots, ggf. 0 oder -1
365cdf0e10cSrcweir sal_Bool bMaybeDirty
366cdf0e10cSrcweir )
367cdf0e10cSrcweir
368cdf0e10cSrcweir /* [Beschreibung]
369cdf0e10cSrcweir
370cdf0e10cSrcweir Diese Methode verteilt die Status auf alle an dieser SID gebundenen
371cdf0e10cSrcweir <SfxControllerItem>s. Ist der Wert derselbe wie zuvor und wurde in-
372cdf0e10cSrcweir zwischen weder ein Controller angemeldet, noch ein Controller invalidiert,
373cdf0e10cSrcweir dann wird kein Wert weitergeleitet. Dadurch wird z.B. Flackern in
374cdf0e10cSrcweir ListBoxen vermieden.
375cdf0e10cSrcweir */
376cdf0e10cSrcweir
377cdf0e10cSrcweir {
378cdf0e10cSrcweir // if ( pDispatch )
379cdf0e10cSrcweir // return;
380cdf0e10cSrcweir SetState_Impl( eState, pState, bMaybeDirty );
381cdf0e10cSrcweir }
382cdf0e10cSrcweir
383cdf0e10cSrcweir //--------------------------------------------------------------------
384cdf0e10cSrcweir
SetVisibleState(sal_Bool bShow)385cdf0e10cSrcweir void SfxStateCache::SetVisibleState( sal_Bool bShow )
386cdf0e10cSrcweir {
387cdf0e10cSrcweir SfxItemState eState( SFX_ITEM_AVAILABLE );
388cdf0e10cSrcweir const SfxPoolItem* pState( NULL );
389cdf0e10cSrcweir sal_Bool bNotify( sal_False );
390cdf0e10cSrcweir sal_Bool bDeleteItem( sal_False );
391cdf0e10cSrcweir
392cdf0e10cSrcweir if ( bShow != bItemVisible )
393cdf0e10cSrcweir {
394cdf0e10cSrcweir bItemVisible = bShow;
395cdf0e10cSrcweir if ( bShow )
396cdf0e10cSrcweir {
397cdf0e10cSrcweir if ( IsInvalidItem(pLastItem) || ( pLastItem == NULL ))
398cdf0e10cSrcweir {
399cdf0e10cSrcweir pState = new SfxVoidItem( nId );
400cdf0e10cSrcweir bDeleteItem = sal_True;
401cdf0e10cSrcweir }
402cdf0e10cSrcweir else
403cdf0e10cSrcweir pState = pLastItem;
404cdf0e10cSrcweir
405cdf0e10cSrcweir eState = eLastState;
406cdf0e10cSrcweir bNotify = ( pState != 0 );
407cdf0e10cSrcweir }
408cdf0e10cSrcweir else
409cdf0e10cSrcweir {
410cdf0e10cSrcweir pState = new SfxVisibilityItem( nId, sal_False );
411cdf0e10cSrcweir bDeleteItem = sal_True;
412cdf0e10cSrcweir }
413cdf0e10cSrcweir
414cdf0e10cSrcweir // Controller updaten
415cdf0e10cSrcweir if ( !pDispatch && pController )
416cdf0e10cSrcweir {
417cdf0e10cSrcweir for ( SfxControllerItem *pCtrl = pController;
418cdf0e10cSrcweir pCtrl;
419cdf0e10cSrcweir pCtrl = pCtrl->GetItemLink() )
420cdf0e10cSrcweir pCtrl->StateChanged( nId, eState, pState );
421cdf0e10cSrcweir }
422cdf0e10cSrcweir
423cdf0e10cSrcweir if ( pInternalController )
424cdf0e10cSrcweir pInternalController->StateChanged( nId, eState, pState );
425cdf0e10cSrcweir
426cdf0e10cSrcweir if ( !bDeleteItem )
427cdf0e10cSrcweir delete pState;
428cdf0e10cSrcweir }
429cdf0e10cSrcweir }
430cdf0e10cSrcweir
431cdf0e10cSrcweir //--------------------------------------------------------------------
432cdf0e10cSrcweir
SetState_Impl(SfxItemState eState,const SfxPoolItem * pState,sal_Bool bMaybeDirty)433cdf0e10cSrcweir void SfxStateCache::SetState_Impl
434cdf0e10cSrcweir (
435cdf0e10cSrcweir SfxItemState eState, // <SfxItemState> von 'pState'
436cdf0e10cSrcweir const SfxPoolItem* pState, // Status des Slots, ggf. 0 oder -1
437cdf0e10cSrcweir sal_Bool bMaybeDirty
438cdf0e10cSrcweir )
439cdf0e10cSrcweir {
440cdf0e10cSrcweir (void)bMaybeDirty; //unused
441cdf0e10cSrcweir DBG_MEMTEST();
442cdf0e10cSrcweir DBG_CHKTHIS(SfxStateCache, 0);
443cdf0e10cSrcweir
444cdf0e10cSrcweir // wenn zwischen Enter- und LeaveRegistrations ein hartes Update kommt
445cdf0e10cSrcweir // k"onnen zwischenzeitlich auch Cached ohne Controller exisitieren
446cdf0e10cSrcweir if ( !pController && !pInternalController )
447cdf0e10cSrcweir return;
448cdf0e10cSrcweir
449cdf0e10cSrcweir DBG_ASSERT( bMaybeDirty || !bSlotDirty, "setting state of dirty message" );
450cdf0e10cSrcweir // DBG_ASSERT( bCtrlDirty || ( aSlotServ.GetSlot() && aSlotServ.GetSlot()->IsMode(SFX_SLOT_VOLATILE) ), ! Discussed with MBA
451cdf0e10cSrcweir // "setting state of non dirty controller" );
452cdf0e10cSrcweir DBG_ASSERT( SfxControllerItem::GetItemState(pState) == eState, "invalid SfxItemState" );
453cdf0e10cSrcweir DBG_PROFSTART(SfxStateCacheSetState);
454cdf0e10cSrcweir
455cdf0e10cSrcweir // m"ussen die Controller "uberhaupt benachrichtigt werden?
456cdf0e10cSrcweir bool bNotify = bItemDirty;
457cdf0e10cSrcweir if ( !bItemDirty )
458cdf0e10cSrcweir {
459cdf0e10cSrcweir bool bBothAvailable = pLastItem && pState &&
460cdf0e10cSrcweir !IsInvalidItem(pState) && !IsInvalidItem(pLastItem);
461cdf0e10cSrcweir DBG_ASSERT( !bBothAvailable || pState != pLastItem, "setting state with own item" );
462cdf0e10cSrcweir if ( bBothAvailable )
463cdf0e10cSrcweir bNotify = pState->Type() != pLastItem->Type() ||
464cdf0e10cSrcweir *pState != *pLastItem;
465cdf0e10cSrcweir else
466cdf0e10cSrcweir bNotify = ( pState != pLastItem ) || ( eState != eLastState );
467cdf0e10cSrcweir }
468cdf0e10cSrcweir
469cdf0e10cSrcweir if ( bNotify )
470cdf0e10cSrcweir {
471cdf0e10cSrcweir // Controller updaten
472cdf0e10cSrcweir if ( !pDispatch && pController )
473cdf0e10cSrcweir {
474cdf0e10cSrcweir for ( SfxControllerItem *pCtrl = pController;
475cdf0e10cSrcweir pCtrl;
476cdf0e10cSrcweir pCtrl = pCtrl->GetItemLink() )
477cdf0e10cSrcweir pCtrl->StateChanged( nId, eState, pState );
478cdf0e10cSrcweir }
479cdf0e10cSrcweir
480cdf0e10cSrcweir if ( pInternalController )
481cdf0e10cSrcweir ((SfxDispatchController_Impl *)pInternalController)->StateChanged( nId, eState, pState, &aSlotServ );
482cdf0e10cSrcweir
483cdf0e10cSrcweir // neuen Wert merken
484cdf0e10cSrcweir if ( !IsInvalidItem(pLastItem) )
485cdf0e10cSrcweir DELETEZ(pLastItem);
486cdf0e10cSrcweir if ( pState && !IsInvalidItem(pState) )
487cdf0e10cSrcweir pLastItem = pState->Clone();
488cdf0e10cSrcweir else
489cdf0e10cSrcweir pLastItem = 0;
490cdf0e10cSrcweir eLastState = eState;
491cdf0e10cSrcweir bItemDirty = sal_False;
492cdf0e10cSrcweir }
493cdf0e10cSrcweir
494cdf0e10cSrcweir bCtrlDirty = sal_False;
495cdf0e10cSrcweir DBG_PROFSTOP(SfxStateCacheSetState);
496cdf0e10cSrcweir }
497cdf0e10cSrcweir
498cdf0e10cSrcweir
499cdf0e10cSrcweir //--------------------------------------------------------------------
500cdf0e10cSrcweir
501cdf0e10cSrcweir // alten Status in allen Controllern nochmal setzen
502cdf0e10cSrcweir
SetCachedState(sal_Bool bAlways)503cdf0e10cSrcweir void SfxStateCache::SetCachedState( sal_Bool bAlways )
504cdf0e10cSrcweir {
505cdf0e10cSrcweir DBG_MEMTEST();
506cdf0e10cSrcweir DBG_CHKTHIS(SfxStateCache, 0);
507cdf0e10cSrcweir DBG_ASSERT(pController==NULL||pController->GetId()==nId, "Cache mit falschem ControllerItem" );
508cdf0e10cSrcweir DBG_PROFSTART(SfxStateCacheSetState);
509cdf0e10cSrcweir
510cdf0e10cSrcweir // nur updaten wenn cached item vorhanden und auch verarbeitbar
511cdf0e10cSrcweir // (Wenn der State gesendet wird, mu\s sichergestellt sein, da\s ein
512cdf0e10cSrcweir // Slotserver vorhanden ist, s. SfxControllerItem::GetCoreMetric() )
513cdf0e10cSrcweir if ( bAlways || ( !bItemDirty && !bSlotDirty ) )
514cdf0e10cSrcweir {
515cdf0e10cSrcweir // Controller updaten
516cdf0e10cSrcweir if ( !pDispatch && pController )
517cdf0e10cSrcweir {
518cdf0e10cSrcweir for ( SfxControllerItem *pCtrl = pController;
519cdf0e10cSrcweir pCtrl;
520cdf0e10cSrcweir pCtrl = pCtrl->GetItemLink() )
521cdf0e10cSrcweir pCtrl->StateChanged( nId, eLastState, pLastItem );
522cdf0e10cSrcweir }
523cdf0e10cSrcweir
524cdf0e10cSrcweir if ( pInternalController )
525cdf0e10cSrcweir ((SfxDispatchController_Impl *)pInternalController)->StateChanged( nId, eLastState, pLastItem, &aSlotServ );
526cdf0e10cSrcweir
527cdf0e10cSrcweir // Controller sind jetzt ok
528cdf0e10cSrcweir bCtrlDirty = sal_True;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir
531cdf0e10cSrcweir DBG_PROFSTOP(SfxStateCacheSetState);
532cdf0e10cSrcweir }
533cdf0e10cSrcweir
534cdf0e10cSrcweir
535cdf0e10cSrcweir //--------------------------------------------------------------------
536cdf0e10cSrcweir
537cdf0e10cSrcweir // FloatingWindows in allen Controls mit dieser Id zerstoeren
538cdf0e10cSrcweir
DeleteFloatingWindows()539cdf0e10cSrcweir void SfxStateCache::DeleteFloatingWindows()
540cdf0e10cSrcweir {
541cdf0e10cSrcweir DBG_MEMTEST();
542cdf0e10cSrcweir DBG_CHKTHIS(SfxStateCache, 0);
543cdf0e10cSrcweir
544cdf0e10cSrcweir SfxControllerItem *pNextCtrl=0;
545cdf0e10cSrcweir for ( SfxControllerItem *pCtrl=pController; pCtrl; pCtrl=pNextCtrl )
546cdf0e10cSrcweir {
547cdf0e10cSrcweir DBG_TRACE((ByteString("pCtrl: ").Append(ByteString::CreateFromInt64((sal_uIntPtr)pCtrl))).GetBuffer());
548cdf0e10cSrcweir pNextCtrl = pCtrl->GetItemLink();
549cdf0e10cSrcweir pCtrl->DeleteFloatingWindow();
550cdf0e10cSrcweir }
551cdf0e10cSrcweir }
552cdf0e10cSrcweir
GetDispatch() const553cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SfxStateCache::GetDispatch() const
554cdf0e10cSrcweir {
555cdf0e10cSrcweir if ( pDispatch )
556cdf0e10cSrcweir return pDispatch->xDisp;
557cdf0e10cSrcweir return ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > ();
558cdf0e10cSrcweir }
559cdf0e10cSrcweir
Dispatch(const SfxItemSet * pSet,sal_Bool bForceSynchron)560cdf0e10cSrcweir void SfxStateCache::Dispatch( const SfxItemSet* pSet, sal_Bool bForceSynchron )
561cdf0e10cSrcweir {
562cdf0e10cSrcweir // protect pDispatch against destruction in the call
563cdf0e10cSrcweir ::com::sun::star::uno::Reference < ::com::sun::star::frame::XStatusListener > xKeepAlive( pDispatch );
564cdf0e10cSrcweir if ( pDispatch )
565cdf0e10cSrcweir {
566cdf0e10cSrcweir uno::Sequence < beans::PropertyValue > aArgs;
567cdf0e10cSrcweir if (pSet)
568cdf0e10cSrcweir TransformItems( nId, *pSet, aArgs );
569cdf0e10cSrcweir pDispatch->Dispatch( aArgs, bForceSynchron );
570cdf0e10cSrcweir }
571cdf0e10cSrcweir }
572cdf0e10cSrcweir
573cdf0e10cSrcweir
574