1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
31 #include <com/sun/star/frame/XLayoutManager.hpp>
33 #include <comphelper/lok.hxx>
34 #include <rtl/strbuf.hxx>
35 #include <sfx2/app.hxx>
36 #include <sfx2/bindings.hxx>
37 #include <sfx2/childwin.hxx>
38 #include <sfx2/dispatch.hxx>
39 #include <sfx2/docfac.hxx>
40 #include <sfx2/docfile.hxx>
41 #include <sfx2/hintpost.hxx>
42 #include <sfx2/ipclient.hxx>
43 #include <sfx2/mnumgr.hxx>
44 #include <sfx2/module.hxx>
45 #include <sfx2/msg.hxx>
46 #include <sfx2/msgpool.hxx>
47 #include <sfx2/objface.hxx>
48 #include <sfx2/request.hxx>
49 #include <sfx2/sfxhelp.hxx>
50 #include <sfx2/sfxuno.hxx>
51 #include <sfx2/viewfrm.hxx>
52 #include <sfx2/viewsh.hxx>
53 #include <svl/eitem.hxx>
54 #include <svl/intitem.hxx>
55 #include <svl/itemiter.hxx>
56 #include <svl/itempool.hxx>
57 #include <svl/undo.hxx>
58 #include <svl/whiter.hxx>
59 #include <svtools/helpopt.hxx>
60 #include <vcl/wrkwin.hxx>
61 #include <vcl/idle.hxx>
63 #include <appdata.hxx>
64 #include <sfxtypes.hxx>
65 #include <slotserv.hxx>
66 #include <workwin.hxx>
68 typedef std::vector
<SfxShell
*> SfxShellStack_Impl
;
70 typedef std::vector
<SfxRequest
*> SfxRequestPtrArray
;
80 SfxToDo_Impl( bool bOpPush
, bool bOpDelete
, bool bOpUntil
, SfxShell
& rCluster
)
89 struct SfxObjectBars_Impl
91 sal_uInt32 nResId
; // Resource - and ConfigId of the Toolbox
92 sal_uInt16 nMode
; // special visibility flags
95 SfxObjectBars_Impl() : nResId(0), nMode(0), pIFace(NULL
) {}
98 struct SfxDispatcher_Impl
100 //When the dispatched is locked, SfxRequests accumulate in aReqArr for
101 //later dispatch when unlocked via Post
103 //The pointers are typically deleted in Post, only if we never get around
104 //to posting them do we delete the unposted requests.
105 SfxRequestPtrArray aReqArr
;
106 ~SfxDispatcher_Impl()
108 for (SfxRequestPtrArray::iterator aI
= aReqArr
.begin(), aEnd
= aReqArr
.end(); aI
!= aEnd
; ++aI
)
111 const SfxSlotServer
* pCachedServ1
; // last called message
112 const SfxSlotServer
* pCachedServ2
; // penultimate called Message
113 SfxShellStack_Impl aStack
; // active functionality
114 Idle aIdle
; // for Flush
115 std::deque
<SfxToDo_Impl
> aToDoStack
; // not processed Push/Pop
116 SfxViewFrame
* pFrame
; // NULL or associated Frame
117 SfxDispatcher
* pParent
; // AppDispatcher, NULL if possible
118 SfxHintPosterRef xPoster
; // Execute asynchronous
119 bool bFlushing
; // sal_True during Flush //?
120 bool bUpdated
; // Update_Impl has run
121 bool bLocked
; // No Execute
122 bool bInvalidateOnUnlock
; // because someone asked
123 bool bActive
; // not to be confused with set!
124 bool* pInCallAliveFlag
; // view the Destructor Stack
125 SfxObjectBars_Impl aObjBars
[SFX_OBJECTBAR_MAX
];
126 SfxObjectBars_Impl aFixedObjBars
[SFX_OBJECTBAR_MAX
];
127 std::vector
<sal_uInt32
> aChildWins
;
128 sal_uInt32 nEventId
; // EventId UserEvent
129 bool bNoUI
; // UI only from Parent Dispatcher
130 bool bReadOnly
; // Document is ReadOnly
131 bool bQuiet
; // Only use parent dispatcher
132 bool bModal
; // Only slots from parent dispatcher
134 SfxSlotFilterState nFilterEnabling
; // 1==filter enabled slots,
135 // 2==ReadOnlyDoc overturned
136 sal_uInt16 nFilterCount
; // Number of SIDs in pFilterSIDs
137 const sal_uInt16
* pFilterSIDs
; // sorted Array of SIDs
138 sal_uInt32 nDisableFlags
;
140 std::deque
< std::deque
<SfxToDo_Impl
> > aToDoCopyStack
;
143 /** This method checks if the stack of the SfxDispatchers is flushed, or if
144 push- or pop- commands are pending.
146 bool SfxDispatcher::IsFlushed() const
148 return xImp
->bFlushed
;
151 /** This method performs outstanding push- and pop- commands. For <SfxShell>s,
152 which are new on the stack, the <SfxShell::Activate(bool)> is invoked
153 with bMDI == sal_True, for SfxShells that are removed from the stack, the
154 <SfxShell::Deactivate(bool)> is invoked with bMDI == sal_True
156 void SfxDispatcher::Flush()
158 if (!xImp
->bFlushed
) FlushImpl();
161 /** With this method, a <SfxShell> pushed on to the SfxDispatcher.
162 The SfxShell is first marked for push and a timer is set up.
163 First when the timer has couted down to zero the push
164 ( <SfxDispatcher::Flush()> ) is actually performed and the
165 <SfxBindings> is invalidated. While the timer is counting down
166 the opposing push and pop commands on the same SfxShell are
169 void SfxDispatcher::Push(SfxShell
& rShell
)
172 Pop( rShell
, SfxDispatcherPopFlags::PUSH
);
175 /** This method checks whether a particular <SfxShell> instance is
176 on the SfxDispatcher.
178 @returns sal_True The SfxShell instance is on the SfxDispatcher.
179 sal_False The SfxShell instance is not on the SfxDispatcher.
181 bool SfxDispatcher::IsActive(const SfxShell
& rShell
)
184 return CheckVirtualStack(rShell
, true);
187 /** With this method it can be determined whether the SfxDispatcher is
188 locked or unlocked. A locked SfxDispatcher does not perform <SfxRequest>s
189 and no longer provides any status information. It behaves as if all the
192 The dispatcher is also marked as blocked, if all Dispatcher are locked
193 (<SfxApplication::LockDispatcher()>) or the associated top frame is in the
194 modal-mode and if the specified slot are handled as frame-specific
195 (ie, not served by the application).
197 bool SfxDispatcher::IsLocked(sal_uInt16
) const
199 return xImp
->bLocked
;
202 /** With this method it can be determined if the SfxDispacher is the
203 applications dispatcher.
205 @return bool it is the application dispatcher.
207 bool SfxDispatcher::IsAppDispatcher() const
209 return !xImp
->pFrame
;
212 /** Helper function to check whether a slot can be executed and
213 check the execution itself
215 void SfxDispatcher::Call_Impl(SfxShell
& rShell
, const SfxSlot
&rSlot
, SfxRequest
&rReq
, bool bRecord
)
217 SFX_STACK(SfxDispatcher::Call_Impl
);
219 // The slot may be called (meaning enabled)
220 if ( rSlot
.IsMode(SfxSlotMode::FASTCALL
) || rShell
.CanExecuteSlot_Impl(rSlot
) )
224 // Recording may start
225 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xFrame(
226 GetFrame()->GetFrame().GetFrameInterface(),
227 com::sun::star::uno::UNO_QUERY
);
229 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xSet(
231 com::sun::star::uno::UNO_QUERY
);
235 com::sun::star::uno::Any aProp
= xSet
->getPropertyValue("DispatchRecorderSupplier");
236 com::sun::star::uno::Reference
< com::sun::star::frame::XDispatchRecorderSupplier
> xSupplier
;
237 com::sun::star::uno::Reference
< com::sun::star::frame::XDispatchRecorder
> xRecorder
;
240 xRecorder
= xSupplier
->getDispatchRecorder();
242 if ( bRecord
&& xRecorder
.is() && !rSlot
.IsMode(SfxSlotMode::NORECORD
) )
243 rReq
.Record_Impl( rShell
, rSlot
, xRecorder
, GetFrame() );
246 // Get all that is needed, because the slot may not have survived the
247 // Execute if it is a 'pseudo slot' for macros or verbs.
248 bool bAutoUpdate
= rSlot
.IsMode(SfxSlotMode::AUTOUPDATE
);
250 // API-call parentheses and document-lock during the calls
252 // 'this' must respond in the Destructor
253 bool bThisDispatcherAlive
= true;
254 bool *pOldInCallAliveFlag
= xImp
->pInCallAliveFlag
;
255 xImp
->pInCallAliveFlag
= &bThisDispatcherAlive
;
257 SfxExecFunc pFunc
= rSlot
.GetExecFnc();
258 rShell
.CallExec( pFunc
, rReq
);
260 // If 'this' is still alive
261 if ( bThisDispatcherAlive
)
262 xImp
->pInCallAliveFlag
= pOldInCallAliveFlag
;
265 if ( pOldInCallAliveFlag
)
267 // also protect nested stack frames
268 *pOldInCallAliveFlag
= false;
271 // do nothing after this object is dead
278 SfxBindings
*pBindings
= GetBindings();
280 // When AutoUpdate update immediately; "Pseudoslots" must not be
282 if ( bAutoUpdate
&& pBindings
)
284 const SfxSlot
* pSlave
= rSlot
.GetLinkedSlot();
287 // When enum slots take any bound slave slot
288 while (!pBindings
->IsBound(pSlave
->GetSlotId()) && pSlave
!= &rSlot
)
289 pSlave
= pSlave
->GetLinkedSlot();
290 pBindings
->Invalidate(pSlave
->GetSlotId());
291 pBindings
->Update(pSlave
->GetSlotId());
295 pBindings
->Invalidate(rSlot
.GetSlotId());
296 pBindings
->Update(rSlot
.GetSlotId());
303 void SfxDispatcher::Construct_Impl( SfxDispatcher
* pParent
)
305 xImp
.reset(new SfxDispatcher_Impl
);
306 xImp
->bFlushed
= true;
308 xImp
->pCachedServ1
= 0;
309 xImp
->pCachedServ2
= 0;
310 xImp
->bFlushing
= false;
311 xImp
->bUpdated
= false;
312 xImp
->bLocked
= false;
313 xImp
->bActive
= false;
314 xImp
->pParent
= NULL
;
316 xImp
->bReadOnly
= false;
317 xImp
->bQuiet
= false;
318 xImp
->bModal
= false;
319 xImp
->pInCallAliveFlag
= 0;
320 xImp
->nFilterEnabling
= SfxSlotFilterState::DISABLED
;
321 xImp
->nFilterCount
= 0;
322 xImp
->pFilterSIDs
= 0;
323 xImp
->nDisableFlags
= 0;
325 xImp
->pParent
= pParent
;
327 xImp
->bInvalidateOnUnlock
= false;
329 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
330 xImp
->aObjBars
[n
].nResId
= 0;
332 GenLink
aGenLink( LINK(this, SfxDispatcher
, PostMsgHandler
) );
334 xImp
->xPoster
= new SfxHintPoster(aGenLink
);
336 xImp
->aIdle
.SetPriority(SchedulerPriority::MEDIUM
);
337 xImp
->aIdle
.SetIdleHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
340 SfxDispatcher::SfxDispatcher( SfxDispatcher
* pParent
)
342 Construct_Impl( pParent
);
346 /** The constructor of the SfxDispatcher class places a stack of empty
347 <SfxShell> pointers. It is not initially locked and is considered flushed.
349 SfxDispatcher::SfxDispatcher(SfxViewFrame
*pViewFrame
)
353 SfxViewFrame
*pFrame
= pViewFrame
->GetParentViewFrame();
355 Construct_Impl( pFrame
->GetDispatcher() );
361 xImp
->pFrame
= pViewFrame
;
364 /** The destructor of the SfxDispatcher class should not be called when the
365 SfxDispatcher instance is active. It may, however, still be a <SfxShell>
366 pointer on the stack.
368 SfxDispatcher::~SfxDispatcher()
371 OStringBuffer
sTemp("Delete Dispatcher ");
372 sTemp
.append(reinterpret_cast<sal_Int64
>(this));
373 OSL_TRACE("%s", sTemp
.getStr());
374 DBG_ASSERT( !xImp
->bActive
, "deleting active Dispatcher" );
377 // So that no timer by Reschedule in PlugComm strikes the LeaveRegistrations
379 xImp
->xPoster
->SetEventHdl( Link
<>() );
381 // Notify the stack varialbles in Call_Impl
382 if ( xImp
->pInCallAliveFlag
)
383 *xImp
->pInCallAliveFlag
= false;
385 // Get bindings and application
386 SfxApplication
*pSfxApp
= SfxGetpApp();
387 SfxBindings
* pBindings
= GetBindings();
389 // When not flushed, revive the bindings
390 if (pBindings
&& !pSfxApp
->IsDowning() && !xImp
->bFlushed
)
391 pBindings
->DLEAVEREGISTRATIONS();
393 // may unregister the bindings
396 if ( pBindings
->GetDispatcher_Impl() == this)
397 pBindings
->SetDispatcher(0);
398 pBindings
= pBindings
->GetSubBindings_Impl();
402 /** With this method, one or more <SfxShell> are poped from the SfxDispatcher.
403 The SfxShell is marked for popping and a timer is set up. Only when the
404 timer has reached the end, the pop is actually performed
405 ( <SfxDispatcher::Flush()> ) and the <SfxBindings> is invalidated.
406 While the timer is running the opposing push and pop commands on one
407 SfxShell cancel each other out.
409 @param rShell the stack to take the SfxShell instance.
410 @param nMode SfxDispatcherPopFlags::POP_UNTIL
411 Also all 'rShell' of SfxShells are taken from the
414 SfxDispatcherPopFlags::POP_DELETE
415 All SfxShells actually taken from the stack
418 SfxDispatcherPopFlags::PUSH (InPlace use only)
421 void SfxDispatcher::Pop(SfxShell
& rShell
, SfxDispatcherPopFlags nMode
)
423 DBG_ASSERT( rShell
.GetInterface(),
424 "pushing SfxShell without previous RegisterInterface()" );
426 bool bDelete
= bool(nMode
& SfxDispatcherPopFlags::POP_DELETE
);
427 bool bUntil
= bool(nMode
& SfxDispatcherPopFlags::POP_UNTIL
);
428 bool bPush
= bool(nMode
& SfxDispatcherPopFlags::PUSH
);
430 SfxApplication
*pSfxApp
= SfxGetpApp();
434 "-SfxDispatcher(" << this << (bPush
? ")::Push(" : ")::Pop(")
435 << (rShell
.GetInterface()
436 ? rShell
.GetInterface()->GetClassName() : SAL_STREAM(&rShell
))
437 << (bDelete
? ") with delete" : ")")
438 << (bUntil
? " (up to)" : ""));
440 // same shell as on top of the to-do stack?
441 if(xImp
->aToDoStack
.size() && xImp
->aToDoStack
.front().pCluster
== &rShell
)
443 // cancel inverse actions
444 if ( xImp
->aToDoStack
.front().bPush
!= bPush
)
445 xImp
->aToDoStack
.pop_front();
448 DBG_ASSERT( bPush
, "SfxInterface pushed more than once" );
449 DBG_ASSERT( !bPush
, "SfxInterface popped more than once" );
455 xImp
->aToDoStack
.push_front( SfxToDo_Impl(bPush
, bDelete
, bUntil
, rShell
) );
458 OSL_TRACE("Unflushed dispatcher!");
459 xImp
->bFlushed
= false;
460 xImp
->bUpdated
= false;
462 // Put bindings to sleep
463 SfxBindings
* pBindings
= GetBindings();
465 pBindings
->DENTERREGISTRATIONS();
469 if(!pSfxApp
->IsDowning() && !xImp
->aToDoStack
.empty())
471 // No immediate update is requested
472 xImp
->aIdle
.SetPriority(SchedulerPriority::MEDIUM
);
473 xImp
->aIdle
.SetIdleHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
481 // Bindings may wake up again
482 if(xImp
->aToDoStack
.empty())
484 SfxBindings
* pBindings
= GetBindings();
486 pBindings
->DLEAVEREGISTRATIONS();
492 /** This handler is called after <SfxDispatcher::Invalidate()> or after
493 changes on the stack (<SfxDispatcher::Push()> and <SfxDispatcher::Pop())
495 It flushes the Stack, if it is dirty, thus it actually executes the
496 pending Push and Pop commands.
498 IMPL_LINK_NOARG_TYPED( SfxDispatcher
, EventHdl_Impl
, Idle
*, void )
502 SfxBindings
* pBindings
= GetBindings();
504 pBindings
->StartUpdate_Impl(false);
507 /** With this method it can be tested whether the <SfxShell> rShell is on the
508 stack, when it was flushed. This way the SfxDispatcher is not actually
511 This method is intended among other things to make assertions possible
512 without the side effect of having to flush the SfxDispathcer.
514 bool SfxDispatcher::CheckVirtualStack(const SfxShell
& rShell
, bool bDeep
)
516 SFX_STACK(SfxDispatcher::CheckVirtualStack
);
518 SfxShellStack_Impl
aStack( xImp
->aStack
);
519 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= xImp
->aToDoStack
.rbegin(); i
!= xImp
->aToDoStack
.rend(); ++i
)
522 aStack
.push_back(i
->pCluster
);
525 SfxShell
* pPopped(NULL
);
528 DBG_ASSERT( !aStack
.empty(), "popping from empty stack" );
529 pPopped
= aStack
.back();
532 while(i
->bUntil
&& pPopped
!= i
->pCluster
);
533 DBG_ASSERT(pPopped
== i
->pCluster
, "popping unpushed SfxInterface");
539 bReturn
= std::find(aStack
.begin(), aStack
.end(), &rShell
) != aStack
.end();
541 bReturn
= aStack
.back() == &rShell
;
545 /** Determines the position of a given SfxShell in the stack of the dispatcher.
546 If possible this is flushed before.
550 sal_uInt16 == USRT_MAX
551 The SfxShell is not on this SfxDispatcher.
554 Position of the SfxShell on the Dispatcher
555 from the top count stating with 0.
557 sal_uInt16
SfxDispatcher::GetShellLevel(const SfxShell
& rShell
)
559 SFX_STACK(SfxDispatcher::GetShellLevel
);
562 for ( sal_uInt16 n
= 0; n
< xImp
->aStack
.size(); ++n
)
563 if ( *( xImp
->aStack
.rbegin() + n
) == &rShell
)
567 sal_uInt16 nRet
= xImp
->pParent
->GetShellLevel(rShell
);
568 if ( nRet
== USHRT_MAX
)
570 return nRet
+ xImp
->aStack
.size();
576 /** Returns a pointer to the <SfxShell> which is at the position nIdx
577 (from the top, last pushed is 0) on the stack.
579 Thus the SfxDispatcher is not flushed.
581 Is the stack not deep enough a NULL-Pointer is returned.
583 SfxShell
*SfxDispatcher::GetShell(sal_uInt16 nIdx
) const
585 sal_uInt16 nShellCount
= xImp
->aStack
.size();
586 if ( nIdx
< nShellCount
)
587 return *(xImp
->aStack
.rbegin() + nIdx
);
588 else if ( xImp
->pParent
)
589 return xImp
->pParent
->GetShell( nIdx
- nShellCount
);
593 /** This method returns a pointer to the <SfxBinding> Instance on which the
594 SfxDispatcher is curretly bound. A SfxDispatcher is only bound to
595 the SfxBindings when it is <UI-aktiv>. If it is not UI-active,
596 a NULL-pointer is returned.
598 The returned pointer is only valid in the immediate context of the method
601 SfxBindings
* SfxDispatcher::GetBindings() const
604 return &xImp
->pFrame
->GetBindings();
609 /** Returns a pointer to the <SfxViewFrame> instance, which belongs to
610 this SfxDispatcher. If it is about the application dispatcher,
611 a NULL-pointer is returned.
613 SfxViewFrame
* SfxDispatcher::GetFrame() const
618 /** This method controls the activation of a dispatcher.
620 Since the application dispatcher is always active, either as a sub
621 dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
622 activated as a whole, instead only its individual <SfxShell>s at
623 <SfxDispatcher::Push(SfxShell&)>.
625 When activating a SfxDispatcher all of the SfxShells located on its stack
626 are called with the handler <SfxShell::Activate(bool)>, starting with
629 void SfxDispatcher::DoActivate_Impl(bool bMDI
, SfxViewFrame
* /* pOld */)
631 SFX_STACK(SfxDispatcher::DoActivate
);
635 OStringBuffer
sTemp("Activate Dispatcher ");
636 sTemp
.append(reinterpret_cast<sal_Int64
>(this));
637 OSL_TRACE("%s", sTemp
.getStr());
638 DBG_ASSERT( !xImp
->bActive
, "Activation error" );
640 xImp
->bActive
= true;
641 xImp
->bUpdated
= false;
642 SfxBindings
* pBindings
= GetBindings();
645 pBindings
->SetDispatcher(this);
646 pBindings
->SetActiveFrame( xImp
->pFrame
->GetFrame().GetFrameInterface() );
652 OStringBuffer
sTemp("Non-MDI-Activate Dispatcher");
653 sTemp
.append(reinterpret_cast<sal_Int64
>(this));
654 OSL_TRACE("%s", sTemp
.getStr());
658 if ( IsAppDispatcher() )
661 for ( int i
= int(xImp
->aStack
.size()) - 1; i
>= 0; --i
)
662 (*(xImp
->aStack
.rbegin() + i
))->DoActivate_Impl(xImp
->pFrame
, bMDI
);
664 if ( bMDI
&& xImp
->pFrame
)
666 SfxBindings
*pBind
= GetBindings();
669 pBind
->HidePopupCtrls_Impl( false );
670 pBind
= pBind
->GetSubBindings_Impl();
673 xImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( false, false, 1 );
676 if(!xImp
->aToDoStack
.empty())
678 // No immediate update is requested
679 xImp
->aIdle
.SetPriority(SchedulerPriority::MEDIUM
);
680 xImp
->aIdle
.SetIdleHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
685 void SfxDispatcher::DoParentActivate_Impl()
689 /** This method controls the deactivation of a dispatcher.
691 Since the application dispatcher is always active, either as a sub
692 dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
693 deactivated as a whole, instead only its individual <SfxShell>s at
694 <SfxDispatcher::Pop(SfxShell&)>.
696 When deactivating a SfxDispatcher all of the SfxShells located on its stack
697 are called with the handler <SfxShell::Deactivate(bool)>, starting with
700 void SfxDispatcher::DoDeactivate_Impl(bool bMDI
, SfxViewFrame
* pNew
)
702 SFX_STACK(SfxDispatcher::DoDeactivate
);
704 SfxApplication
*pSfxApp
= SfxGetpApp();
708 SAL_INFO("sfx.control", "Deactivate Dispatcher " << this);
709 DBG_ASSERT( xImp
->bActive
, "Deactivate error" );
710 xImp
->bActive
= false;
712 if ( xImp
->pFrame
&& !(xImp
->pFrame
->GetObjectShell()->IsInPlaceActive() ) )
714 SfxWorkWindow
*pWorkWin
= xImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
717 for (size_t n
=0; n
<xImp
->aChildWins
.size();)
719 SfxChildWindow
*pWin
= pWorkWin
->GetChildWindow_Impl( (sal_uInt16
) ( xImp
->aChildWins
[n
] & 0xFFFF ) );
720 if (!pWin
|| (pWin
&& pWin
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
))
721 xImp
->aChildWins
.erase(xImp
->aChildWins
.begin()+n
);
729 SAL_INFO("sfx.control", "Non-MDI-DeActivate Dispatcher " << this);
732 if ( IsAppDispatcher() && !pSfxApp
->IsDowning() )
735 for ( sal_uInt16 i
= 0; i
< xImp
->aStack
.size(); ++i
)
736 (*(xImp
->aStack
.rbegin() + i
))->DoDeactivate_Impl(xImp
->pFrame
, bMDI
);
738 bool bHidePopups
= bMDI
&& xImp
->pFrame
;
739 if ( pNew
&& xImp
->pFrame
)
741 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xOldFrame(
742 pNew
->GetFrame().GetFrameInterface()->getCreator(), com::sun::star::uno::UNO_QUERY
);
744 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xMyFrame(
745 GetFrame()->GetFrame().GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
747 if ( xOldFrame
== xMyFrame
)
753 SfxBindings
*pBind
= GetBindings();
756 pBind
->HidePopupCtrls_Impl( true );
757 pBind
= pBind
->GetSubBindings_Impl();
760 xImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( true, false, 1 );
766 void SfxDispatcher::DoParentDeactivate_Impl()
770 /** This method searches in SfxDispatcher after <SfxShell> , from the Slot Id
771 nSlot currently being handled. For this, the dispatcher is first flushed.
773 @param nSlot the searchable Slot-Id
774 @param ppShell the SfxShell, which are currently handled the nSlot
775 @param ppSlot the SfxSlot, which are currently handled the nSlot
778 The SfxShell was found, ppShell and ppSlot are valid.
781 The SfxShell was not found, ppShell and ppSlot are invalid.
783 bool SfxDispatcher::GetShellAndSlot_Impl(sal_uInt16 nSlot
, SfxShell
** ppShell
,
784 const SfxSlot
** ppSlot
, bool bOwnShellsOnly
, bool bModal
, bool bRealSlot
)
786 SFX_STACK(SfxDispatcher::GetShellAndSlot_Impl
);
790 if ( _FindServer(nSlot
, aSvr
, bModal
) )
792 if ( bOwnShellsOnly
&& aSvr
.GetShellLevel() >= xImp
->aStack
.size() )
795 *ppShell
= GetShell(aSvr
.GetShellLevel());
796 *ppSlot
= aSvr
.GetSlot();
797 if ( 0 == (*ppSlot
)->GetExecFnc() && bRealSlot
)
798 *ppSlot
= (*ppShell
)->GetInterface()->GetRealSlot(*ppSlot
);
799 // Check only real slots as enum slots don't have an execute function!
800 if ( bRealSlot
&& ((0 == *ppSlot
) || (0 == (*ppSlot
)->GetExecFnc()) ))
809 /** This method performs a request for a cached <Slot-Server>.
811 @param rShell to the calling <SfxShell>
812 @param rSlot to the calling <SfxSlot>
813 @param rReq function to be performed (Id and optional parameters)
814 @param eCallMode Synchronously, asynchronously or as shown in the slot
816 void SfxDispatcher::_Execute(SfxShell
& rShell
, const SfxSlot
& rSlot
,
817 SfxRequest
& rReq
, SfxCallMode eCallMode
)
819 DBG_ASSERT( !xImp
->bFlushing
, "recursive call to dispatcher" );
820 DBG_ASSERT( xImp
->aToDoStack
.empty(), "unprepared InPlace _Execute" );
822 if ( IsLocked( rSlot
.GetSlotId() ) )
825 if ( bool(eCallMode
& SfxCallMode::ASYNCHRON
) ||
826 ( (eCallMode
& SfxCallMode::SYNCHRON
) == SfxCallMode::SLOT
&&
827 rSlot
.IsMode(SfxSlotMode::ASYNCHRON
) ) )
829 SfxDispatcher
*pDispat
= this;
832 sal_uInt16 nShellCount
= pDispat
->xImp
->aStack
.size();
833 for ( sal_uInt16 n
=0; n
<nShellCount
; n
++ )
835 if ( &rShell
== *(pDispat
->xImp
->aStack
.rbegin() + n
) )
837 if ( bool(eCallMode
& SfxCallMode::RECORD
) )
838 rReq
.AllowRecording( true );
839 pDispat
->xImp
->xPoster
->Post(new SfxRequest(rReq
));
844 pDispat
= pDispat
->xImp
->pParent
;
848 Call_Impl( rShell
, rSlot
, rReq
, SfxCallMode::RECORD
==(eCallMode
&SfxCallMode::RECORD
) );
851 /** Helper function to put from rItem below the Which-ID in the pool of the
854 void MappedPut_Impl(SfxAllItemSet
&rSet
, const SfxPoolItem
&rItem
)
856 // Put with mapped Which-Id if possible
857 const SfxItemPool
*pPool
= rSet
.GetPool();
858 sal_uInt16 nWhich
= rItem
.Which();
859 if ( SfxItemPool::IsSlot(nWhich
) )
860 nWhich
= pPool
->GetWhich(nWhich
);
861 rSet
.Put( rItem
, nWhich
);
864 const SfxSlot
* SfxDispatcher::GetSlot( const OUString
& rCommand
)
866 // Count the number of Shells on the linked Dispatcher
868 sal_uInt16 nTotCount
= xImp
->aStack
.size();
871 SfxDispatcher
*pParent
= xImp
->pParent
;
874 nTotCount
= nTotCount
+ pParent
->xImp
->aStack
.size();
875 pParent
= pParent
->xImp
->pParent
;
879 sal_uInt16 nFirstShell
= 0;
880 for ( sal_uInt16 i
= nFirstShell
; i
< nTotCount
; ++i
)
882 SfxShell
*pObjShell
= GetShell(i
);
883 SfxInterface
*pIFace
= pObjShell
->GetInterface();
884 const SfxSlot
*pSlot
= pIFace
->GetSlot( rCommand
);
892 const SfxPoolItem
* SfxDispatcher::Execute(sal_uInt16 nSlot
, SfxCallMode nCall
,
893 SfxItemSet
* pArgs
, SfxItemSet
* pInternalArgs
, sal_uInt16 nModi
)
895 if ( IsLocked(nSlot
) )
898 SfxShell
*pShell
= 0;
899 const SfxSlot
*pSlot
= 0;
900 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, false,
901 SfxCallMode::MODAL
==(nCall
&SfxCallMode::MODAL
) ) )
903 SfxAllItemSet
aSet( pShell
->GetPool() );
906 SfxItemIter
aIter(*pArgs
);
907 for ( const SfxPoolItem
*pArg
= aIter
.FirstItem();
909 pArg
= aIter
.NextItem() )
910 MappedPut_Impl( aSet
, *pArg
);
912 SfxRequest
aReq( nSlot
, nCall
, aSet
);
914 aReq
.SetInternalArgs_Impl( *pInternalArgs
);
915 aReq
.SetModifier( nModi
);
917 _Execute( *pShell
, *pSlot
, aReq
, nCall
);
918 return aReq
.GetReturnValue();
923 /** Method to execute a <SfxSlot>s over the Slot-Id.
925 @param nSlot the Id of the executing function
926 @param eCall SfxCallMode::SYNCRHON, ..._ASYNCHRON or ..._SLOT
927 @param pArgs Zero teminated C-Array of Parameters
928 @param pInternalArgs Zero terminated C-Array of Parameters
930 @return const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
931 though the Message-Loop, which contains the return
934 Or a NULL-Pointer, when the function was not
935 executed (for example canceled by the user).
937 const SfxPoolItem
* SfxDispatcher::Execute(sal_uInt16 nSlot
, SfxCallMode eCall
,
938 const SfxPoolItem
**pArgs
, sal_uInt16 nModi
, const SfxPoolItem
**pInternalArgs
)
940 if ( IsLocked(nSlot
) )
943 SfxShell
*pShell
= 0;
944 const SfxSlot
*pSlot
= 0;
945 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, false,
946 SfxCallMode::MODAL
==(eCall
&SfxCallMode::MODAL
) ) )
949 if ( pArgs
&& *pArgs
)
951 SfxAllItemSet
aSet( pShell
->GetPool() );
952 for ( const SfxPoolItem
**pArg
= pArgs
; *pArg
; ++pArg
)
953 MappedPut_Impl( aSet
, **pArg
);
954 pReq
= new SfxRequest( nSlot
, eCall
, aSet
);
957 pReq
= new SfxRequest( nSlot
, eCall
, pShell
->GetPool() );
958 pReq
->SetModifier( nModi
);
959 if( pInternalArgs
&& *pInternalArgs
)
961 SfxAllItemSet
aSet( SfxGetpApp()->GetPool() );
962 for ( const SfxPoolItem
**pArg
= pInternalArgs
; *pArg
; ++pArg
)
964 pReq
->SetInternalArgs_Impl( aSet
);
966 _Execute( *pShell
, *pSlot
, *pReq
, eCall
);
967 const SfxPoolItem
* pRet
= pReq
->GetReturnValue();
968 delete pReq
; return pRet
;
973 /** Method to execute a <SfxSlot>s over the Slot-Id.
975 @param nSlot the Id of the executing function
976 @param eCall SfxCallMode::SYNCRHON, ..._ASYNCHRON or ..._SLOT
977 @param rArgs <SfxItemSet> with the parameters
979 @return const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
980 though the Message-Loop, which contains the return
983 Or a NULL-Pointer, when the function was not
984 executed (for example canceled by the user).
986 const SfxPoolItem
* SfxDispatcher::Execute(sal_uInt16 nSlot
, SfxCallMode eCall
,
987 const SfxItemSet
&rArgs
)
989 return Execute( nSlot
, eCall
, 0, rArgs
);
992 const SfxPoolItem
* SfxDispatcher::Execute(sal_uInt16 nSlot
, SfxCallMode eCall
,
993 sal_uInt16 nModi
, const SfxItemSet
&rArgs
)
995 if ( IsLocked(nSlot
) )
998 SfxShell
*pShell
= 0;
999 const SfxSlot
*pSlot
= 0;
1000 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, false,
1001 SfxCallMode::MODAL
==(eCall
&SfxCallMode::MODAL
) ) )
1003 SfxAllItemSet
aSet( pShell
->GetPool() );
1004 SfxItemIter
aIter(rArgs
);
1005 for ( const SfxPoolItem
*pArg
= aIter
.FirstItem();
1007 pArg
= aIter
.NextItem() )
1008 MappedPut_Impl( aSet
, *pArg
);
1009 SfxRequest
aReq( nSlot
, eCall
, aSet
);
1010 aReq
.SetModifier( nModi
);
1011 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1012 return aReq
.GetReturnValue();
1017 /** Method to execute a <SfxSlot>s over the Slot-Id.
1021 The parameters are copied, can therefore be passed on as the address
1024 @param nSlot the Id of the executing function
1025 @param eCall SfxCallMode::SYNCRHON, ..._ASYNCHRON or ..._SLOT
1026 @param pArg1 First parameter
1027 @param ... Zero terminated list of parameters
1029 @return Pointer to the SfxPoolItem valid to the next run
1030 though the Message-Loop, which contains the return
1033 Or a NULL-Pointer, when the function was not
1034 executed (for example canceled by the user).
1038 pDispatcher->Execute( SID_OPENDOCUMENT, SfxCallMode::SYNCHRON,
1039 &SfxStringItem( SID_FILE_NAME, "\\tmp\\temp.sdd" ),
1040 &SfxStringItem( SID_FILTER_NAME, "StarDraw Presentation" ),
1041 &SfxBoolItem( SID_DOC_READONLY, sal_False ),
1044 const SfxPoolItem
* SfxDispatcher::Execute(sal_uInt16 nSlot
, SfxCallMode eCall
,
1045 const SfxPoolItem
* pArg1
, ...)
1047 if ( IsLocked(nSlot
) )
1050 SfxShell
*pShell
= 0;
1051 const SfxSlot
*pSlot
= 0;
1052 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, false,
1053 SfxCallMode::MODAL
==(eCall
&SfxCallMode::MODAL
) ) )
1055 SfxAllItemSet
aSet( pShell
->GetPool() );
1058 va_start( pVarArgs
, pArg1
);
1059 for ( const SfxPoolItem
*pArg
= pArg1
;
1061 pArg
= va_arg( pVarArgs
, const SfxPoolItem
* ) )
1062 MappedPut_Impl( aSet
, *pArg
);
1065 SfxRequest
aReq( nSlot
, eCall
, aSet
);
1066 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1067 return aReq
.GetReturnValue();
1072 /** Helper method to receive the asynchronously executed <SfxRequest>s.
1074 IMPL_LINK(SfxDispatcher
, PostMsgHandler
, SfxRequest
*, pReq
)
1076 DBG_ASSERT( !xImp
->bFlushing
, "recursive call to dispatcher" );
1077 SFX_STACK(SfxDispatcher::PostMsgHandler
);
1079 // Has also the Pool not yet died?
1080 if ( !pReq
->IsCancelled() )
1082 if ( !IsLocked(pReq
->GetSlot()) )
1086 if ( _FindServer(pReq
->GetSlot(), aSvr
, true ) ) // HACK(x), whatever that was supposed to mean
1088 const SfxSlot
*pSlot
= aSvr
.GetSlot();
1089 SfxShell
*pSh
= GetShell(aSvr
.GetShellLevel());
1091 // When the pSlot is a "Pseudoslot" for macros or Verbs, it can
1092 // be destroyed in the Call_Impl, thus do not use it anymore!
1093 pReq
->SetSynchronCall( false );
1094 Call_Impl( *pSh
, *pSlot
, *pReq
, pReq
->AllowsRecording() ); //! why bRecord?
1099 if ( xImp
->bLocked
)
1100 xImp
->aReqArr
.push_back(new SfxRequest(*pReq
));
1102 xImp
->xPoster
->Post(new SfxRequest(*pReq
));
1110 void SfxDispatcher::SetMenu_Impl()
1112 #if HAVE_FEATURE_DESKTOP
1115 SfxViewFrame
* pTop
= xImp
->pFrame
->GetTopViewFrame();
1116 if ( pTop
&& pTop
->GetBindings().GetDispatcher() == this )
1118 SfxFrame
& rFrame
= pTop
->GetFrame();
1119 if ( rFrame
.IsMenuBarOn_Impl() )
1121 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( rFrame
.GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
1122 if ( xPropSet
.is() )
1124 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1125 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1126 aValue
>>= xLayoutManager
;
1127 if ( xLayoutManager
.is() )
1129 OUString
aMenuBarURL( "private:resource/menubar/menubar" );
1130 if ( !xLayoutManager
->isElementVisible( aMenuBarURL
) )
1131 xLayoutManager
->createElement( aMenuBarURL
);
1140 void SfxDispatcher::Update_Impl( bool bForce
)
1142 SFX_STACK(SfxDispatcher::Update_Impl
);
1146 if ( !xImp
->pFrame
)
1149 SfxGetpApp(); // -Wall is this required???
1150 SfxDispatcher
*pDisp
= this;
1151 bool bUpdate
= bForce
;
1152 while ( pDisp
&& pDisp
->xImp
->pFrame
)
1154 SfxWorkWindow
*pWork
= pDisp
->xImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1155 SfxDispatcher
*pAct
= pWork
->GetBindings().GetDispatcher_Impl();
1156 if ( pAct
== pDisp
|| pAct
== this )
1159 bUpdate
= !pDisp
->xImp
->bUpdated
;
1160 pDisp
->xImp
->bUpdated
= true;
1165 pDisp
= pDisp
->xImp
->pParent
;
1168 if ( !bUpdate
|| xImp
->pFrame
->GetFrame().IsClosing_Impl() )
1171 SfxViewFrame
* pTop
= xImp
->pFrame
? xImp
->pFrame
->GetTopViewFrame() : NULL
;
1172 bool bUIActive
= pTop
&& pTop
->GetBindings().GetDispatcher() == this && !comphelper::LibreOfficeKit::isActive();
1174 if ( !bUIActive
&& pTop
&& GetBindings() == &pTop
->GetBindings() )
1175 // keep own tools internally for collecting
1176 GetBindings()->GetDispatcher()->xImp
->bUpdated
= false;
1178 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xFrame
;
1179 SfxBindings
* pBindings
= GetBindings();
1182 pBindings
->DENTERREGISTRATIONS();
1183 xFrame
= pBindings
->GetActiveFrame();
1185 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( xFrame
, com::sun::star::uno::UNO_QUERY
);
1186 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1187 if ( xPropSet
.is() )
1191 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1192 aValue
>>= xLayoutManager
;
1194 catch (const com::sun::star::uno::Exception
&)
1199 if ( xLayoutManager
.is() )
1200 xLayoutManager
->lock();
1202 bool bIsIPActive
= xImp
->pFrame
&& xImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
1203 SfxInPlaceClient
*pClient
= xImp
->pFrame
? xImp
->pFrame
->GetViewShell()->GetUIActiveClient() : NULL
;
1204 if ( bUIActive
&& /* !bIsIPActive && */ ( !pClient
|| !pClient
->IsObjectUIActive() ) )
1207 SfxWorkWindow
*pWorkWin
= xImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1208 SfxWorkWindow
*pTaskWin
= xImp
->pFrame
->GetTopFrame().GetWorkWindow_Impl();
1209 pTaskWin
->ResetStatusBar_Impl();
1211 SfxDispatcher
*pDispat
= this;
1214 SfxWorkWindow
*pWork
= pDispat
->xImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1215 SfxDispatcher
*pAct
= pWork
->GetBindings().GetDispatcher_Impl();
1216 if ( pAct
== pDispat
|| pAct
== this )
1218 pWork
->ResetObjectBars_Impl();
1219 pWork
->ResetChildWindows_Impl();
1222 pDispat
= pDispat
->xImp
->pParent
;
1225 bool bIsActive
= false;
1226 SfxDispatcher
*pActDispat
= pWorkWin
->GetBindings().GetDispatcher_Impl();
1228 while ( pActDispat
&& !bIsActive
)
1230 if ( pDispat
== pActDispat
)
1232 pActDispat
= pActDispat
->xImp
->pParent
;
1235 _Update_Impl( bUIActive
, !bIsIPActive
, bIsIPActive
, pTaskWin
);
1236 if ( (bUIActive
|| bIsActive
) && !comphelper::LibreOfficeKit::isActive() )
1237 pWorkWin
->UpdateObjectBars_Impl();
1240 pBindings
->DLEAVEREGISTRATIONS();
1242 if ( xLayoutManager
.is() )
1243 xLayoutManager
->unlock();
1248 void SfxDispatcher::_Update_Impl( bool bUIActive
, bool bIsMDIApp
, bool bIsIPOwner
, SfxWorkWindow
*pTaskWin
)
1251 SfxWorkWindow
*pWorkWin
= xImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1252 bool bIsActive
= false;
1253 SfxDispatcher
*pActDispat
= pWorkWin
->GetBindings().GetDispatcher_Impl();
1254 SfxDispatcher
*pDispat
= this;
1255 while ( pActDispat
&& !bIsActive
)
1257 if ( pDispat
== pActDispat
)
1259 pActDispat
= pActDispat
->xImp
->pParent
;
1262 if ( xImp
->pParent
&& !xImp
->bQuiet
/* && bUIActive */ )
1263 xImp
->pParent
->_Update_Impl( bUIActive
, bIsMDIApp
, bIsIPOwner
, pTaskWin
);
1265 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
1266 xImp
->aObjBars
[n
].nResId
= 0;
1267 xImp
->aChildWins
.clear();
1269 // bQuiet : own shells aren't considered for UI and SlotServer
1270 // bNoUI: own Shells aren't considered fors UI
1271 if ( xImp
->bQuiet
|| xImp
->bNoUI
|| (xImp
->pFrame
&& xImp
->pFrame
->GetObjectShell()->IsPreview()) )
1274 sal_uInt32 nStatBarId
=0;
1275 SfxShell
*pStatusBarShell
= NULL
;
1277 SfxSlotPool
* pSlotPool
= &SfxSlotPool::GetSlotPool( GetFrame() );
1278 sal_uInt16 nTotCount
= xImp
->aStack
.size();
1279 for ( sal_uInt16 nShell
= nTotCount
; nShell
> 0; --nShell
)
1281 SfxShell
*pShell
= GetShell( nShell
-1 );
1282 SfxInterface
*pIFace
= pShell
->GetInterface();
1284 // don't consider shells if "Hidden" oder "Quiet"
1285 bool bReadOnlyShell
= IsReadOnlyShell_Impl( nShell
-1 );
1287 for ( nNo
= 0; pIFace
&& nNo
<pIFace
->GetObjectBarCount(); ++nNo
)
1289 sal_uInt16 nPos
= pIFace
->GetObjectBarPos(nNo
);
1290 if ( bReadOnlyShell
&& !( nPos
& SFX_VISIBILITY_READONLYDOC
) )
1293 // check whether toolbar needs activation of a special feature
1294 sal_uInt32 nFeature
= pIFace
->GetObjectBarFeature(nNo
);
1295 if ( nFeature
&& !pShell
->HasUIFeature( nFeature
) )
1298 // check for toolboxes that are exclusively for a viewer
1301 bool bViewerTbx
= SFX_VISIBILITY_VIEWER
== ( nPos
& SFX_VISIBILITY_VIEWER
);
1302 SfxObjectShell
* pSh
= xImp
->pFrame
->GetObjectShell();
1303 SFX_ITEMSET_ARG( pSh
->GetMedium()->GetItemSet(), pItem
, SfxBoolItem
, SID_VIEWONLY
, false );
1304 bool bIsViewer
= pItem
&& pItem
->GetValue();
1305 if ( bIsViewer
!= bViewerTbx
)
1309 // always register toolbars, allows to switch them on
1310 bool bVisible
= pIFace
->IsObjectBarVisible(nNo
);
1312 nPos
&= SFX_POSITION_MASK
;
1314 SfxObjectBars_Impl
& rBar
= xImp
->aObjBars
[nPos
& SFX_POSITION_MASK
];
1316 rBar
.nResId
= pIFace
->GetObjectBarId(nNo
);
1317 rBar
.pIFace
= pIFace
;
1319 if ( bUIActive
|| bIsActive
)
1321 pWorkWin
->SetObjectBar_Impl(nPos
, rBar
.nResId
, rBar
.pIFace
);
1328 for ( nNo
=0; pIFace
&& nNo
<pIFace
->GetChildWindowCount(); nNo
++ )
1330 sal_uInt32 nId
= pIFace
->GetChildWindowId(nNo
);
1331 const SfxSlot
*pSlot
= pSlotPool
->GetSlot( (sal_uInt16
) nId
);
1332 SAL_WARN_IF( !pSlot
, "sfx.control", "Childwindow slot missing: " << nId
);
1333 if ( bReadOnlyShell
)
1335 // only show ChildWindows if their slot is allowed for readonly documents
1336 if ( pSlot
&& !pSlot
->IsMode( SfxSlotMode::READONLYDOC
) )
1340 sal_uInt32 nFeature
= pIFace
->GetChildWindowFeature(nNo
);
1341 if ( nFeature
&& !pShell
->HasUIFeature( nFeature
) )
1344 // slot decides whether a ChildWindow is shown when document is OLE server or OLE client
1345 sal_uInt16 nMode
= SFX_VISIBILITY_STANDARD
;
1348 if ( pSlot
->IsMode(SfxSlotMode::CONTAINER
) )
1350 if ( pWorkWin
->IsVisible_Impl( SFX_VISIBILITY_CLIENT
) )
1351 nMode
|= SFX_VISIBILITY_CLIENT
;
1355 if ( pWorkWin
->IsVisible_Impl( SFX_VISIBILITY_SERVER
) )
1356 nMode
|= SFX_VISIBILITY_SERVER
;
1360 if ( bUIActive
|| bIsActive
)
1361 pWorkWin
->SetChildWindowVisible_Impl( nId
, true, nMode
);
1362 if ( bUIActive
|| bIsActive
|| !pWorkWin
->IsFloating( (sal_uInt16
) ( nId
& 0xFFFF ) ) )
1363 xImp
->aChildWins
.push_back( nId
);
1366 if ( bIsMDIApp
|| bIsIPOwner
)
1368 sal_uInt32 nId
= pIFace
->GetStatusBarResId().GetId();
1372 pStatusBarShell
= pShell
;
1377 for ( sal_uInt16 nPos
=0; nPos
<SFX_OBJECTBAR_MAX
; nPos
++ )
1379 SfxObjectBars_Impl
& rFixed
= xImp
->aFixedObjBars
[nPos
];
1380 if ( rFixed
.nResId
)
1382 SfxObjectBars_Impl
& rBar
= xImp
->aObjBars
[nPos
];
1384 pWorkWin
->SetObjectBar_Impl(rFixed
.nMode
,
1385 rFixed
.nResId
, rFixed
.pIFace
);
1389 if ( pTaskWin
&& ( bIsMDIApp
|| bIsIPOwner
) )
1391 bool bIsTaskActive
= false;
1393 SfxDispatcher
*pActDispatcher
= pTaskWin
->GetBindings().GetDispatcher_Impl();
1394 SfxDispatcher
*pDispatcher
= this;
1395 while ( pActDispatcher
&& !bIsTaskActive
)
1397 if ( pDispatcher
== pActDispatcher
)
1398 bIsTaskActive
= true;
1399 pActDispatcher
= pActDispatcher
->xImp
->pParent
;
1402 if ( bIsTaskActive
&& nStatBarId
&& xImp
->pFrame
)
1404 // internal frames also may control statusbar
1405 SfxBindings
& rBindings
= xImp
->pFrame
->GetBindings();
1406 xImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->SetStatusBar_Impl( nStatBarId
, pStatusBarShell
, rBindings
);
1411 /** Helper method to execute the outstanding push and pop commands.
1413 void SfxDispatcher::FlushImpl()
1415 SFX_STACK(SfxDispatcher::FlushImpl
);
1417 OSL_TRACE("Flushing dispatcher!");
1421 if ( xImp
->pParent
)
1422 xImp
->pParent
->Flush();
1424 xImp
->bFlushing
= !xImp
->bFlushing
;
1425 if ( !xImp
->bFlushing
)
1427 xImp
->bFlushing
= true;
1431 SfxApplication
*pSfxApp
= SfxGetpApp();
1433 // Re-build the true stack in the first round
1434 std::deque
<SfxToDo_Impl
> aToDoCopy
;
1435 bool bModify
= false;
1436 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= xImp
->aToDoStack
.rbegin(); i
!= xImp
->aToDoStack
.rend(); ++i
)
1443 DBG_ASSERT( std::find(xImp
->aStack
.begin(), xImp
->aStack
.end(), i
->pCluster
) == xImp
->aStack
.end(),
1444 "pushed SfxShell already on stack" );
1445 xImp
->aStack
.push_back(i
->pCluster
);
1446 i
->pCluster
->SetDisableFlags(xImp
->nDisableFlags
);
1448 // Mark the moved shell
1449 aToDoCopy
.push_front(*i
);
1454 SfxShell
* pPopped
= 0;
1455 bool bFound
= false;
1458 DBG_ASSERT( !xImp
->aStack
.empty(), "popping from empty stack" );
1459 pPopped
= xImp
->aStack
.back();
1460 xImp
->aStack
.pop_back();
1461 pPopped
->SetDisableFlags( 0 );
1462 bFound
= (pPopped
== i
->pCluster
);
1464 // Mark the moved Shell
1465 aToDoCopy
.push_front(SfxToDo_Impl(false, i
->bDelete
, false, *pPopped
));
1467 while(i
->bUntil
&& !bFound
);
1468 DBG_ASSERT( bFound
, "wrong SfxShell popped" );
1471 xImp
->aToDoStack
.clear();
1473 // Invalidate bindings, if possible
1474 if ( !pSfxApp
->IsDowning() )
1478 xImp
->pCachedServ1
= 0;
1479 xImp
->pCachedServ2
= 0;
1482 InvalidateBindings_Impl( bModify
);
1485 xImp
->bFlushing
= false;
1486 xImp
->bUpdated
= false; // not only when bModify, if Doc/Template-Config
1487 xImp
->bFlushed
= true;
1488 OSL_TRACE("Successfully flushed dispatcher!");
1490 //fdo#70703 FlushImpl may call back into itself so use aToDoCopyStack to talk
1491 //to outer levels of ourself. If DoActivate_Impl/DoDeactivate_Impl deletes
1492 //an entry, then they will walk back up aToDoCopyStack and set outer
1493 //levels's entries to bDeleted
1494 xImp
->aToDoCopyStack
.push_back(aToDoCopy
);
1495 std::deque
<SfxToDo_Impl
>& rToDoCopy
= xImp
->aToDoCopyStack
.back();
1496 // Activate the Shells and possible delete them in the 2nd round
1497 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= rToDoCopy
.rbegin(); i
!= rToDoCopy
.rend(); ++i
)
1504 i
->pCluster
->DoActivate_Impl(xImp
->pFrame
, true);
1506 i
->pCluster
->DoDeactivate_Impl(xImp
->pFrame
, true);
1509 aToDoCopy
= xImp
->aToDoCopyStack
.back();
1510 xImp
->aToDoCopyStack
.pop_back();
1512 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= aToDoCopy
.rbegin(); i
!= aToDoCopy
.rend(); ++i
)
1514 if (i
->bDelete
&& !i
->bDeleted
)
1516 if (!xImp
->aToDoCopyStack
.empty())
1518 //fdo#70703 if there is an outer FlushImpl then inform it that
1519 //we have deleted this cluster
1520 for (std::deque
< std::deque
<SfxToDo_Impl
> >::iterator aI
= xImp
->aToDoCopyStack
.begin();
1521 aI
!= xImp
->aToDoCopyStack
.end(); ++aI
)
1523 std::deque
<SfxToDo_Impl
> &v
= *aI
;
1524 for(std::deque
<SfxToDo_Impl
>::iterator aJ
= v
.begin(); aJ
!= v
.end(); ++aJ
)
1526 if (aJ
->pCluster
== i
->pCluster
)
1527 aJ
->bDeleted
= true;
1534 bool bAwakeBindings
= !aToDoCopy
.empty();
1535 if( bAwakeBindings
)
1538 // If more changes have occurred on the stach when
1539 // Activate/Deactivate/Delete:
1540 if (!xImp
->bFlushed
)
1541 // If Push/Pop hs been called by someone, theb also EnterReg was called!
1544 if( bAwakeBindings
&& GetBindings() )
1545 GetBindings()->DLEAVEREGISTRATIONS();
1547 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
1548 xImp
->aFixedObjBars
[n
].nResId
= 0;
1550 SAL_INFO("sfx.control", "SfxDispatcher(" << this << ")::Flush() done");
1553 /** With this method a filter set, the target slots can be enabled or disabled.
1554 The passed array must be retained until the destructor or the next
1555 <SetSlotFilter()>, it is not deleted from the dispatcher, so it can thus be
1558 In read-only documents the quasi ReadOnlyDoc Flag of slots can be
1559 overturned by the use of 'bEnable == 2', so this will be displayed again.
1560 On the other slots it has no effect.
1562 // HACK(hier muss mal ein enum rein) ???
1563 @param nEnable 1==true: only enable specified slots, disable all other
1564 0==false: disable specified slots, first enable all other
1565 @param nCount Number of SIDs in the following Array
1566 @param pSIDs sorted Array of 'nCount' SIDs
1570 Targeted disabling of Slots 1, 2 and 3:
1572 static sal_uInt16 const pSIDs[] = { 1, 2, 3 };
1573 pDisp->SetSlotFilter( sal_False, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
1575 only permit Slots 5, 6 and 7:
1577 static sal_uInt16 const pSIDs[] = { 5, 6, 7 };
1578 pDisp->SetSlotFilter( sal_True, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
1582 pDisp->SetSlotFilter();
1584 void SfxDispatcher::SetSlotFilter(SfxSlotFilterState nEnable
,
1585 sal_uInt16 nCount
, const sal_uInt16
* pSIDs
)
1589 for ( sal_uInt16 n
= 1; n
< nCount
; ++n
)
1590 DBG_ASSERT( pSIDs
[n
] > pSIDs
[n
-1], "SetSlotFilter: SIDs not sorted" );
1593 if ( xImp
->pFilterSIDs
)
1594 xImp
->pFilterSIDs
= 0;
1596 xImp
->nFilterEnabling
= nEnable
;
1597 xImp
->nFilterCount
= nCount
;
1598 xImp
->pFilterSIDs
= pSIDs
;
1600 GetBindings()->InvalidateAll(true);
1603 extern "C" int SAL_CALL
SfxCompareSIDs_Impl(const void* pSmaller
, const void* pBigger
)
1605 return ( (long) *static_cast<sal_uInt16
const *>(pSmaller
) ) - ( (long) *static_cast<sal_uInt16
const *>(pBigger
) );
1608 /** Searches for 'nSID' in the Filter set by <SetSlotFilter()> and
1609 returns sal_True, if the SIDis allowed, or sal_False, if it is
1610 disabled by the Filter.
1612 @return 0 => disabled
1614 2 => enabled even if ReadOnlyDoc
1616 SfxSlotFilterState
SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID
) const
1619 if ( 0 == xImp
->nFilterCount
)
1620 // => all SIDs allowed
1621 return SfxSlotFilterState::ENABLED
;
1624 bool bFound
= 0 != bsearch( &nSID
, xImp
->pFilterSIDs
, xImp
->nFilterCount
,
1625 sizeof(sal_uInt16
), SfxCompareSIDs_Impl
);
1627 // even if ReadOnlyDoc
1628 if ( SfxSlotFilterState::ENABLED_READONLY
== xImp
->nFilterEnabling
)
1629 return bFound
? SfxSlotFilterState::ENABLED_READONLY
: SfxSlotFilterState::ENABLED
;
1630 // Otherwise after Negative/Positive Filter
1631 else if ( SfxSlotFilterState::ENABLED
== xImp
->nFilterEnabling
)
1632 return bFound
? SfxSlotFilterState::ENABLED
: SfxSlotFilterState::DISABLED
;
1634 return bFound
? SfxSlotFilterState::DISABLED
: SfxSlotFilterState::ENABLED
;
1637 /** This helper method searches for the <Slot-Server> which currently serves
1638 the nSlot. As the result, rServe is filled accordingly.
1640 If known the SfxInterface which is currently served by nSlot can be
1643 The SfxDispatcher is flushed while searching for nSlot.
1645 @param nSlot Slot-Id to search for
1646 @param rServer <SfxSlotServer>-Instance to fill
1647 @param bModal Despite ModalMode
1650 The Slot was found, rServer is valid.
1653 The Slot is currently not served, rServer is invalid.
1655 bool SfxDispatcher::_FindServer(sal_uInt16 nSlot
, SfxSlotServer
& rServer
, bool bModal
)
1657 SFX_STACK(SfxDispatcher::_FindServer
);
1659 // Dispatcher locked? (nevertheless let SID_HELP_PI through)
1660 if ( IsLocked(nSlot
) )
1662 xImp
->bInvalidateOnUnlock
= true;
1666 // Count the number of Shells in the linked dispatchers.
1668 sal_uInt16 nTotCount
= xImp
->aStack
.size();
1669 if ( xImp
->pParent
)
1671 SfxDispatcher
*pParent
= xImp
->pParent
;
1674 nTotCount
= nTotCount
+ pParent
->xImp
->aStack
.size();
1675 pParent
= pParent
->xImp
->pParent
;
1680 if (nSlot
>= SID_VERB_START
&& nSlot
<= SID_VERB_END
)
1682 for ( sal_uInt16 nShell
= 0;; ++nShell
)
1684 SfxShell
*pSh
= GetShell(nShell
);
1687 if ( pSh
->ISA(SfxViewShell
) )
1689 const SfxSlot
* pSlot
= pSh
->GetVerbSlot_Impl(nSlot
);
1692 rServer
.SetShellLevel(nShell
);
1693 rServer
.SetSlot( pSlot
);
1700 // SID check against set filter
1701 SfxSlotFilterState nSlotEnableMode
= SfxSlotFilterState::DISABLED
;
1704 nSlotEnableMode
= IsSlotEnabledByFilter_Impl( nSlot
);
1705 if ( SfxSlotFilterState::DISABLED
== nSlotEnableMode
)
1709 // In Quiet-Mode only Parent-Dispatcher
1712 if ( xImp
->pParent
)
1714 bool bRet
= xImp
->pParent
->_FindServer( nSlot
, rServer
, bModal
);
1715 rServer
.SetShellLevel
1716 ( rServer
.GetShellLevel() + xImp
->aStack
.size() );
1723 bool bReadOnly
= ( SfxSlotFilterState::ENABLED_READONLY
!= nSlotEnableMode
&& xImp
->bReadOnly
);
1725 // search through all the shells of the chained dispatchers
1726 // from top to bottom
1727 sal_uInt16 nFirstShell
= xImp
->bModal
&& !bModal
? xImp
->aStack
.size() : 0;
1728 for ( sal_uInt16 i
= nFirstShell
; i
< nTotCount
; ++i
)
1730 SfxShell
*pObjShell
= GetShell(i
);
1731 SfxInterface
*pIFace
= pObjShell
->GetInterface();
1732 const SfxSlot
*pSlot
= pIFace
->GetSlot(nSlot
);
1734 if ( pSlot
&& pSlot
->nDisableFlags
&& ( pSlot
->nDisableFlags
& pObjShell
->GetDisableFlags() ) != 0 )
1737 if ( pSlot
&& !( pSlot
->nFlags
& SfxSlotMode::READONLYDOC
) && bReadOnly
)
1742 // Slot belongs to Container?
1743 bool bIsContainerSlot
= pSlot
->IsMode(SfxSlotMode::CONTAINER
);
1744 bool bIsInPlace
= xImp
->pFrame
&& xImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
1746 // Shell belongs to Server?
1747 // AppDispatcher or IPFrame-Dispatcher
1748 bool bIsServerShell
= !xImp
->pFrame
|| bIsInPlace
;
1750 // Of course ShellServer-Slots are also executable even when it is
1751 // executed on a container dispatcher without a IPClient.
1752 if ( !bIsServerShell
)
1754 SfxViewShell
*pViewSh
= xImp
->pFrame
->GetViewShell();
1755 bIsServerShell
= !pViewSh
|| !pViewSh
->GetUIActiveClient();
1758 // Shell belongs to Container?
1759 // AppDispatcher or no IPFrameDispatcher
1760 bool bIsContainerShell
= !xImp
->pFrame
|| !bIsInPlace
;
1761 // Shell and Slot match
1762 if ( !( ( bIsContainerSlot
&& bIsContainerShell
) ||
1763 ( !bIsContainerSlot
&& bIsServerShell
) ) )
1769 rServer
.SetSlot(pSlot
);
1770 rServer
.SetShellLevel(i
);
1778 /** Helper method to obtain the status of the <Slot-Server>s rSvr.
1779 The required slots IDs (partly converted to Which-IDs of the pool)
1780 must be present in rstate.
1782 The SfxDispatcher is flushed before the query.
1784 @param rSvr Slot-Server to query
1785 @param rState SfxItemSet to be filled
1786 @param pRealSlot The actual Slot if possible
1788 bool SfxDispatcher::_FillState(const SfxSlotServer
& rSvr
, SfxItemSet
& rState
,
1789 const SfxSlot
* pRealSlot
)
1791 SFX_STACK(SfxDispatcher::_FillState
);
1793 const SfxSlot
*pSlot
= rSvr
.GetSlot();
1794 if ( pSlot
&& IsLocked( pSlot
->GetSlotId() ) )
1796 xImp
->bInvalidateOnUnlock
= true;
1802 DBG_ASSERT(xImp
->bFlushed
,
1803 "Dispatcher not flushed after retrieving slot servers!");
1804 if (!xImp
->bFlushed
)
1807 // Determine the object and call the Message of this object
1808 SfxShell
*pSh
= GetShell(rSvr
.GetShellLevel());
1809 DBG_ASSERT(pSh
, "ObjectShell not found");
1814 pFunc
= pRealSlot
->GetStateFnc();
1816 pFunc
= pSlot
->GetStateFnc();
1818 pSh
->CallState( pFunc
, rState
);
1820 // To examine the conformity of IDL (SlotMap) and current Items
1821 if ( rState
.Count() )
1823 SfxInterface
*pIF
= pSh
->GetInterface();
1824 SfxItemIter
aIter( rState
);
1825 for ( const SfxPoolItem
*pItem
= aIter
.FirstItem();
1827 pItem
= aIter
.NextItem() )
1829 if ( !IsInvalidItem(pItem
) && !pItem
->ISA(SfxVoidItem
) )
1831 sal_uInt16 nSlotId
= rState
.GetPool()->GetSlotId(pItem
->Which());
1833 !pItem
->IsA(pIF
->GetSlot(nSlotId
)->GetType()->Type()),
1835 "item-type unequal to IDL (=> no BASIC) with SID: "
1836 << nSlotId
<< " in " << pIF
->GetClassName());
1848 SfxPopupMenuManager
* SfxDispatcher::Popup( sal_uInt16 nConfigId
, vcl::Window
*pWin
, const Point
*pPos
)
1850 SfxDispatcher
&rDisp
= *SfxGetpApp()->GetDispatcher_Impl();
1851 sal_uInt16 nShLevel
= 0;
1854 if ( rDisp
.xImp
->bQuiet
)
1857 nShLevel
= rDisp
.xImp
->aStack
.size();
1860 vcl::Window
*pWindow
= pWin
? pWin
: rDisp
.xImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
1861 for ( pSh
= rDisp
.GetShell(nShLevel
); pSh
; ++nShLevel
, pSh
= rDisp
.GetShell(nShLevel
) )
1863 const ResId
& rResId
= pSh
->GetInterface()->GetPopupMenuResId();
1864 if ( ( nConfigId
== 0 && rResId
.GetId() ) || ( nConfigId
!= 0 && rResId
.GetId() == nConfigId
) )
1866 return SfxPopupMenuManager::Popup( rResId
, rDisp
.GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
1872 void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId
, vcl::Window
*pWin
, const Point
*pPos
)
1874 SfxDispatcher
&rDisp
= *SfxGetpApp()->GetDispatcher_Impl();
1875 sal_uInt16 nShLevel
= 0;
1878 if ( rDisp
.xImp
->bQuiet
)
1881 nShLevel
= rDisp
.xImp
->aStack
.size();
1884 vcl::Window
*pWindow
= pWin
? pWin
: rDisp
.xImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
1885 for ( pSh
= rDisp
.GetShell(nShLevel
); pSh
; ++nShLevel
, pSh
= rDisp
.GetShell(nShLevel
) )
1887 const ResId
& rResId
= pSh
->GetInterface()->GetPopupMenuResId();
1888 if ( ( nConfigId
== 0 && rResId
.GetId() ) || ( nConfigId
!= 0 && rResId
.GetId() == nConfigId
) )
1890 SfxPopupMenuManager::ExecutePopup( rResId
, rDisp
.GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
1896 void SfxDispatcher::ExecutePopup( const ResId
&rId
, vcl::Window
*pWin
, const Point
*pPos
)
1898 vcl::Window
*pWindow
= pWin
? pWin
: xImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
1899 SfxPopupMenuManager::ExecutePopup( rId
, GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
1902 /** With this method the SfxDispatcher can be locked and released. A locked
1903 SfxDispatcher does not perform <SfxRequest>s and does no longer provide
1904 status information. It behaves as if all the slots were disabled.
1906 void SfxDispatcher::Lock( bool bLock
)
1908 SfxBindings
* pBindings
= GetBindings();
1909 if ( !bLock
&& xImp
->bLocked
&& xImp
->bInvalidateOnUnlock
)
1912 pBindings
->InvalidateAll(true);
1913 xImp
->bInvalidateOnUnlock
= false;
1915 else if ( pBindings
)
1916 pBindings
->InvalidateAll(false);
1917 xImp
->bLocked
= bLock
;
1920 for(size_t i
= 0; i
< xImp
->aReqArr
.size(); ++i
)
1921 xImp
->xPoster
->Post(xImp
->aReqArr
[i
]);
1922 xImp
->aReqArr
.clear();
1926 sal_uInt32
SfxDispatcher::GetObjectBarId( sal_uInt16 nPos
) const
1928 return xImp
->aObjBars
[nPos
].nResId
;
1931 void SfxDispatcher::HideUI( bool bHide
)
1933 bool bWasHidden
= xImp
->bNoUI
;
1934 xImp
->bNoUI
= bHide
;
1937 SfxViewFrame
* pTop
= xImp
->pFrame
->GetTopViewFrame();
1938 if ( pTop
&& pTop
->GetBindings().GetDispatcher() == this )
1940 SfxFrame
& rFrame
= pTop
->GetFrame();
1941 if ( rFrame
.IsMenuBarOn_Impl() )
1943 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( rFrame
.GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
1944 if ( xPropSet
.is() )
1946 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1947 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1948 aValue
>>= xLayoutManager
;
1949 if ( xLayoutManager
.is() )
1950 xLayoutManager
->setVisible( !bHide
);
1956 if ( bHide
!= bWasHidden
)
1957 Update_Impl( true );
1960 void SfxDispatcher::SetReadOnly_Impl( bool bOn
)
1962 xImp
->bReadOnly
= bOn
;
1965 bool SfxDispatcher::GetReadOnly_Impl() const
1967 return xImp
->bReadOnly
;
1970 /** With 'bOn' the Dispatcher is quasi dead and transfers everything to the
1973 void SfxDispatcher::SetQuietMode_Impl( bool bOn
)
1976 SfxBindings
* pBindings
= GetBindings();
1978 pBindings
->InvalidateAll(true);
1981 SfxItemState
SfxDispatcher::QueryState( sal_uInt16 nSlot
, const SfxPoolItem
* &rpState
)
1983 SfxShell
*pShell
= 0;
1984 const SfxSlot
*pSlot
= 0;
1985 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, false, false ) )
1987 rpState
= pShell
->GetSlotState(nSlot
);
1989 return SfxItemState::DISABLED
;
1991 return SfxItemState::DEFAULT
;
1994 return SfxItemState::DISABLED
;
1997 SfxItemState
SfxDispatcher::QueryState( sal_uInt16 nSID
, ::com::sun::star::uno::Any
& rAny
)
1999 SfxShell
*pShell
= 0;
2000 const SfxSlot
*pSlot
= 0;
2001 if ( GetShellAndSlot_Impl( nSID
, &pShell
, &pSlot
, false, false ) )
2003 const SfxPoolItem
* pItem( 0 );
2005 pItem
= pShell
->GetSlotState( nSID
);
2007 return SfxItemState::DISABLED
;
2010 ::com::sun::star::uno::Any aState
;
2011 if ( !pItem
->ISA(SfxVoidItem
) )
2013 sal_uInt16
nSubId( 0 );
2014 SfxItemPool
& rPool
= pShell
->GetPool();
2015 sal_uInt16 nWhich
= rPool
.GetWhich( nSID
);
2016 if ( rPool
.GetMetric( nWhich
) == SFX_MAPUNIT_TWIP
)
2017 nSubId
|= CONVERT_TWIPS
;
2018 pItem
->QueryValue( aState
, (sal_uInt8
)nSubId
);
2022 return SfxItemState::DEFAULT
;
2026 return SfxItemState::DISABLED
;
2029 bool SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell
) const
2031 sal_uInt16 nShellCount
= xImp
->aStack
.size();
2032 if ( nShell
< nShellCount
)
2034 SfxShell
* pShell
= *( xImp
->aStack
.rbegin() + nShell
);
2035 if( pShell
->ISA( SfxModule
) || pShell
->ISA( SfxApplication
) || pShell
->ISA( SfxViewFrame
) )
2038 return xImp
->bReadOnly
;
2040 else if ( xImp
->pParent
)
2041 return xImp
->pParent
->IsReadOnlyShell_Impl( nShell
- nShellCount
);
2045 void SfxDispatcher::RemoveShell_Impl( SfxShell
& rShell
)
2049 sal_uInt16 nCount
= xImp
->aStack
.size();
2050 for ( sal_uInt16 n
=0; n
<nCount
; ++n
)
2052 if ( xImp
->aStack
[n
] == &rShell
)
2054 xImp
->aStack
.erase( xImp
->aStack
.begin() + n
);
2055 rShell
.SetDisableFlags( 0 );
2056 rShell
.DoDeactivate_Impl(xImp
->pFrame
, true);
2061 if ( !SfxGetpApp()->IsDowning() )
2063 xImp
->bUpdated
= false;
2064 xImp
->pCachedServ1
= 0;
2065 xImp
->pCachedServ2
= 0;
2066 InvalidateBindings_Impl(true);
2070 void SfxDispatcher::InvalidateBindings_Impl( bool bModify
)
2073 if ( IsAppDispatcher() )
2075 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst();
2077 pFrame
= SfxViewFrame::GetNext( *pFrame
) )
2078 pFrame
->GetBindings().InvalidateAll(bModify
);
2082 SfxDispatcher
*pDisp
= GetBindings()->GetDispatcher_Impl();
2085 if ( pDisp
== this )
2087 GetBindings()->InvalidateAll( bModify
);
2091 pDisp
= pDisp
->xImp
->pParent
;
2096 bool SfxDispatcher::IsUpdated_Impl() const
2098 return xImp
->bUpdated
;
2101 void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags
)
2103 xImp
->nDisableFlags
= nFlags
;
2104 for ( SfxShellStack_Impl::reverse_iterator it
= xImp
->aStack
.rbegin(); it
!= xImp
->aStack
.rend(); ++it
)
2105 (*it
)->SetDisableFlags( nFlags
);
2108 sal_uInt32
SfxDispatcher::GetDisableFlags() const
2110 return xImp
->nDisableFlags
;
2113 SfxModule
* SfxDispatcher::GetModule() const
2115 for ( sal_uInt16 nShell
= 0;; ++nShell
)
2117 SfxShell
*pSh
= GetShell(nShell
);
2120 if ( pSh
->ISA(SfxModule
) )
2121 return static_cast<SfxModule
*>(pSh
);
2125 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */