Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #ifdef SOLARIS
22 : : #include <ctime>
23 : : #endif
24 : :
25 : : #include <string>
26 : : #include <com/sun/star/util/XURLTransformer.hpp>
27 : : #include <com/sun/star/frame/XController.hpp>
28 : : #include <com/sun/star/frame/XFrameActionListener.hpp>
29 : : #include <com/sun/star/frame/XComponentLoader.hpp>
30 : : #include <com/sun/star/frame/XFrame.hpp>
31 : : #include <com/sun/star/frame/FrameActionEvent.hpp>
32 : : #include <com/sun/star/frame/FrameAction.hpp>
33 : : #include <com/sun/star/beans/PropertyValue.hpp>
34 : : #include <cppuhelper/weak.hxx>
35 : : #include <svl/eitem.hxx>
36 : : #include <svl/intitem.hxx>
37 : : #include <svl/stritem.hxx>
38 : : #include <svl/visitem.hxx>
39 : : #include <comphelper/processfactory.hxx>
40 : :
41 : : #include <sfx2/app.hxx>
42 : : #include <sfx2/appuno.hxx>
43 : : #include "statcach.hxx"
44 : : #include <sfx2/msg.hxx>
45 : : #include <sfx2/ctrlitem.hxx>
46 : : #include <sfx2/dispatch.hxx>
47 : : #include "sfxtypes.hxx"
48 : : #include <sfx2/sfxuno.hxx>
49 : : #include <sfx2/unoctitm.hxx>
50 : : #include <sfx2/msgpool.hxx>
51 : : #include <sfx2/viewfrm.hxx>
52 : :
53 : : using namespace ::com::sun::star;
54 : : using namespace ::com::sun::star::uno;
55 : : using namespace ::com::sun::star::util;
56 : :
57 : : //====================================================================
58 : :
59 : : DBG_NAME(SfxStateCache)
60 : : DBG_NAME(SfxStateCacheSetState)
61 : :
62 [ # # ][ # # ]: 0 : SFX_IMPL_XINTERFACE_2( BindDispatch_Impl, OWeakObject, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
[ # # ]
63 [ # # ][ # # ]: 0 : SFX_IMPL_XTYPEPROVIDER_2( BindDispatch_Impl, ::com::sun::star::frame::XStatusListener, ::com::sun::star::lang::XEventListener )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
64 : :
65 : : //-----------------------------------------------------------------------------
66 : 0 : 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 )
67 : : : xDisp( rDisp )
68 : : , aURL( rURL )
69 : : , pCache( pStateCache )
70 [ # # ]: 0 : , pSlot( pS )
71 : : {
72 : : DBG_ASSERT( pCache && pSlot, "Invalid BindDispatch!");
73 : 0 : aStatus.IsEnabled = sal_True;
74 : 0 : }
75 : :
76 : 0 : void SAL_CALL BindDispatch_Impl::disposing( const ::com::sun::star::lang::EventObject& ) throw( ::com::sun::star::uno::RuntimeException )
77 : : {
78 [ # # ]: 0 : if ( xDisp.is() )
79 : : {
80 [ # # ]: 0 : xDisp->removeStatusListener( (::com::sun::star::frame::XStatusListener*) this, aURL );
81 [ # # ]: 0 : xDisp = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > ();
82 : : }
83 : 0 : }
84 : :
85 : 0 : void SAL_CALL BindDispatch_Impl::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& rEvent ) throw( ::com::sun::star::uno::RuntimeException )
86 : : {
87 [ # # ]: 0 : aStatus = rEvent;
88 [ # # ]: 0 : if ( !pCache )
89 : 0 : return;
90 : :
91 [ # # ]: 0 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > xRef( (::cppu::OWeakObject*)this, ::com::sun::star::uno::UNO_QUERY );
92 [ # # ]: 0 : if ( aStatus.Requery )
93 [ # # ]: 0 : pCache->Invalidate( sal_True );
94 : : else
95 : : {
96 : 0 : SfxPoolItem *pItem=NULL;
97 : 0 : sal_uInt16 nId = pCache->GetId();
98 : 0 : SfxItemState eState = SFX_ITEM_DISABLED;
99 [ # # ]: 0 : if ( !aStatus.IsEnabled )
100 : : {
101 : : // default
102 : : }
103 [ # # ]: 0 : else if (aStatus.State.hasValue())
104 : : {
105 : 0 : eState = SFX_ITEM_AVAILABLE;
106 : 0 : ::com::sun::star::uno::Any aAny = aStatus.State;
107 : :
108 : 0 : ::com::sun::star::uno::Type pType = aAny.getValueType();
109 [ # # ][ # # ]: 0 : if ( pType == ::getBooleanCppuType() )
110 : : {
111 : 0 : sal_Bool bTemp = false;
112 : 0 : aAny >>= bTemp ;
113 [ # # ][ # # ]: 0 : pItem = new SfxBoolItem( nId, bTemp );
114 : : }
115 [ # # ][ # # ]: 0 : else if ( pType == ::getCppuType((const sal_uInt16*)0) )
116 : : {
117 : 0 : sal_uInt16 nTemp = 0;
118 : 0 : aAny >>= nTemp ;
119 [ # # ][ # # ]: 0 : pItem = new SfxUInt16Item( nId, nTemp );
120 : : }
121 [ # # ][ # # ]: 0 : else if ( pType == ::getCppuType((const sal_uInt32*)0) )
122 : : {
123 : 0 : sal_uInt32 nTemp = 0;
124 : 0 : aAny >>= nTemp ;
125 [ # # ][ # # ]: 0 : pItem = new SfxUInt32Item( nId, nTemp );
126 : : }
127 [ # # ][ # # ]: 0 : else if ( pType == ::getCppuType((const ::rtl::OUString*)0) )
128 : : {
129 : 0 : ::rtl::OUString sTemp ;
130 : 0 : aAny >>= sTemp ;
131 [ # # ][ # # ]: 0 : pItem = new SfxStringItem( nId, sTemp );
[ # # ][ # # ]
132 : : }
133 : : else
134 : : {
135 [ # # ]: 0 : if ( pSlot )
136 [ # # ]: 0 : pItem = pSlot->GetType()->CreateItem();
137 [ # # ]: 0 : if ( pItem )
138 : : {
139 : 0 : pItem->SetWhich( nId );
140 [ # # ]: 0 : pItem->PutValue( aAny );
141 : : }
142 : : else
143 [ # # ][ # # ]: 0 : pItem = new SfxVoidItem( nId );
144 : 0 : }
145 : : }
146 : : else
147 : : {
148 : : // DONTCARE status
149 [ # # ][ # # ]: 0 : pItem = new SfxVoidItem(0);
150 : 0 : eState = SFX_ITEM_UNKNOWN;
151 : : }
152 : :
153 [ # # ][ # # ]: 0 : for ( SfxControllerItem *pCtrl = pCache->GetItemLink();
154 : : pCtrl;
155 : : pCtrl = pCtrl->GetItemLink() )
156 [ # # ]: 0 : pCtrl->StateChanged( nId, eState, pItem );
157 : :
158 [ # # ][ # # ]: 0 : delete pItem;
159 : 0 : }
160 : : }
161 : :
162 : 0 : void BindDispatch_Impl::Release()
163 : : {
164 [ # # ]: 0 : if ( xDisp.is() )
165 : : {
166 [ # # ]: 0 : xDisp->removeStatusListener( (::com::sun::star::frame::XStatusListener*) this, aURL );
167 [ # # ]: 0 : xDisp = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > ();
168 : : }
169 : :
170 : 0 : pCache = NULL;
171 : 0 : release();
172 : 0 : }
173 : :
174 : 0 : const ::com::sun::star::frame::FeatureStateEvent& BindDispatch_Impl::GetStatus() const
175 : : {
176 : 0 : return aStatus;
177 : : }
178 : :
179 : 0 : void BindDispatch_Impl::Dispatch( uno::Sequence < beans::PropertyValue > aProps, sal_Bool bForceSynchron )
180 : : {
181 [ # # ][ # # ]: 0 : if ( xDisp.is() && aStatus.IsEnabled )
[ # # ]
182 : : {
183 : 0 : sal_Int32 nLength = aProps.getLength();
184 : 0 : aProps.realloc(nLength+1);
185 [ # # ][ # # ]: 0 : aProps[nLength].Name = DEFINE_CONST_UNICODE("SynchronMode");
186 : 0 : aProps[nLength].Value <<= bForceSynchron ;
187 : 0 : xDisp->dispatch( aURL, aProps );
188 : : }
189 : 0 : }
190 : :
191 : : //--------------------------------------------------------------------
192 : : // This constructor for an invalid cache that is updated in the first request.
193 : :
194 : 130714 : SfxStateCache::SfxStateCache( sal_uInt16 nFuncId ):
195 : : pDispatch( 0 ),
196 : : nId(nFuncId),
197 : : pInternalController(0),
198 : : pController(0),
199 : : pLastItem( 0 ),
200 : : eLastState( 0 ),
201 : 130714 : bItemVisible( sal_True )
202 : : {
203 : : DBG_CTOR(SfxStateCache, 0);
204 : 130714 : bCtrlDirty = sal_True;
205 : 130714 : bSlotDirty = sal_True;
206 : 130714 : bItemDirty = sal_True;
207 : 130714 : }
208 : :
209 : : //--------------------------------------------------------------------
210 : : // The Destructor checks by assertion, even if controllers are registered.
211 : :
212 : 129514 : SfxStateCache::~SfxStateCache()
213 : : {
214 : : DBG_DTOR(SfxStateCache, 0);
215 : : DBG_ASSERT( pController == 0 && pInternalController == 0, "there are still Controllers registered" );
216 [ + - ]: 129514 : if ( !IsInvalidItem(pLastItem) )
217 [ + + ][ + - ]: 129514 : delete pLastItem;
218 [ - + ]: 129514 : if ( pDispatch )
219 : : {
220 [ # # ]: 0 : pDispatch->Release();
221 : 0 : pDispatch = NULL;
222 : : }
223 : 129514 : }
224 : :
225 : : //--------------------------------------------------------------------
226 : : // invalidates the cache (next request will force update)
227 : 346148 : void SfxStateCache::Invalidate( sal_Bool bWithMsg )
228 : : {
229 : 346148 : bCtrlDirty = sal_True;
230 [ + + ]: 346148 : if ( bWithMsg )
231 : : {
232 : 106975 : bSlotDirty = sal_True;
233 : 106975 : aSlotServ.SetSlot( 0 );
234 [ - + ]: 106975 : if ( pDispatch )
235 : : {
236 : 0 : pDispatch->Release();
237 : 0 : pDispatch = NULL;
238 : : }
239 : : }
240 : 346148 : }
241 : :
242 : : //--------------------------------------------------------------------
243 : : // gets the corresponding function from the dispatcher or the cache
244 : :
245 : 347570 : const SfxSlotServer* SfxStateCache::GetSlotServer( SfxDispatcher &rDispat , const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > & xProv )
246 : : {
247 : : DBG_CHKTHIS(SfxStateCache, 0);
248 : :
249 [ + + ]: 347570 : if ( bSlotDirty )
250 : : {
251 : : // get the SlotServer; we need it for internal controllers anyway, but also in most cases
252 : 104108 : rDispat._FindServer( nId, aSlotServ, sal_False );
253 : :
254 : : DBG_ASSERT( !pDispatch, "Old Dispatch not removed!" );
255 : :
256 : : // we don't need to check the dispatch provider if we only have an internal controller
257 [ + - ]: 104108 : if ( xProv.is() )
258 : : {
259 : 104108 : const SfxSlot* pSlot = aSlotServ.GetSlot();
260 [ + + ]: 104108 : if ( !pSlot )
261 : : // get the slot - even if it is disabled on the dispatcher
262 [ + - ][ + - ]: 1825 : pSlot = SfxSlotPool::GetSlotPool( rDispat.GetFrame() ).GetSlot( nId );
[ + - ]
263 : :
264 [ + + ][ - + ]: 104108 : if ( !pSlot || !pSlot->pUnoName )
265 : : {
266 : 196 : bSlotDirty = sal_False;
267 : 196 : bCtrlDirty = sal_True;
268 [ - + ]: 196 : return aSlotServ.GetSlot()? &aSlotServ: 0;
269 : : }
270 : :
271 : : // create the dispatch URL from the slot data
272 : 103912 : ::com::sun::star::util::URL aURL;
273 [ + - ][ + - ]: 103912 : ::rtl::OUString aCmd = DEFINE_CONST_UNICODE(".uno:");
[ + - ]
274 : 103912 : aURL.Protocol = aCmd;
275 : 103912 : aURL.Path = ::rtl::OUString::createFromAscii( pSlot->GetUnoName() );
276 : 103912 : aCmd += aURL.Path;
277 : 103912 : aURL.Complete = aCmd;
278 : 103912 : aURL.Main = aCmd;
279 : :
280 : : // try to get a dispatch object for this command
281 [ + - ][ + - ]: 103912 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
282 [ + - ]: 103912 : if ( xDisp.is() )
283 : : {
284 : : // test the dispatch object if it is just a wrapper for a SfxDispatcher
285 [ + - ]: 103912 : ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel( xDisp, ::com::sun::star::uno::UNO_QUERY );
286 : 103912 : SfxOfficeDispatch* pDisp = NULL;
287 [ + - ]: 103912 : if ( xTunnel.is() )
288 : : {
289 [ + - ][ + - ]: 103912 : sal_Int64 nImplementation = xTunnel->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier());
[ + - ]
290 : 103912 : pDisp = reinterpret_cast< SfxOfficeDispatch* >(sal::static_int_cast< sal_IntPtr >( nImplementation ));
291 : : }
292 : :
293 [ + - ]: 103912 : if ( pDisp )
294 : : {
295 : : // The intercepting object is an SFX component
296 : : // If this dispatch object does not use the wanted dispatcher or the AppDispatcher, it's treated like any other UNO component
297 : : // (intercepting by internal dispatches)
298 [ + - ]: 103912 : SfxDispatcher *pDispatcher = pDisp->GetDispatcher_Impl();
299 [ - + ][ # # ]: 103912 : if ( pDispatcher == &rDispat || pDispatcher == SFX_APP()->GetAppDispatcher_Impl() )
[ # # ][ # # ]
[ + - ]
300 : : {
301 : : // so we can use it directly
302 : 103912 : bSlotDirty = sal_False;
303 : 103912 : bCtrlDirty = sal_True;
304 [ + + ]: 103912 : return aSlotServ.GetSlot()? &aSlotServ: 0;
305 : : }
306 : : }
307 : :
308 : : // so the dispatch object isn't a SfxDispatcher wrapper or it is one, but it uses another dispatcher, but not rDispat
309 [ # # ]: 0 : pDispatch = new BindDispatch_Impl( xDisp, aURL, this, pSlot );
310 : 0 : pDispatch->acquire();
311 : :
312 : : // flags must be set before adding StatusListener because the dispatch object will set the state
313 : 0 : bSlotDirty = sal_False;
314 : 0 : bCtrlDirty = sal_True;
315 [ # # ][ # # ]: 103912 : xDisp->addStatusListener( pDispatch, aURL );
[ - + ][ # # ]
316 : : }
317 [ # # ][ # # ]: 0 : else if ( rDispat.GetFrame() )
318 : : {
319 : : ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchProvider > xFrameProv(
320 [ # # ][ # # ]: 0 : rDispat.GetFrame()->GetFrame().GetFrameInterface(), ::com::sun::star::uno::UNO_QUERY );
[ # # ][ # # ]
321 [ # # ][ # # ]: 0 : if ( xFrameProv != xProv )
322 [ # # ][ # # ]: 0 : return GetSlotServer( rDispat, xFrameProv );
323 [ + - ][ + - ]: 104108 : }
[ - + ]
324 : : }
325 : :
326 : 0 : bSlotDirty = sal_False;
327 : 0 : bCtrlDirty = sal_True;
328 : : }
329 : :
330 : : // we *always* return a SlotServer (if there is one); but in case of an external dispatch we might not use it
331 : : // for the "real" (non internal) controllers
332 [ + + ]: 347570 : return aSlotServ.GetSlot()? &aSlotServ: 0;
333 : : }
334 : :
335 : :
336 : : //--------------------------------------------------------------------
337 : :
338 : : // Set Status in all Controllers
339 : :
340 : 118744 : void SfxStateCache::SetState
341 : : (
342 : : SfxItemState eState, // <SfxItemState> from 'pState'
343 : : const SfxPoolItem* pState, // Slot Status, 0 or -1
344 : : sal_Bool bMaybeDirty
345 : : )
346 : :
347 : : /* [Description]
348 : :
349 : : This method distributes the status of all of this SID bound
350 : : <SfxControllerItem>s. If the value is the same as before, and if neither
351 : : controller was registered nor invalidated inbetween, then no value is
352 : : passed. This way the flickering is for example avoided in ListBoxes.
353 : : */
354 : : {
355 : 118744 : SetState_Impl( eState, pState, bMaybeDirty );
356 : 118744 : }
357 : :
358 : : //--------------------------------------------------------------------
359 : :
360 : 0 : void SfxStateCache::SetVisibleState( sal_Bool bShow )
361 : : {
362 : 0 : SfxItemState eState( SFX_ITEM_AVAILABLE );
363 : 0 : const SfxPoolItem* pState( NULL );
364 : 0 : sal_Bool bDeleteItem( sal_False );
365 : :
366 [ # # ]: 0 : if ( bShow != bItemVisible )
367 : : {
368 : 0 : bItemVisible = bShow;
369 [ # # ]: 0 : if ( bShow )
370 : : {
371 [ # # ][ # # ]: 0 : if ( IsInvalidItem(pLastItem) || ( pLastItem == NULL ))
[ # # ]
372 : : {
373 [ # # ]: 0 : pState = new SfxVoidItem( nId );
374 : 0 : bDeleteItem = sal_True;
375 : : }
376 : : else
377 : 0 : pState = pLastItem;
378 : :
379 : 0 : eState = eLastState;
380 : : }
381 : : else
382 : : {
383 [ # # ]: 0 : pState = new SfxVisibilityItem( nId, sal_False );
384 : 0 : bDeleteItem = sal_True;
385 : : }
386 : :
387 : : // Update Controller
388 [ # # ][ # # ]: 0 : if ( !pDispatch && pController )
389 : : {
390 [ # # ]: 0 : for ( SfxControllerItem *pCtrl = pController;
391 : : pCtrl;
392 : : pCtrl = pCtrl->GetItemLink() )
393 : 0 : pCtrl->StateChanged( nId, eState, pState );
394 : : }
395 : :
396 [ # # ]: 0 : if ( pInternalController )
397 : 0 : pInternalController->StateChanged( nId, eState, pState );
398 : :
399 [ # # ]: 0 : if ( bDeleteItem )
400 [ # # ]: 0 : delete pState;
401 : : }
402 : 0 : }
403 : :
404 : : //--------------------------------------------------------------------
405 : :
406 : 118744 : void SfxStateCache::SetState_Impl
407 : : (
408 : : SfxItemState eState, // <SfxItemState> from 'pState'
409 : : const SfxPoolItem* pState, // Slot Status, 0 or -1
410 : : sal_Bool bMaybeDirty
411 : : )
412 : : {
413 : : (void)bMaybeDirty; //unused
414 : : DBG_CHKTHIS(SfxStateCache, 0);
415 : :
416 : : // If a hard update occurs between enter- and leave-registrations is a
417 : : // can also intermediate Cached exist without controller.
418 [ + + ][ - + ]: 118744 : if ( !pController && !pInternalController )
419 : 118744 : return;
420 : :
421 : : DBG_ASSERT( bMaybeDirty || !bSlotDirty, "setting state of dirty message" );
422 : : DBG_ASSERT( SfxControllerItem::GetItemState(pState) == eState, "invalid SfxItemState" );
423 : : DBG_PROFSTART(SfxStateCacheSetState);
424 : :
425 : : // does the controller have to be notified at all?
426 : 118744 : bool bNotify = bItemDirty;
427 [ + + ]: 118744 : if ( !bItemDirty )
428 : : {
429 : : bool bBothAvailable = pLastItem && pState &&
430 [ + + ][ + + ]: 54990 : !IsInvalidItem(pState) && !IsInvalidItem(pLastItem);
[ + - ][ + - ]
431 : : DBG_ASSERT( !bBothAvailable || pState != pLastItem, "setting state with own item" );
432 [ + + ]: 54990 : if ( bBothAvailable )
433 : 48096 : bNotify = pState->Type() != pLastItem->Type() ||
434 [ + + ][ + - ]: 48096 : *pState != *pLastItem;
435 : : else
436 [ + + ][ - + ]: 6894 : bNotify = ( pState != pLastItem ) || ( eState != eLastState );
437 : : }
438 : :
439 [ + + ]: 118744 : if ( bNotify )
440 : : {
441 : : // Update Controller
442 [ + - ][ + + ]: 64705 : if ( !pDispatch && pController )
443 : : {
444 [ + + ]: 24086 : for ( SfxControllerItem *pCtrl = pController;
445 : : pCtrl;
446 : : pCtrl = pCtrl->GetItemLink() )
447 : 13482 : pCtrl->StateChanged( nId, eState, pState );
448 : : }
449 : :
450 [ + + ]: 64705 : if ( pInternalController )
451 : 64597 : ((SfxDispatchController_Impl *)pInternalController)->StateChanged( nId, eState, pState, &aSlotServ );
452 : :
453 : : // Remember new value
454 [ + - ]: 64705 : if ( !IsInvalidItem(pLastItem) )
455 [ + + ]: 64705 : DELETEZ(pLastItem);
456 [ + + ][ + + ]: 64705 : if ( pState && !IsInvalidItem(pState) )
[ + + ]
457 : 53897 : pLastItem = pState->Clone();
458 : : else
459 : 10808 : pLastItem = 0;
460 : 64705 : eLastState = eState;
461 : 64705 : bItemDirty = sal_False;
462 : : }
463 : :
464 : 118744 : bCtrlDirty = sal_False;
465 : : DBG_PROFSTOP(SfxStateCacheSetState);
466 : : }
467 : :
468 : :
469 : : //--------------------------------------------------------------------
470 : : // Set old status again in all the controllers
471 : :
472 : 239 : void SfxStateCache::SetCachedState( sal_Bool bAlways )
473 : : {
474 : : DBG_CHKTHIS(SfxStateCache, 0);
475 : : DBG_ASSERT(pController==NULL||pController->GetId()==nId, "Cache with wrong ControllerItem" );
476 : : DBG_PROFSTART(SfxStateCacheSetState);
477 : :
478 : : // Only update if cached item exists and also able to process.
479 : : // (If the State is sent, it must be ensured that a SlotServer is present,
480 : : // see SfxControllerItem:: GetCoreMetric())
481 [ - + ][ # # ]: 239 : if ( bAlways || ( !bItemDirty && !bSlotDirty ) )
[ # # ]
482 : : {
483 : : // Update Controller
484 [ + - ][ - + ]: 239 : if ( !pDispatch && pController )
485 : : {
486 [ # # ]: 0 : for ( SfxControllerItem *pCtrl = pController;
487 : : pCtrl;
488 : : pCtrl = pCtrl->GetItemLink() )
489 : 0 : pCtrl->StateChanged( nId, eLastState, pLastItem );
490 : : }
491 : :
492 [ + - ]: 239 : if ( pInternalController )
493 : 239 : ((SfxDispatchController_Impl *)pInternalController)->StateChanged( nId, eLastState, pLastItem, &aSlotServ );
494 : :
495 : : // Controller is now ok
496 : 239 : bCtrlDirty = sal_True;
497 : : }
498 : :
499 : : DBG_PROFSTOP(SfxStateCacheSetState);
500 : 239 : }
501 : :
502 : :
503 : : //--------------------------------------------------------------------
504 : : // Destroy FloatingWindows in all Controls with this Id
505 : :
506 : 257175 : void SfxStateCache::DeleteFloatingWindows()
507 : : {
508 : : DBG_CHKTHIS(SfxStateCache, 0);
509 : :
510 : 257175 : SfxControllerItem *pNextCtrl=0;
511 [ + + ]: 286927 : for ( SfxControllerItem *pCtrl=pController; pCtrl; pCtrl=pNextCtrl )
512 : : {
513 : : OSL_TRACE(rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("pCtrl: ")).append(reinterpret_cast<sal_Int64>(pCtrl)).getStr());
514 : 29752 : pNextCtrl = pCtrl->GetItemLink();
515 : 29752 : pCtrl->DeleteFloatingWindow();
516 : : }
517 : 257175 : }
518 : :
519 : 36899 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SfxStateCache::GetDispatch() const
520 : : {
521 [ - + ]: 36899 : if ( pDispatch )
522 : 0 : return pDispatch->xDisp;
523 : 36899 : return ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > ();
524 : : }
525 : :
526 : 0 : void SfxStateCache::Dispatch( const SfxItemSet* pSet, sal_Bool bForceSynchron )
527 : : {
528 : : // protect pDispatch against destruction in the call
529 [ # # ]: 0 : ::com::sun::star::uno::Reference < ::com::sun::star::frame::XStatusListener > xKeepAlive( pDispatch );
530 [ # # ]: 0 : if ( pDispatch )
531 : : {
532 [ # # ]: 0 : uno::Sequence < beans::PropertyValue > aArgs;
533 [ # # ]: 0 : if (pSet)
534 [ # # ]: 0 : TransformItems( nId, *pSet, aArgs );
535 [ # # ][ # # ]: 0 : pDispatch->Dispatch( aArgs, bForceSynchron );
[ # # ][ # # ]
536 : 0 : }
537 : 0 : }
538 : :
539 : :
540 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|