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>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
32 #include <com/sun/star/frame/XLayoutManager.hpp>
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>
62 #include <appdata.hxx>
63 #include <sfxtypes.hxx>
64 #include <slotserv.hxx>
65 #include <workwin.hxx>
67 DBG_NAME(SfxDispatcherFlush
)
68 DBG_NAME(SfxDispatcherFillState
)
70 typedef std::vector
<SfxRequest
*> SfxRequestPtrArray
;
72 struct SfxObjectBars_Impl
74 sal_uInt32 nResId
; // Resource - and ConfigId of the Toolbox
75 sal_uInt16 nMode
; // special visibility flags
79 SfxObjectBars_Impl() : nResId(0), nMode(0), pIFace(NULL
) {}
82 //------------------------------------------------------------------
84 struct SfxDispatcher_Impl
86 //When the dispatched is locked, SfxRequests accumulate in aReqArr for
87 //later dispatch when unlocked via Post
89 //The pointers are typically deleted in Post, only if we never get around
90 //to posting them do we delete the unposted requests.
91 SfxRequestPtrArray aReqArr
;
94 for (SfxRequestPtrArray::iterator aI
= aReqArr
.begin(), aEnd
= aReqArr
.end(); aI
!= aEnd
; ++aI
)
97 const SfxSlotServer
* pCachedServ1
; // last called message
98 const SfxSlotServer
* pCachedServ2
; // penultimate called Message
99 SfxShellStack_Impl aStack
; // active functionality
100 Timer aTimer
; // for Flush
101 std::deque
<SfxToDo_Impl
> aToDoStack
; // not processed Push/Pop
102 SfxViewFrame
* pFrame
; // NULL or associated Frame
103 SfxDispatcher
* pParent
; // AppDispatcher, NULL if possible
104 SfxHintPosterRef xPoster
; // Execute asynchronous
105 sal_Bool bFlushing
; // sal_True during Flush //?
106 sal_Bool bUpdated
; // Update_Impl has run
107 sal_Bool bLocked
; // No Execute
108 sal_Bool bInvalidateOnUnlock
; // because someone asked
109 sal_Bool bActive
; // not to be confused with set!
110 sal_Bool
* pInCallAliveFlag
; // view the Destructor Stack
111 SfxObjectBars_Impl aObjBars
[SFX_OBJECTBAR_MAX
];
112 SfxObjectBars_Impl aFixedObjBars
[SFX_OBJECTBAR_MAX
];
113 std::vector
<sal_uInt32
> aChildWins
;
114 sal_uInt32 nEventId
; // EventId UserEvent
115 sal_Bool bNoUI
; // UI only from Parent Dispatcher
116 sal_Bool bReadOnly
; // Document is ReadOnly
117 sal_Bool bQuiet
; // Only use parent dispatcher
118 sal_Bool bModal
; // Only slots from parent dispatcher
120 sal_Bool bFilterEnabling
; // sal_True=filter enabled slots,
121 // 2==ReadOnlyDoc overturned
122 sal_uInt16 nFilterCount
; // Number of SIDs in pFilterSIDs
123 const sal_uInt16
* pFilterSIDs
; // sorted Array of SIDs
124 sal_uInt32 nDisableFlags
;
127 //------------------------------------------------------------------
129 #define SFX_FLUSH_TIMEOUT 50
131 //====================================================================
132 sal_Bool
SfxDispatcher::IsLocked( sal_uInt16
) const
136 With this method it can be determined whether the SfxDispatcher is
137 locked or unlocked. A locked SfxDispatcher does not perform <SfxRequest>s
138 and no longer provides any status information. It behaves as if all the
141 The dispatcher is also marked as blocked, if all Dispatcher are locked
142 (<SfxApplication::LockDispatcher()>) or the associated top frame is in the
143 modal-mode and if the specified slot are handled as frame-specific
144 (ie, not served by the application).
148 return pImp
->bLocked
;
151 //--------------------------------------------------------------------
152 sal_Bool
SfxDispatcher::IsAppDispatcher() const
156 With this method it can be determined if the SfxDispacher is the
157 applications dispatcher.
161 sal_Bool sal_True it is the application dispatcher.
162 sal_Fals it is a SfxViewFrame dispatcher.
166 return !pImp
->pFrame
;
169 //--------------------------------------------------------------------
170 int SfxDispatcher::Call_Impl( SfxShell
& rShell
, const SfxSlot
&rSlot
, SfxRequest
&rReq
, sal_Bool bRecord
)
174 Helper function to check whether a slot can be executed and
175 check the execution itself
179 SFX_STACK(SfxDispatcher::Call_Impl
);
181 // The slot may be called (meaning enabled)
182 if ( rSlot
.IsMode(SFX_SLOT_FASTCALL
) || rShell
.CanExecuteSlot_Impl(rSlot
) )
186 // Recording may start
187 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xFrame(
188 GetFrame()->GetFrame().GetFrameInterface(),
189 com::sun::star::uno::UNO_QUERY
);
191 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xSet(
193 com::sun::star::uno::UNO_QUERY
);
197 com::sun::star::uno::Any aProp
= xSet
->getPropertyValue("DispatchRecorderSupplier");
198 com::sun::star::uno::Reference
< com::sun::star::frame::XDispatchRecorderSupplier
> xSupplier
;
199 com::sun::star::uno::Reference
< com::sun::star::frame::XDispatchRecorder
> xRecorder
;
202 xRecorder
= xSupplier
->getDispatchRecorder();
204 if ( bRecord
&& xRecorder
.is() && !rSlot
.IsMode(SFX_SLOT_NORECORD
) )
205 rReq
.Record_Impl( rShell
, rSlot
, xRecorder
, GetFrame() );
208 // Get all that is needed, because the slot may not have survived the
209 // Execute if it is a 'pseudo slot' for macros or verbs.
210 sal_Bool bAutoUpdate
= rSlot
.IsMode(SFX_SLOT_AUTOUPDATE
);
212 // API-call parentheses and document-lock during the calls
214 // 'this' must respond in the Destructor
215 sal_Bool bThisDispatcherAlive
= sal_True
;
216 sal_Bool
*pOldInCallAliveFlag
= pImp
->pInCallAliveFlag
;
217 pImp
->pInCallAliveFlag
= &bThisDispatcherAlive
;
219 SfxExecFunc pFunc
= rSlot
.GetExecFnc();
220 rShell
.CallExec( pFunc
, rReq
);
222 // If 'this' is still alive
223 if ( bThisDispatcherAlive
)
224 pImp
->pInCallAliveFlag
= pOldInCallAliveFlag
;
227 if ( pOldInCallAliveFlag
)
229 // also protect nested stack frames
230 *pOldInCallAliveFlag
= sal_False
;
233 // do nothing after this object is dead
234 return rReq
.IsDone();
240 SfxBindings
*pBindings
= GetBindings();
242 // When AutoUpdate update immediately; "Pseudoslots" must not be
244 if ( bAutoUpdate
&& pBindings
)
246 const SfxSlot
* pSlave
= rSlot
.GetLinkedSlot();
249 // When enum slots take any bound slave slot
250 while (!pBindings
->IsBound(pSlave
->GetSlotId()) && pSlave
!= &rSlot
)
251 pSlave
= pSlave
->GetLinkedSlot();
252 pBindings
->Invalidate(pSlave
->GetSlotId());
253 pBindings
->Update(pSlave
->GetSlotId());
257 pBindings
->Invalidate(rSlot
.GetSlotId());
258 pBindings
->Update(rSlot
.GetSlotId());
269 //====================================================================
270 void SfxDispatcher::Construct_Impl( SfxDispatcher
* pParent
)
272 pImp
= new SfxDispatcher_Impl
;
275 pImp
->pCachedServ1
= 0;
276 pImp
->pCachedServ2
= 0;
277 pImp
->bFlushing
= sal_False
;
278 pImp
->bUpdated
= sal_False
;
279 pImp
->bLocked
= sal_False
;
280 pImp
->bActive
= sal_False
;
281 pImp
->pParent
= NULL
;
282 pImp
->bNoUI
= sal_False
;
283 pImp
->bReadOnly
= sal_False
;
284 pImp
->bQuiet
= sal_False
;
285 pImp
->bModal
= sal_False
;
286 pImp
->pInCallAliveFlag
= 0;
287 pImp
->bFilterEnabling
= sal_False
;
288 pImp
->nFilterCount
= 0;
289 pImp
->pFilterSIDs
= 0;
290 pImp
->nDisableFlags
= 0;
292 pImp
->pParent
= pParent
;
294 pImp
->bInvalidateOnUnlock
= sal_False
;
296 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
297 pImp
->aObjBars
[n
].nResId
= 0;
299 GenLink
aGenLink( LINK(this, SfxDispatcher
, PostMsgHandler
) );
301 pImp
->xPoster
= new SfxHintPoster(aGenLink
);
303 pImp
->aTimer
.SetTimeout(SFX_FLUSH_TIMEOUT
);
304 pImp
->aTimer
.SetTimeoutHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
307 SfxDispatcher::SfxDispatcher( SfxDispatcher
* pParent
)
309 Construct_Impl( pParent
);
313 SfxDispatcher::SfxDispatcher( SfxViewFrame
*pViewFrame
)
317 The constructor of the SfxDispatcher class places a stack of empty
318 <SfxShell> pointers. It is not initially locked and is considered flushed.
324 SfxViewFrame
*pFrame
= pViewFrame
->GetParentViewFrame();
326 Construct_Impl( pFrame
->GetDispatcher() );
332 pImp
->pFrame
= pViewFrame
;
335 //====================================================================
336 SfxDispatcher::~SfxDispatcher()
340 The destructor of the SfxDispatcher class should not be called when the
341 SfxDispatcher instance is active. It may, however, still be a <SfxShell>
342 pointer on the stack.
347 OStringBuffer
sTemp("Delete Dispatcher ");
348 sTemp
.append(reinterpret_cast<sal_Int64
>(this));
349 OSL_TRACE("%s", sTemp
.getStr());
350 DBG_ASSERT( !pImp
->bActive
, "deleting active Dispatcher" );
353 // So that no timer by Reschedule in PlugComm strikes the LeaveRegistrations
355 pImp
->xPoster
->SetEventHdl( Link() );
357 // Notify the stack varialbles in Call_Impl
358 if ( pImp
->pInCallAliveFlag
)
359 *pImp
->pInCallAliveFlag
= sal_False
;
361 // Get bindings and application
362 SfxApplication
*pSfxApp
= SFX_APP();
363 SfxBindings
* pBindings
= GetBindings();
365 // When not flushed, revive the bindings
366 if ( pBindings
&& !pSfxApp
->IsDowning() && !bFlushed
)
367 pBindings
->DLEAVEREGISTRATIONS();
369 // may unregister the bindings
372 if ( pBindings
->GetDispatcher_Impl() == this)
373 pBindings
->SetDispatcher(0);
374 pBindings
= pBindings
->GetSubBindings_Impl();
380 //====================================================================
381 void SfxDispatcher::Pop
383 SfxShell
& rShell
, /* the stack to take the SfxShell instance. */
385 sal_uInt16 nMode
/* SFX_SHELL_POP_UNTIL
386 Also all 'rShell' of SfxShells are taken from the
390 All SfxShells actually taken from the stack
393 SFX_SHELL_PUSH (InPlace use only)
394 The Shell is pushed. */
398 With this method, one or more <SfxShell> are poped from the SfxDispatcher.
399 The SfxShell is marked for popping and a timer is set up. Only when the
400 timer has reached the end, the pop is actually performed
401 ( <SfxDispatcher::Flush()> ) and the <SfxBindings> is invalidated.
402 While the timer is running the opposing push and pop commands on one
403 SfxShell cancel each other out.
407 DBG_ASSERT( rShell
.GetInterface(),
408 "pushing SfxShell without previous RegisterInterface()" );
410 bool bDelete
= (nMode
& SFX_SHELL_POP_DELETE
) == SFX_SHELL_POP_DELETE
;
411 bool bUntil
= (nMode
& SFX_SHELL_POP_UNTIL
) == SFX_SHELL_POP_UNTIL
;
412 bool bPush
= (nMode
& SFX_SHELL_PUSH
) == SFX_SHELL_PUSH
;
414 SfxApplication
*pSfxApp
= SFX_APP();
418 "-SfxDispatcher(" << this << (bPush
? ")::Push(" : ")::Pop(")
419 << (rShell
.GetInterface()
420 ? rShell
.GetInterface()->GetClassName() : SAL_STREAM(&rShell
))
421 << (bDelete
? ") with delete" : ")")
422 << (bUntil
? " (up to)" : ""));
424 // same shell as on top of the to-do stack?
425 if(pImp
->aToDoStack
.size() && pImp
->aToDoStack
.front().pCluster
== &rShell
)
427 // cancel inverse actions
428 if ( pImp
->aToDoStack
.front().bPush
!= bPush
)
429 pImp
->aToDoStack
.pop_front();
432 DBG_ASSERT( bPush
, "SfxInterface pushed more than once" );
433 DBG_ASSERT( !bPush
, "SfxInterface popped more than once" );
438 // Remember ::com::sun::star::chaos::Action
439 pImp
->aToDoStack
.push_front( SfxToDo_Impl(bPush
, bDelete
, bUntil
, rShell
) );
442 OSL_TRACE("Unflushed dispatcher!");
443 bFlushed
= sal_False
;
444 pImp
->bUpdated
= sal_False
;
446 // Put bindings to sleep
447 SfxBindings
* pBindings
= GetBindings();
449 pBindings
->DENTERREGISTRATIONS();
453 if(!pSfxApp
->IsDowning() && !pImp
->aToDoStack
.empty())
455 // No immediate update is requested
456 pImp
->aTimer
.SetTimeout(SFX_FLUSH_TIMEOUT
);
457 pImp
->aTimer
.SetTimeoutHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
458 pImp
->aTimer
.Start();
465 // Bindings may wake up again
466 if(pImp
->aToDoStack
.empty())
468 SfxBindings
* pBindings
= GetBindings();
470 pBindings
->DLEAVEREGISTRATIONS();
475 //--------------------------------------------------------------------
477 IMPL_LINK_INLINE_START( SfxDispatcher
, EventHdl_Impl
, void *, pvoid
)
481 This handler is called after <SfxDispatcher::Invalidate()> or after
482 changes on the stack (<SfxDispatcher::Push()> and <SfxDispatcher::Pop())
484 It flushes the Stack, if it is dirty, thus it actually excecutes the
485 pending Push and Pop commands.
489 (void)pvoid
; // unused
493 SfxBindings
* pBindings
= GetBindings();
495 pBindings
->StartUpdate_Impl(sal_False
);
498 IMPL_LINK_INLINE_END( SfxDispatcher
, EventHdl_Impl
, void *, pvoid
)
500 //--------------------------------------------------------------------
501 sal_Bool
SfxDispatcher::CheckVirtualStack( const SfxShell
& rShell
, sal_Bool bDeep
)
505 With this method it can be tested whether the <SfxShell> rShell is on the
506 stack, when it was flushed. This way the SfxDispatcher is not actually
509 This method is intended among other things to make assertions possible
510 without the side effect of having to flush the SfxDispathcer.
514 SFX_STACK(SfxDispatcher::CheckVirtualStack
);
516 SfxShellStack_Impl
aStack( pImp
->aStack
);
517 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= pImp
->aToDoStack
.rbegin(); i
!= pImp
->aToDoStack
.rend(); ++i
)
520 aStack
.push_back(i
->pCluster
);
523 SfxShell
* pPopped(NULL
);
526 DBG_ASSERT( !aStack
.empty(), "popping from empty stack" );
527 pPopped
= aStack
.back();
530 while(i
->bUntil
&& pPopped
!= i
->pCluster
);
531 DBG_ASSERT(pPopped
== i
->pCluster
, "popping unpushed SfxInterface");
537 bReturn
= std::find(aStack
.begin(), aStack
.end(), &rShell
) != aStack
.end();
539 bReturn
= aStack
.back() == &rShell
;
543 //--------------------------------------------------------------------
544 sal_uInt16
SfxDispatcher::GetShellLevel( const SfxShell
& rShell
)
548 Determines the position of a given SfxShell in the stack of the dispatcher.
549 If possible this is flushed before.
553 sal_uInt16 == USRT_MAX
554 The SfxShell is not on this SfxDispatcher.
557 Position of the SfxShell on the Dispatcher
558 from the top count stating with 0.
562 SFX_STACK(SfxDispatcher::GetShellLevel
);
565 for ( sal_uInt16 n
= 0; n
< pImp
->aStack
.size(); ++n
)
566 if ( *( pImp
->aStack
.rbegin() + n
) == &rShell
)
570 sal_uInt16 nRet
= pImp
->pParent
->GetShellLevel(rShell
);
571 if ( nRet
== USHRT_MAX
)
573 return nRet
+ pImp
->aStack
.size();
579 //--------------------------------------------------------------------
580 SfxShell
*SfxDispatcher::GetShell(sal_uInt16 nIdx
) const
584 Returns a pointer to the <SfxShell> which is at the position nIdx
585 (from the top, last pushed is 0) on the stack.
587 Thus the SfxDispatcher is not flushed.
589 Is the stack not deep enough a NULL-Pointer is returned.
593 sal_uInt16 nShellCount
= pImp
->aStack
.size();
594 if ( nIdx
< nShellCount
)
595 return *(pImp
->aStack
.rbegin() + nIdx
);
596 else if ( pImp
->pParent
)
597 return pImp
->pParent
->GetShell( nIdx
- nShellCount
);
601 //--------------------------------------------------------------------
602 SfxBindings
* SfxDispatcher::GetBindings() const
606 This method returns a pointer to the <SfxBinding> Instance on which the
607 SfxDispatcher is curretly bound. A SfxDispatcher is only bound to
608 the SfxBindings when it is <UI-aktiv>. If it is not UI-active,
609 a NULL-pointer is returned.
611 The returned pointer is only valid in the immediate context of the method
617 return &pImp
->pFrame
->GetBindings();
622 //--------------------------------------------------------------------
623 SfxViewFrame
* SfxDispatcher::GetFrame() const
627 Returns a pointer to the <SfxViewFrame> instance, which belongs to
628 this SfxDispatcher. If it is about the application dispatcher,
629 a NULL-pointer is returned.
636 //--------------------------------------------------------------------
637 void SfxDispatcher::DoActivate_Impl( sal_Bool bMDI
, SfxViewFrame
* /* pOld */ )
641 This method controls the activation of a dispatcher.
643 Since the application dispatcher is always active, either as a sub
644 dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
645 activated as a whole, instead only its individual <SfxShell>s at
646 <SfxDispatcher::Push(SfxShell&)>.
648 When activating a SfxDispatcher all of the SfxShells located on its stack
649 are called with the handler <SfxShell::Activate(sal_Bool)>, starting with
654 SFX_STACK(SfxDispatcher::DoActivate
);
658 OStringBuffer
sTemp("Activate Dispatcher ");
659 sTemp
.append(reinterpret_cast<sal_Int64
>(this));
660 OSL_TRACE("%s", sTemp
.getStr());
661 DBG_ASSERT( !pImp
->bActive
, "Activation error" );
663 pImp
->bActive
= sal_True
;
664 pImp
->bUpdated
= sal_False
;
665 SfxBindings
* pBindings
= GetBindings();
668 pBindings
->SetDispatcher(this);
669 pBindings
->SetActiveFrame( pImp
->pFrame
->GetFrame().GetFrameInterface() );
675 OStringBuffer
sTemp("Non-MDI-Activate Dispatcher");
676 sTemp
.append(reinterpret_cast<sal_Int64
>(this));
677 OSL_TRACE("%s", sTemp
.getStr());
681 if ( IsAppDispatcher() )
684 for ( int i
= int(pImp
->aStack
.size()) - 1; i
>= 0; --i
)
685 (*(pImp
->aStack
.rbegin() + i
))->DoActivate_Impl(pImp
->pFrame
, bMDI
);
687 if ( bMDI
&& pImp
->pFrame
)
689 SfxBindings
*pBind
= GetBindings();
692 pBind
->HidePopupCtrls_Impl( sal_False
);
693 pBind
= pBind
->GetSubBindings_Impl();
696 pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( sal_False
, sal_False
, 1 );
699 if(!pImp
->aToDoStack
.empty())
701 // No immediate update is requested
702 pImp
->aTimer
.SetTimeout(SFX_FLUSH_TIMEOUT
);
703 pImp
->aTimer
.SetTimeoutHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
704 pImp
->aTimer
.Start();
708 void SfxDispatcher::DoParentActivate_Impl()
710 for ( int i
= int(pImp
->aStack
.size()) - 1; i
>= 0; --i
)
711 (*(pImp
->aStack
.rbegin() + i
))->ParentActivate();
714 //--------------------------------------------------------------------
715 void SfxDispatcher::DoDeactivate_Impl( sal_Bool bMDI
, SfxViewFrame
* pNew
)
719 This method controls the deactivation of a dispatcher.
721 Since the application dispatcher is always active, either as a sub
722 dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
723 deactivated as a whole, instead only its individual <SfxShell>s at
724 <SfxDispatcher::Pop(SfxShell&)>.
726 When deactivating a SfxDispatcher all of the SfxShells located on its stack
727 are called with the handler <SfxShell::Deactivate(sal_Bool)>, starting with
732 SFX_STACK(SfxDispatcher::DoDeactivate
);
734 SfxApplication
*pSfxApp
= SFX_APP();
738 OSL_TRACE(OStringBuffer("Deactivate Dispatcher").append(reinterpret_cast<sal_Int64
>(this)).getStr());
739 DBG_ASSERT( pImp
->bActive
, "Deactivate error" );
740 pImp
->bActive
= sal_False
;
742 if ( pImp
->pFrame
&& !(pImp
->pFrame
->GetObjectShell()->IsInPlaceActive() ) )
744 SfxWorkWindow
*pWorkWin
= pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
747 for (size_t n
=0; n
<pImp
->aChildWins
.size();)
749 SfxChildWindow
*pWin
= pWorkWin
->GetChildWindow_Impl( (sal_uInt16
) ( pImp
->aChildWins
[n
] & 0xFFFF ) );
750 if (!pWin
|| (pWin
&& pWin
->GetAlignment() == SFX_ALIGN_NOALIGNMENT
))
751 pImp
->aChildWins
.erase(pImp
->aChildWins
.begin()+n
);
759 OSL_TRACE(OStringBuffer("Non-MDI-DeActivate Dispatcher").append(reinterpret_cast<sal_Int64
>(this)).getStr());
762 if ( IsAppDispatcher() && !pSfxApp
->IsDowning() )
765 for ( sal_uInt16 i
= 0; i
< pImp
->aStack
.size(); ++i
)
766 (*(pImp
->aStack
.rbegin() + i
))->DoDeactivate_Impl(pImp
->pFrame
, bMDI
);
768 sal_Bool bHidePopups
= bMDI
&& pImp
->pFrame
;
769 if ( pNew
&& pImp
->pFrame
)
771 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xOldFrame(
772 pNew
->GetFrame().GetFrameInterface()->getCreator(), com::sun::star::uno::UNO_QUERY
);
774 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xMyFrame(
775 GetFrame()->GetFrame().GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
777 if ( xOldFrame
== xMyFrame
)
778 bHidePopups
= sal_False
;
783 SfxBindings
*pBind
= GetBindings();
786 pBind
->HidePopupCtrls_Impl( sal_True
);
787 pBind
= pBind
->GetSubBindings_Impl();
790 pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( sal_True
, sal_False
, 1 );
796 void SfxDispatcher::DoParentDeactivate_Impl()
798 for ( int i
= int(pImp
->aStack
.size()) - 1; i
>= 0; --i
)
799 (*(pImp
->aStack
.rbegin() + i
))->ParentDeactivate();
802 //--------------------------------------------------------------------
803 int SfxDispatcher::GetShellAndSlot_Impl
805 sal_uInt16 nSlot
, // the searchable Slot-Id
806 SfxShell
** ppShell
, // the SfxShell, which are currently handled
808 const SfxSlot
** ppSlot
, // the SfxSlot, which are currently handled
810 sal_Bool bOwnShellsOnly
,
811 sal_Bool bModal
, // ModalMode
817 This method searches in SfxDispatcher after <SfxShell> , from the Slot Id
818 nSlot currently being handled. For this, the dispatcher is first flushed.
823 The SfxShell was found, ppShell and ppSlot are valid.
826 The SfxShell was not found, ppShell and ppSlot are invalid.
830 SFX_STACK(SfxDispatcher::GetShellAndSlot_Impl
);
834 if ( _FindServer(nSlot
, aSvr
, bModal
) )
836 if ( bOwnShellsOnly
&& aSvr
.GetShellLevel() >= pImp
->aStack
.size() )
839 *ppShell
= GetShell(aSvr
.GetShellLevel());
840 *ppSlot
= aSvr
.GetSlot();
841 if ( 0 == (*ppSlot
)->GetExecFnc() && bRealSlot
)
842 *ppSlot
= (*ppShell
)->GetInterface()->GetRealSlot(*ppSlot
);
843 // Check only real slots as enum slots don't have an execute function!
844 if ( bRealSlot
&& ((0 == *ppSlot
) || (0 == (*ppSlot
)->GetExecFnc()) ))
853 //--------------------------------------------------------------------
854 void SfxDispatcher::_Execute
856 SfxShell
& rShell
, // to the calling <SfxShell>
857 const SfxSlot
& rSlot
, // to the calling <SfxSlot>
858 SfxRequest
& rReq
, // function to be performed
859 // (Id and optional parameters)
860 SfxCallMode eCallMode
// Synchronously, asynchronously or as shown in
866 This method performs a request for a cached <Slot-Server>.
870 DBG_ASSERT( !pImp
->bFlushing
, "recursive call to dispatcher" );
871 DBG_ASSERT( pImp
->aToDoStack
.empty(), "unprepared InPlace _Execute" );
873 if ( IsLocked( rSlot
.GetSlotId() ) )
876 if ( (eCallMode
& SFX_CALLMODE_ASYNCHRON
) ||
877 ( !(eCallMode
& SFX_CALLMODE_SYNCHRON
) &&
878 rSlot
.IsMode(SFX_SLOT_ASYNCHRON
) ) )
880 SfxDispatcher
*pDispat
= this;
883 sal_uInt16 nShellCount
= pDispat
->pImp
->aStack
.size();
884 for ( sal_uInt16 n
=0; n
<nShellCount
; n
++ )
886 if ( &rShell
== *(pDispat
->pImp
->aStack
.rbegin() + n
) )
888 if ( eCallMode
& SFX_CALLMODE_RECORD
)
889 rReq
.AllowRecording( sal_True
);
890 pDispat
->pImp
->xPoster
->Post(new SfxRequest(rReq
));
895 pDispat
= pDispat
->pImp
->pParent
;
899 Call_Impl( rShell
, rSlot
, rReq
, SFX_CALLMODE_RECORD
==(eCallMode
&SFX_CALLMODE_RECORD
) );
902 //--------------------------------------------------------------------
903 void MappedPut_Impl( SfxAllItemSet
&rSet
, const SfxPoolItem
&rItem
)
907 Helper function to put from rItem below the Which-ID in the pool of the
912 // Put with mapped Which-Id if possible
913 const SfxItemPool
*pPool
= rSet
.GetPool();
914 sal_uInt16 nWhich
= rItem
.Which();
915 if ( pPool
->IsSlot(nWhich
) )
916 nWhich
= pPool
->GetWhich(nWhich
);
917 rSet
.Put( rItem
, nWhich
);
920 //--------------------------------------------------------------------
922 const SfxSlot
* SfxDispatcher::GetSlot( const OUString
& rCommand
)
924 // Count the number of Shells on the linked Dispatcher
926 sal_uInt16 nTotCount
= pImp
->aStack
.size();
929 SfxDispatcher
*pParent
= pImp
->pParent
;
932 nTotCount
= nTotCount
+ pParent
->pImp
->aStack
.size();
933 pParent
= pParent
->pImp
->pParent
;
937 const SfxSlot
*pSlot
=NULL
;
938 sal_uInt16 nFirstShell
= 0;
939 for ( sal_uInt16 i
= nFirstShell
; i
< nTotCount
; ++i
)
941 SfxShell
*pObjShell
= GetShell(i
);
942 SfxInterface
*pIFace
= pObjShell
->GetInterface();
943 pSlot
= pIFace
->GetSlot( rCommand
);
951 //--------------------------------------------------------------------
952 const SfxPoolItem
* SfxDispatcher::Execute(
956 SfxItemSet
* pInternalArgs
,
959 if ( IsLocked(nSlot
) )
962 SfxShell
*pShell
= 0;
963 const SfxSlot
*pSlot
= 0;
964 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
965 SFX_CALLMODE_MODAL
==(nCall
&SFX_CALLMODE_MODAL
) ) )
967 SfxAllItemSet
aSet( pShell
->GetPool() );
970 SfxItemIter
aIter(*pArgs
);
971 for ( const SfxPoolItem
*pArg
= aIter
.FirstItem();
973 pArg
= aIter
.NextItem() )
974 MappedPut_Impl( aSet
, *pArg
);
976 SfxRequest
aReq( nSlot
, nCall
, aSet
);
978 aReq
.SetInternalArgs_Impl( *pInternalArgs
);
979 aReq
.SetModifier( nModi
);
981 _Execute( *pShell
, *pSlot
, aReq
, nCall
);
982 return aReq
.GetReturnValue();
987 //--------------------------------------------------------------------
988 const SfxPoolItem
* SfxDispatcher::Execute
990 sal_uInt16 nSlot
, // the Id of the executing function
991 SfxCallMode eCall
, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON
993 const SfxPoolItem
**pArgs
, // Zero teminated C-Array of Parameters
995 const SfxPoolItem
**pInternalArgs
// Zero terminated C-Array of Parameters
1000 Method to excecute a <SfxSlot>s over the Slot-Id.
1004 const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
1005 though the Message-Loop, which contains the return
1008 Or a NULL-Pointer, when the function was not
1009 executed (for example canceled by the user).
1013 if ( IsLocked(nSlot
) )
1016 SfxShell
*pShell
= 0;
1017 const SfxSlot
*pSlot
= 0;
1018 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
1019 SFX_CALLMODE_MODAL
==(eCall
&SFX_CALLMODE_MODAL
) ) )
1022 if ( pArgs
&& *pArgs
)
1024 SfxAllItemSet
aSet( pShell
->GetPool() );
1025 for ( const SfxPoolItem
**pArg
= pArgs
; *pArg
; ++pArg
)
1026 MappedPut_Impl( aSet
, **pArg
);
1027 pReq
= new SfxRequest( nSlot
, eCall
, aSet
);
1030 pReq
= new SfxRequest( nSlot
, eCall
, pShell
->GetPool() );
1031 pReq
->SetModifier( nModi
);
1032 if( pInternalArgs
&& *pInternalArgs
)
1034 SfxAllItemSet
aSet( SFX_APP()->GetPool() );
1035 for ( const SfxPoolItem
**pArg
= pInternalArgs
; *pArg
; ++pArg
)
1037 pReq
->SetInternalArgs_Impl( aSet
);
1039 _Execute( *pShell
, *pSlot
, *pReq
, eCall
);
1040 const SfxPoolItem
* pRet
= pReq
->GetReturnValue();
1041 delete pReq
; return pRet
;
1046 //--------------------------------------------------------------------
1047 const SfxPoolItem
* SfxDispatcher::Execute
1049 sal_uInt16 nSlot
, // the Id of the executing function
1050 SfxCallMode eCall
, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON or ..._SLOT
1051 const SfxItemSet
&rArgs
// <SfxItemSet> with the parameters
1056 Method to excecute a <SfxSlot>s over the Slot-Id.
1060 const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
1061 though the Message-Loop, which contains the return
1064 Or a NULL-Pointer, when the function was not
1065 executed (for example canceled by the user).
1069 return Execute( nSlot
, eCall
, 0, rArgs
);
1072 //--------------------------------------------------------------------
1073 const SfxPoolItem
* SfxDispatcher::Execute
1078 const SfxItemSet
&rArgs
1081 if ( IsLocked(nSlot
) )
1084 SfxShell
*pShell
= 0;
1085 const SfxSlot
*pSlot
= 0;
1086 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
1087 SFX_CALLMODE_MODAL
==(eCall
&SFX_CALLMODE_MODAL
) ) )
1089 SfxAllItemSet
aSet( pShell
->GetPool() );
1090 SfxItemIter
aIter(rArgs
);
1091 for ( const SfxPoolItem
*pArg
= aIter
.FirstItem();
1093 pArg
= aIter
.NextItem() )
1094 MappedPut_Impl( aSet
, *pArg
);
1095 SfxRequest
aReq( nSlot
, eCall
, aSet
);
1096 aReq
.SetModifier( nModi
);
1097 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1098 return aReq
.GetReturnValue();
1103 //--------------------------------------------------------------------
1104 const SfxPoolItem
* SfxDispatcher::Execute
1106 sal_uInt16 nSlot
, // the Id of the executing function
1107 SfxCallMode eCall
, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON or
1109 const SfxPoolItem
* pArg1
, // First parameter
1110 ... // Zero terminated list of parameters
1115 Method to excecute a <SfxSlot>s over the Slot-Id.
1119 The parameters are copied, can therefore be passed on as the address
1124 const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
1125 though the Message-Loop, which contains the return
1128 Or a NULL-Pointer, when the function was not
1129 executed (for example canceled by the user).
1133 pDispatcher->Execute( SID_OPENDOCUMENT, SFX_CALLMODE_SYNCHRON,
1134 &SfxStringItem( SID_FILE_NAME, "\\tmp\\temp.sdd" ),
1135 &SfxStringItem( SID_FILTER_NAME, "StarDraw Presentation" ),
1136 &SfxBoolItem( SID_DOC_READONLY, sal_False ),
1141 if ( IsLocked(nSlot
) )
1144 SfxShell
*pShell
= 0;
1145 const SfxSlot
*pSlot
= 0;
1146 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
1147 SFX_CALLMODE_MODAL
==(eCall
&SFX_CALLMODE_MODAL
) ) )
1149 SfxAllItemSet
aSet( pShell
->GetPool() );
1152 va_start( pVarArgs
, pArg1
);
1153 for ( const SfxPoolItem
*pArg
= pArg1
;
1155 pArg
= va_arg( pVarArgs
, const SfxPoolItem
* ) )
1156 MappedPut_Impl( aSet
, *pArg
);
1159 SfxRequest
aReq( nSlot
, eCall
, aSet
);
1160 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1161 return aReq
.GetReturnValue();
1166 //--------------------------------------------------------------------
1168 IMPL_LINK( SfxDispatcher
, PostMsgHandler
, SfxRequest
*, pReq
)
1172 Helper method to receive the asynchronously executed <SfxRequest>s.
1176 DBG_ASSERT( !pImp
->bFlushing
, "recursive call to dispatcher" );
1177 SFX_STACK(SfxDispatcher::PostMsgHandler
);
1179 // Has also the Pool not yet died?
1180 if ( !pReq
->IsCancelled() )
1182 if ( !IsLocked(pReq
->GetSlot()) )
1186 if ( _FindServer(pReq
->GetSlot(), aSvr
, sal_True
) ) // HACK(x), whatever that was supposed to mean
1188 const SfxSlot
*pSlot
= aSvr
.GetSlot();
1189 SfxShell
*pSh
= GetShell(aSvr
.GetShellLevel());
1191 DBG( SfxApplication
*pSfxApp
= SFX_APP() );
1192 DBG( pSfxApp
->EnterAsynchronCall_Impl() );
1194 // When the pSlot is a "Pseudoslot" for macros or Verbs, it can
1195 // be destroyed in the Call_Impl, thus do not use it anymore!
1196 pReq
->SetSynchronCall( sal_False
);
1197 Call_Impl( *pSh
, *pSlot
, *pReq
, pReq
->AllowsRecording() ); //! why bRecord?
1198 DBG( pSfxApp
->LeaveAsynchronCall_Impl() );
1203 if ( pImp
->bLocked
)
1204 pImp
->aReqArr
.push_back(new SfxRequest(*pReq
));
1206 pImp
->xPoster
->Post(new SfxRequest(*pReq
));
1213 //--------------------------------------------------------------------
1214 void SfxDispatcher::SetMenu_Impl()
1216 #if HAVE_FEATURE_DESKTOP
1219 SfxViewFrame
* pTop
= pImp
->pFrame
->GetTopViewFrame();
1220 if ( pTop
&& pTop
->GetBindings().GetDispatcher() == this )
1222 SfxFrame
& rFrame
= pTop
->GetFrame();
1223 if ( rFrame
.IsMenuBarOn_Impl() )
1225 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( rFrame
.GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
1226 if ( xPropSet
.is() )
1228 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1229 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1230 aValue
>>= xLayoutManager
;
1231 if ( xLayoutManager
.is() )
1233 OUString
aMenuBarURL( "private:resource/menubar/menubar" );
1234 if ( !xLayoutManager
->isElementVisible( aMenuBarURL
) )
1235 xLayoutManager
->createElement( aMenuBarURL
);
1244 //--------------------------------------------------------------------
1245 void SfxDispatcher::Update_Impl( sal_Bool bForce
)
1247 SFX_STACK(SfxDispatcher::Update_Impl
);
1251 if ( !pImp
->pFrame
)
1254 SFX_APP(); // -Wall is this required???
1255 SfxDispatcher
*pDisp
= this;
1256 sal_Bool bUpdate
= bForce
;
1257 while ( pDisp
&& pDisp
->pImp
->pFrame
)
1259 SfxWorkWindow
*pWork
= pDisp
->pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1260 SfxDispatcher
*pAct
= pWork
->GetBindings().GetDispatcher_Impl();
1261 if ( pAct
== pDisp
|| pAct
== this )
1264 bUpdate
= !pDisp
->pImp
->bUpdated
;
1265 pDisp
->pImp
->bUpdated
= sal_True
;
1270 pDisp
= pDisp
->pImp
->pParent
;
1273 if ( !bUpdate
|| pImp
->pFrame
->GetFrame().IsClosing_Impl() )
1276 SfxViewFrame
* pTop
= pImp
->pFrame
? pImp
->pFrame
->GetTopViewFrame() : NULL
;
1277 sal_Bool bUIActive
= pTop
&& pTop
->GetBindings().GetDispatcher() == this;
1279 if ( !bUIActive
&& pTop
&& GetBindings() == &pTop
->GetBindings() )
1280 // keep own tools internally for collecting
1281 GetBindings()->GetDispatcher()->pImp
->bUpdated
= sal_False
;
1283 SfxBindings
* pBindings
= GetBindings();
1285 pBindings
->DENTERREGISTRATIONS();
1287 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xFrame
= pBindings
->GetActiveFrame();
1288 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( xFrame
, com::sun::star::uno::UNO_QUERY
);
1289 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1290 if ( xPropSet
.is() )
1294 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1295 aValue
>>= xLayoutManager
;
1297 catch (const com::sun::star::uno::Exception
&)
1302 if ( xLayoutManager
.is() )
1303 xLayoutManager
->lock();
1305 sal_Bool bIsIPActive
= pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
1306 SfxInPlaceClient
*pClient
= pImp
->pFrame
? pImp
->pFrame
->GetViewShell()->GetUIActiveClient() : NULL
;
1307 if ( bUIActive
&& /* !bIsIPActive && */ ( !pClient
|| !pClient
->IsObjectUIActive() ) )
1310 SfxWorkWindow
*pWorkWin
= pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1311 SfxWorkWindow
*pTaskWin
= pImp
->pFrame
->GetTopFrame().GetWorkWindow_Impl();
1312 pTaskWin
->ResetStatusBar_Impl();
1314 SfxDispatcher
*pDispat
= this;
1317 SfxWorkWindow
*pWork
= pDispat
->pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1318 SfxDispatcher
*pAct
= pWork
->GetBindings().GetDispatcher_Impl();
1319 if ( pAct
== pDispat
|| pAct
== this )
1321 pWork
->ResetObjectBars_Impl();
1322 pWork
->ResetChildWindows_Impl();
1325 pDispat
= pDispat
->pImp
->pParent
;
1328 sal_Bool bIsActive
= sal_False
;
1329 SfxDispatcher
*pActDispat
= pWorkWin
->GetBindings().GetDispatcher_Impl();
1331 while ( pActDispat
&& !bIsActive
)
1333 if ( pDispat
== pActDispat
)
1334 bIsActive
= sal_True
;
1335 pActDispat
= pActDispat
->pImp
->pParent
;
1338 _Update_Impl( bUIActive
, !bIsIPActive
, bIsIPActive
, pTaskWin
);
1339 if ( bUIActive
|| bIsActive
)
1340 pWorkWin
->UpdateObjectBars_Impl();
1343 pBindings
->DLEAVEREGISTRATIONS();
1345 if ( xLayoutManager
.is() )
1346 xLayoutManager
->unlock();
1351 void SfxDispatcher::_Update_Impl( sal_Bool bUIActive
, sal_Bool bIsMDIApp
, sal_Bool bIsIPOwner
, SfxWorkWindow
*pTaskWin
)
1354 SfxWorkWindow
*pWorkWin
= pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1355 sal_Bool bIsActive
= sal_False
;
1356 sal_Bool bIsTaskActive
= sal_False
;
1357 SfxDispatcher
*pActDispat
= pWorkWin
->GetBindings().GetDispatcher_Impl();
1358 SfxDispatcher
*pDispat
= this;
1359 while ( pActDispat
&& !bIsActive
)
1361 if ( pDispat
== pActDispat
)
1362 bIsActive
= sal_True
;
1363 pActDispat
= pActDispat
->pImp
->pParent
;
1366 if ( pImp
->pParent
&& !pImp
->bQuiet
/* && bUIActive */ )
1367 pImp
->pParent
->_Update_Impl( bUIActive
, bIsMDIApp
, bIsIPOwner
, pTaskWin
);
1369 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
1370 pImp
->aObjBars
[n
].nResId
= 0;
1371 pImp
->aChildWins
.clear();
1373 // bQuiet : own shells aren't considered for UI and SlotServer
1374 // bNoUI: own Shells aren't considered fors UI
1375 if ( pImp
->bQuiet
|| pImp
->bNoUI
|| (pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsPreview()) )
1378 sal_uInt32 nStatBarId
=0;
1379 SfxShell
*pStatusBarShell
= NULL
;
1381 SfxSlotPool
* pSlotPool
= &SfxSlotPool::GetSlotPool( GetFrame() );
1382 sal_uInt16 nTotCount
= pImp
->aStack
.size();
1383 for ( sal_uInt16 nShell
= nTotCount
; nShell
> 0; --nShell
)
1385 SfxShell
*pShell
= GetShell( nShell
-1 );
1386 SfxInterface
*pIFace
= pShell
->GetInterface();
1388 // don't consider shells if "Hidden" oder "Quiet"
1389 sal_Bool bReadOnlyShell
= IsReadOnlyShell_Impl( nShell
-1 );
1391 for ( nNo
= 0; pIFace
&& nNo
<pIFace
->GetObjectBarCount(); ++nNo
)
1393 sal_uInt16 nPos
= pIFace
->GetObjectBarPos(nNo
);
1394 if ( bReadOnlyShell
&& !( nPos
& SFX_VISIBILITY_READONLYDOC
) )
1397 // check whether toolbar needs activation of a special feature
1398 sal_uInt32 nFeature
= pIFace
->GetObjectBarFeature(nNo
);
1399 if ( nFeature
&& !pShell
->HasUIFeature( nFeature
) )
1402 // check for toolboxes that are exclusively for a viewer
1405 sal_Bool bViewerTbx
= SFX_VISIBILITY_VIEWER
== ( nPos
& SFX_VISIBILITY_VIEWER
);
1406 SfxObjectShell
* pSh
= pImp
->pFrame
->GetObjectShell();
1407 SFX_ITEMSET_ARG( pSh
->GetMedium()->GetItemSet(), pItem
, SfxBoolItem
, SID_VIEWONLY
, sal_False
);
1408 sal_Bool bIsViewer
= pItem
&& pItem
->GetValue();
1409 if ( bIsViewer
!= bViewerTbx
)
1413 // always register toolbars, allows to switch them on
1414 sal_Bool bVisible
= pIFace
->IsObjectBarVisible(nNo
);
1416 nPos
&= SFX_POSITION_MASK
;
1418 SfxObjectBars_Impl
& rBar
= pImp
->aObjBars
[nPos
& SFX_POSITION_MASK
];
1420 rBar
.nResId
= pIFace
->GetObjectBarResId(nNo
).GetId();
1421 const OUString
*pName
= pIFace
->GetObjectBarName(nNo
);
1423 rBar
.aName
= *pName
;
1426 rBar
.pIFace
= pIFace
;
1428 if ( bUIActive
|| bIsActive
)
1430 pWorkWin
->SetObjectBar_Impl(
1431 nPos
, rBar
.nResId
, rBar
.pIFace
, &rBar
.aName
);
1438 for ( nNo
=0; pIFace
&& nNo
<pIFace
->GetChildWindowCount(); nNo
++ )
1440 sal_uInt32 nId
= pIFace
->GetChildWindowId(nNo
);
1441 const SfxSlot
*pSlot
= pSlotPool
->GetSlot( (sal_uInt16
) nId
);
1442 SAL_WARN_IF( !pSlot
, "sfx.control", "Childwindow slot missing: " << nId
);
1443 if ( bReadOnlyShell
)
1445 // only show ChildWindows if their slot is allowed for readonly documents
1446 if ( pSlot
&& !pSlot
->IsMode( SFX_SLOT_READONLYDOC
) )
1450 sal_uInt32 nFeature
= pIFace
->GetChildWindowFeature(nNo
);
1451 if ( nFeature
&& !pShell
->HasUIFeature( nFeature
) )
1454 // slot decides whether a ChildWindow is shown when document is OLE server or OLE client
1455 sal_uInt16 nMode
= SFX_VISIBILITY_STANDARD
;
1458 if ( pSlot
->IsMode(SFX_SLOT_CONTAINER
) )
1460 if ( pWorkWin
->IsVisible_Impl( SFX_VISIBILITY_CLIENT
) )
1461 nMode
|= SFX_VISIBILITY_CLIENT
;
1465 if ( pWorkWin
->IsVisible_Impl( SFX_VISIBILITY_SERVER
) )
1466 nMode
|= SFX_VISIBILITY_SERVER
;
1470 if ( bUIActive
|| bIsActive
)
1471 pWorkWin
->SetChildWindowVisible_Impl( nId
, sal_True
, nMode
);
1472 if ( bUIActive
|| bIsActive
|| !pWorkWin
->IsFloating( (sal_uInt16
) ( nId
& 0xFFFF ) ) )
1473 pImp
->aChildWins
.push_back( nId
);
1476 if ( bIsMDIApp
|| bIsIPOwner
)
1478 sal_uInt32 nId
= pIFace
->GetStatusBarResId().GetId();
1482 pStatusBarShell
= pShell
;
1487 for ( sal_uInt16 nPos
=0; nPos
<SFX_OBJECTBAR_MAX
; nPos
++ )
1489 SfxObjectBars_Impl
& rFixed
= pImp
->aFixedObjBars
[nPos
];
1490 if ( rFixed
.nResId
)
1492 SfxObjectBars_Impl
& rBar
= pImp
->aObjBars
[nPos
];
1494 pWorkWin
->SetObjectBar_Impl( rFixed
.nMode
,
1495 rFixed
.nResId
, rFixed
.pIFace
, &rFixed
.aName
);
1499 if ( pTaskWin
&& ( bIsMDIApp
|| bIsIPOwner
) )
1501 SfxDispatcher
*pActDispatcher
= pTaskWin
->GetBindings().GetDispatcher_Impl();
1502 SfxDispatcher
*pDispatcher
= this;
1503 while ( pActDispatcher
&& !bIsTaskActive
)
1505 if ( pDispatcher
== pActDispatcher
)
1506 bIsTaskActive
= sal_True
;
1507 pActDispatcher
= pActDispatcher
->pImp
->pParent
;
1510 if ( bIsTaskActive
&& nStatBarId
&& pImp
->pFrame
)
1512 // internal frames also may control statusbar
1513 SfxBindings
& rBindings
= pImp
->pFrame
->GetBindings();
1514 pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->SetStatusBar_Impl( nStatBarId
, pStatusBarShell
, rBindings
);
1519 //--------------------------------------------------------------------
1520 void SfxDispatcher::FlushImpl()
1524 Helper method to execute the outstanding push and pop commands.
1528 DBG_PROFSTART(SfxDispatcherFlush
);
1529 SFX_STACK(SfxDispatcher::FlushImpl
);
1531 OSL_TRACE("Flushing dispatcher!");
1533 pImp
->aTimer
.Stop();
1535 if ( pImp
->pParent
)
1536 pImp
->pParent
->Flush();
1538 pImp
->bFlushing
= !pImp
->bFlushing
;
1539 if ( !pImp
->bFlushing
)
1541 pImp
->bFlushing
= sal_True
;
1542 DBG_PROFSTOP(SfxDispatcherFlush
);
1546 SfxApplication
*pSfxApp
= SFX_APP();
1548 // Re-build the true stack in the first round
1549 std::deque
<SfxToDo_Impl
> aToDoCopy
;
1550 sal_Bool bModify
= sal_False
;
1551 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= pImp
->aToDoStack
.rbegin(); i
!= pImp
->aToDoStack
.rend(); ++i
)
1558 DBG_ASSERT( std::find(pImp
->aStack
.begin(), pImp
->aStack
.end(), i
->pCluster
) == pImp
->aStack
.end(),
1559 "pushed SfxShell already on stack" );
1560 pImp
->aStack
.push_back(i
->pCluster
);
1561 i
->pCluster
->SetDisableFlags(pImp
->nDisableFlags
);
1563 // Mark the moved shell
1564 aToDoCopy
.push_front(*i
);
1569 SfxShell
* pPopped
= 0;
1570 bool bFound
= false;
1573 DBG_ASSERT( !pImp
->aStack
.empty(), "popping from empty stack" );
1574 pPopped
= pImp
->aStack
.back();
1575 pImp
->aStack
.pop_back();
1576 pPopped
->SetDisableFlags( 0 );
1577 bFound
= (pPopped
== i
->pCluster
);
1579 // Mark the moved Shell
1580 aToDoCopy
.push_front(SfxToDo_Impl(sal_False
, i
->bDelete
, sal_False
, *pPopped
));
1582 while(i
->bUntil
&& !bFound
);
1583 DBG_ASSERT( bFound
, "wrong SfxShell popped" );
1586 pImp
->aToDoStack
.clear();
1588 // Invalidate bindings, if possible
1589 if ( !pSfxApp
->IsDowning() )
1593 pImp
->pCachedServ1
= 0;
1594 pImp
->pCachedServ2
= 0;
1597 InvalidateBindings_Impl( bModify
);
1600 pImp
->bFlushing
= sal_False
;
1601 pImp
->bUpdated
= sal_False
; // not only when bModify, if Doc/Template-Config
1602 bFlushed
= sal_True
;
1603 OSL_TRACE("Successfully flushed dispatcher!");
1605 //fdo#70703 FlushImpl may call back into itself so use aToDoCopyStack to talk
1606 //to outer levels of ourself. If DoActivate_Impl/DoDeactivate_Impl deletes
1607 //an entry, then they will walk back up aToDoCopyStack and set outer
1608 //levels's entries to bDeleted
1609 aToDoCopyStack
.push_back(aToDoCopy
);
1610 std::deque
<SfxToDo_Impl
>& rToDoCopy
= aToDoCopyStack
.back();
1611 // Activate the Shells and possible delete them in the 2nd round
1612 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= rToDoCopy
.rbegin(); i
!= rToDoCopy
.rend(); ++i
)
1619 i
->pCluster
->DoActivate_Impl(pImp
->pFrame
, sal_True
);
1621 i
->pCluster
->DoDeactivate_Impl(pImp
->pFrame
, sal_True
);
1624 aToDoCopy
= aToDoCopyStack
.back();
1625 aToDoCopyStack
.pop_back();
1627 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= aToDoCopy
.rbegin(); i
!= aToDoCopy
.rend(); ++i
)
1629 if (i
->bDelete
&& !i
->bDeleted
)
1631 if (!aToDoCopyStack
.empty())
1633 //fdo#70703 if there is an outer FlushImpl then inform it that
1634 //we have deleted this cluster
1635 for (std::deque
< std::deque
<SfxToDo_Impl
> >::iterator aI
= aToDoCopyStack
.begin();
1636 aI
!= aToDoCopyStack
.end(); ++aI
)
1638 std::deque
<SfxToDo_Impl
> &v
= *aI
;
1639 for(std::deque
<SfxToDo_Impl
>::iterator aJ
= v
.begin(); aJ
!= v
.end(); ++aJ
)
1641 if (aJ
->pCluster
== i
->pCluster
)
1642 aJ
->bDeleted
= true;
1649 sal_Bool bAwakeBindings
= !aToDoCopy
.empty();
1650 if( bAwakeBindings
)
1653 // If more changes have occurred on the stach when
1654 // Activate/Deactivate/Delete:
1656 // If Push/Pop hs been called by someone, theb also EnterReg was called!
1659 if( bAwakeBindings
&& GetBindings() )
1660 GetBindings()->DLEAVEREGISTRATIONS();
1661 DBG_PROFSTOP(SfxDispatcherFlush
);
1663 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
1664 pImp
->aFixedObjBars
[n
].nResId
= 0;
1666 SAL_INFO("sfx.control", "SfxDispatcher(" << this << ")::Flush() done");
1669 //--------------------------------------------------------------------
1670 void SfxDispatcher::SetSlotFilter
1672 // HACK(hier muss mal ein enum rein) ???
1673 sal_Bool bEnable
, /* sal_True:
1674 only enable specified slots,
1678 disable specified slots,
1679 first enable all other
1681 sal_uInt16 nCount
, // Number of SIDs in the following Array
1682 const sal_uInt16
* pSIDs
// sorted Array of 'nCount' SIDs
1687 With this method a filter set, the target slots can be enabled or disabled.
1688 The passed array must be retained until the destructor or the next
1689 <SetSlotFilter()>, it is not deleted from the dispatcher, so it can thus be
1692 In read-only documents the quasi ReadOnlyDoc Flag of slots can be
1693 overturned by the use of 'bEnable == 2', so this will be displayed again.
1694 On the other slots it has no effect.
1698 Targeted disabling of Slots 1, 2 and 3:
1700 static sal_uInt16 const pSIDs[] = { 1, 2, 3 };
1701 pDisp->SetSlotFilter( sal_False, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
1703 only permit Slots 5, 6 and 7:
1705 static sal_uInt16 const pSIDs[] = { 5, 6, 7 };
1706 pDisp->SetSlotFilter( sal_True, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
1710 pDisp->SetSlotFilter();
1716 for ( sal_uInt16 n
= 1; n
< nCount
; ++n
)
1717 DBG_ASSERT( pSIDs
[n
] > pSIDs
[n
-1], "SetSlotFilter: SIDs not sorted" );
1720 if ( pImp
->pFilterSIDs
)
1721 pImp
->pFilterSIDs
= 0;
1723 pImp
->bFilterEnabling
= bEnable
;
1724 pImp
->nFilterCount
= nCount
;
1725 pImp
->pFilterSIDs
= pSIDs
;
1727 GetBindings()->InvalidateAll(sal_True
);
1730 //--------------------------------------------------------------------
1738 SfxCompareSIDs_Impl( const void* pSmaller
, const void* pBigger
)
1740 return ( (long) *((sal_uInt16
*)pSmaller
) ) - ( (long) *((sal_uInt16
*)pBigger
) );
1743 //--------------------------------------------------------------------
1744 sal_Bool
SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID
) const
1748 Searches for 'nSID' in the Filter set by <SetSlotFilter()> and
1749 returns sal_True, if the SIDis allowed, or sal_False, if it is
1750 disabled by the Filter.
1753 sal_Bool 0 => disabled
1755 2 => enabled even if ReadOnlyDoc
1760 if ( 0 == pImp
->nFilterCount
)
1761 // => all SIDs allowed
1765 sal_Bool bFound
= 0 != bsearch( &nSID
, pImp
->pFilterSIDs
, pImp
->nFilterCount
,
1766 sizeof(sal_uInt16
), SfxCompareSIDs_Impl
);
1768 // even if ReadOnlyDoc
1769 if ( 2 == pImp
->bFilterEnabling
)
1770 return bFound
? 2 : 1;
1771 // Otherwise after Negative/Positive Filter
1772 return pImp
->bFilterEnabling
? bFound
: !bFound
;
1775 //--------------------------------------------------------------------
1776 sal_Bool
SfxDispatcher::_TryIntercept_Impl
1778 sal_uInt16 nSlot
, // Slot-Id to search for
1779 SfxSlotServer
& rServer
, // <SfxSlotServer>-Instance to fill
1783 // Maybe the parent is also belongs to a component
1784 SfxDispatcher
*pParent
= pImp
->pParent
;
1785 sal_uInt16 nLevels
= pImp
->aStack
.size();
1786 while ( pParent
&& pParent
->pImp
->pFrame
)
1788 if ( pParent
->pImp
->pFrame
->GetFrame().HasComponent() )
1790 // Components may be intercepted
1791 if ( pParent
->_TryIntercept_Impl( nSlot
, rServer
, sal_True
) )
1793 // The own shells are added to the Shell Level
1794 rServer
.SetShellLevel( rServer
.GetShellLevel() + nLevels
);
1798 // No further Interception
1802 nLevels
= nLevels
+ pParent
->pImp
->aStack
.size();
1804 pParent
= pParent
->pImp
->pParent
;
1809 // Query the ComponentViewShell
1811 SfxShell
*pObjShell
= GetShell(0);
1812 SfxInterface
*pIFace
= pObjShell
->GetInterface();
1813 const SfxSlot
*pSlot
= pIFace
->GetSlot(nSlot
);
1817 rServer
.SetSlot(pSlot
);
1818 rServer
.SetShellLevel(0);
1826 sal_Bool
SfxDispatcher::_FindServer
1828 sal_uInt16 nSlot
, // Slot-Id to search for
1829 SfxSlotServer
& rServer
, // <SfxSlotServer>-Instance to fill
1830 sal_Bool bModal
// Dispite ModalMode
1835 This helper method searches for the <Slot-Server> which currently serves
1836 the nSlot. As the result, rServe is filled accordingly.
1838 If known the SfxInterface which is currently served by nSlot can be
1841 The SfxDispatcher is flushed while searching for nSlot.
1847 The Slot was found, rServer is valid.
1850 The Slot is currently not served, rServer is invalid.
1854 SFX_STACK(SfxDispatcher::_FindServer
);
1856 // Dispatcher locked? (nevertheless let SID_HELP_PI through)
1857 if ( IsLocked(nSlot
) )
1859 pImp
->bInvalidateOnUnlock
= sal_True
;
1863 // Count the number of Shells in the linked dispatchers.
1865 sal_uInt16 nTotCount
= pImp
->aStack
.size();
1866 if ( pImp
->pParent
)
1868 SfxDispatcher
*pParent
= pImp
->pParent
;
1871 nTotCount
= nTotCount
+ pParent
->pImp
->aStack
.size();
1872 pParent
= pParent
->pImp
->pParent
;
1877 if (nSlot
>= SID_VERB_START
&& nSlot
<= SID_VERB_END
)
1879 for ( sal_uInt16 nShell
= 0;; ++nShell
)
1881 SfxShell
*pSh
= GetShell(nShell
);
1884 if ( pSh
->ISA(SfxViewShell
) )
1886 const SfxSlot
* pSlot
= pSh
->GetVerbSlot_Impl(nSlot
);
1889 rServer
.SetShellLevel(nShell
);
1890 rServer
.SetSlot( pSlot
);
1897 // SID check against set filter
1898 sal_uInt16 nSlotEnableMode
=0;
1901 nSlotEnableMode
= IsSlotEnabledByFilter_Impl( nSlot
);
1902 if ( 0 == nSlotEnableMode
)
1906 // In Quiet-Mode only Parent-Dispatcher
1909 if ( pImp
->pParent
)
1911 sal_Bool bRet
= pImp
->pParent
->_FindServer( nSlot
, rServer
, bModal
);
1912 rServer
.SetShellLevel
1913 ( rServer
.GetShellLevel() + pImp
->aStack
.size() );
1920 sal_Bool bReadOnly
= ( 2 != nSlotEnableMode
&& pImp
->bReadOnly
);
1922 // search through all the shells of the chained dispatchers
1923 // from top to bottom
1924 sal_uInt16 nFirstShell
= pImp
->bModal
&& !bModal
? pImp
->aStack
.size() : 0;
1925 for ( sal_uInt16 i
= nFirstShell
; i
< nTotCount
; ++i
)
1927 SfxShell
*pObjShell
= GetShell(i
);
1928 SfxInterface
*pIFace
= pObjShell
->GetInterface();
1929 const SfxSlot
*pSlot
= pIFace
->GetSlot(nSlot
);
1931 if ( pSlot
&& pSlot
->nDisableFlags
&& ( pSlot
->nDisableFlags
& pObjShell
->GetDisableFlags() ) != 0 )
1934 if ( pSlot
&& !( pSlot
->nFlags
& SFX_SLOT_READONLYDOC
) && bReadOnly
)
1939 // Slot belongs to Container?
1940 bool bIsContainerSlot
= pSlot
->IsMode(SFX_SLOT_CONTAINER
);
1941 bool bIsInPlace
= pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
1943 // Shell belongs to Server?
1944 // AppDispatcher or IPFrame-Dispatcher
1945 bool bIsServerShell
= !pImp
->pFrame
|| bIsInPlace
;
1947 // Of course ShellServer-Slots are also executable even when it is
1948 // excecuted on a container dispatcher without a IPClient.
1949 if ( !bIsServerShell
)
1951 SfxViewShell
*pViewSh
= pImp
->pFrame
->GetViewShell();
1952 bIsServerShell
= !pViewSh
|| !pViewSh
->GetUIActiveClient();
1955 // Shell belongs to Container?
1956 // AppDispatcher or no IPFrameDispatcher
1957 bool bIsContainerShell
= !pImp
->pFrame
|| !bIsInPlace
;
1958 // Shell and Slot match
1959 if ( !( ( bIsContainerSlot
&& bIsContainerShell
) ||
1960 ( !bIsContainerSlot
&& bIsServerShell
) ) )
1966 rServer
.SetSlot(pSlot
);
1967 rServer
.SetShellLevel(i
);
1975 //--------------------------------------------------------------------
1976 sal_Bool
SfxDispatcher::_FillState
1978 const SfxSlotServer
& rSvr
, // <Slot-Server> to query
1979 SfxItemSet
& rState
, // <SfxItemSet> to be filled
1980 const SfxSlot
* pRealSlot
// The actual Slot if possible
1985 Helper method to obtain the status of the <Slot-Server>s rSvr.
1986 The required slots IDs (partly converted to Which-IDs of the pool)
1987 must be present in rstate.
1989 The SfxDispatcher is flushed before the query.
1993 SFX_STACK(SfxDispatcher::_FillState
);
1995 DBG_PROFSTART(SfxDispatcherFillState
);
1997 const SfxSlot
*pSlot
= rSvr
.GetSlot();
1998 if ( pSlot
&& IsLocked( pSlot
->GetSlotId() ) )
2000 pImp
->bInvalidateOnUnlock
= sal_True
;
2001 DBG_PROFSTOP(SfxDispatcherFillState
);
2007 DBG_ASSERT(bFlushed
, "Dispatcher not flushed after retrieving slot servers!");
2011 // Determine the object and call the Message of this object
2012 SfxShell
*pSh
= GetShell(rSvr
.GetShellLevel());
2013 DBG_ASSERT(pSh
, "ObjectShell not found");
2018 pFunc
= pRealSlot
->GetStateFnc();
2020 pFunc
= pSlot
->GetStateFnc();
2022 pSh
->CallState( pFunc
, rState
);
2024 // To examine the conformity of IDL (SlotMap) and current Items
2025 if ( DbgIsAssertWarning() && rState
.Count() )
2027 SfxInterface
*pIF
= pSh
->GetInterface();
2028 SfxItemIter
aIter( rState
);
2029 for ( const SfxPoolItem
*pItem
= aIter
.FirstItem();
2031 pItem
= aIter
.NextItem() )
2033 if ( !IsInvalidItem(pItem
) && !pItem
->ISA(SfxVoidItem
) )
2035 sal_uInt16 nSlotId
= rState
.GetPool()->GetSlotId(pItem
->Which());
2036 if ( !pItem
->IsA(pIF
->GetSlot(nSlotId
)->GetType()->Type()) )
2038 OStringBuffer
aMsg("item-type unequal to IDL (=> no BASIC)");
2039 aMsg
.append("\nwith SID: ");
2040 aMsg
.append(static_cast<sal_Int32
>(nSlotId
));
2041 aMsg
.append("\nin ");
2042 aMsg
.append(pIF
->GetClassName());
2043 DbgOut(aMsg
.getStr(), DBG_OUT_ERROR
, __FILE__
, __LINE__
);
2050 DBG_PROFSTOP(SfxDispatcherFillState
);
2054 DBG_PROFSTOP(SfxDispatcherFillState
);
2058 SfxPopupMenuManager
* SfxDispatcher::Popup( sal_uInt16 nConfigId
,Window
*pWin
, const Point
*pPos
)
2060 SfxDispatcher
&rDisp
= *SFX_APP()->GetDispatcher_Impl();
2061 sal_uInt16 nShLevel
= 0;
2064 if ( rDisp
.pImp
->bQuiet
)
2067 nShLevel
= rDisp
.pImp
->aStack
.size();
2070 Window
*pWindow
= pWin
? pWin
: rDisp
.pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
2071 for ( pSh
= rDisp
.GetShell(nShLevel
); pSh
; ++nShLevel
, pSh
= rDisp
.GetShell(nShLevel
) )
2073 const ResId
& rResId
= pSh
->GetInterface()->GetPopupMenuResId();
2074 if ( ( nConfigId
== 0 && rResId
.GetId() ) || ( nConfigId
!= 0 && rResId
.GetId() == nConfigId
) )
2076 return SfxPopupMenuManager::Popup( rResId
, rDisp
.GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2083 //----------------------------------------------------------------------
2084 void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId
, Window
*pWin
, const Point
*pPos
)
2086 SfxDispatcher
&rDisp
= *SFX_APP()->GetDispatcher_Impl();
2087 sal_uInt16 nShLevel
= 0;
2090 if ( rDisp
.pImp
->bQuiet
)
2093 nShLevel
= rDisp
.pImp
->aStack
.size();
2096 Window
*pWindow
= pWin
? pWin
: rDisp
.pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
2097 for ( pSh
= rDisp
.GetShell(nShLevel
); pSh
; ++nShLevel
, pSh
= rDisp
.GetShell(nShLevel
) )
2099 const ResId
& rResId
= pSh
->GetInterface()->GetPopupMenuResId();
2100 if ( ( nConfigId
== 0 && rResId
.GetId() ) || ( nConfigId
!= 0 && rResId
.GetId() == nConfigId
) )
2102 SfxPopupMenuManager::ExecutePopup( rResId
, rDisp
.GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2108 //----------------------------------------------------------------------
2109 void SfxDispatcher::ExecutePopup( const ResId
&rId
, Window
*pWin
, const Point
*pPos
)
2111 Window
*pWindow
= pWin
? pWin
: pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
2112 SfxPopupMenuManager::ExecutePopup( rId
, GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2115 //--------------------------------------------------------------------
2116 void SfxDispatcher::Lock( sal_Bool bLock
)
2120 With this method the SfxDispatcher can be locked and released. A locked
2121 SfxDispatcher does not perform <SfxRequest>s and does no longer provide
2122 status information. It behaves as if all the slots were disabled.
2126 SfxBindings
* pBindings
= GetBindings();
2127 if ( !bLock
&& pImp
->bLocked
&& pImp
->bInvalidateOnUnlock
)
2130 pBindings
->InvalidateAll(sal_True
);
2131 pImp
->bInvalidateOnUnlock
= sal_False
;
2133 else if ( pBindings
)
2134 pBindings
->InvalidateAll(sal_False
);
2135 pImp
->bLocked
= bLock
;
2138 for(size_t i
= 0; i
< pImp
->aReqArr
.size(); ++i
)
2139 pImp
->xPoster
->Post(pImp
->aReqArr
[i
]);
2140 pImp
->aReqArr
.clear();
2144 sal_uInt32
SfxDispatcher::GetObjectBarId( sal_uInt16 nPos
) const
2146 return pImp
->aObjBars
[nPos
].nResId
;
2149 //-------------------------------------------------------------------------
2150 void SfxDispatcher::HideUI( sal_Bool bHide
)
2152 sal_Bool bWasHidden
= pImp
->bNoUI
;
2153 pImp
->bNoUI
= bHide
;
2156 SfxViewFrame
* pTop
= pImp
->pFrame
->GetTopViewFrame();
2157 if ( pTop
&& pTop
->GetBindings().GetDispatcher() == this )
2159 SfxFrame
& rFrame
= pTop
->GetFrame();
2160 if ( rFrame
.IsMenuBarOn_Impl() )
2162 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( rFrame
.GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
2163 if ( xPropSet
.is() )
2165 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
2166 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
2167 aValue
>>= xLayoutManager
;
2168 if ( xLayoutManager
.is() )
2169 xLayoutManager
->setVisible( !bHide
);
2175 if ( bHide
!= bWasHidden
)
2176 Update_Impl( sal_True
);
2179 void SfxDispatcher::SetReadOnly_Impl( sal_Bool bOn
)
2181 pImp
->bReadOnly
= bOn
;
2184 sal_Bool
SfxDispatcher::GetReadOnly_Impl() const
2186 return pImp
->bReadOnly
;
2189 //-------------------------------------------------------------------------
2190 void SfxDispatcher::SetQuietMode_Impl( sal_Bool bOn
)
2194 With 'bOn' the Dispatcher is quasi dead and transfers everything to the
2200 SfxBindings
* pBindings
= GetBindings();
2202 pBindings
->InvalidateAll(sal_True
);
2205 SfxItemState
SfxDispatcher::QueryState( sal_uInt16 nSlot
, const SfxPoolItem
* &rpState
)
2207 SfxShell
*pShell
= 0;
2208 const SfxSlot
*pSlot
= 0;
2209 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
, sal_False
) )
2211 rpState
= pShell
->GetSlotState(nSlot
);
2213 return SFX_ITEM_DISABLED
;
2215 return SFX_ITEM_AVAILABLE
;
2218 return SFX_ITEM_DISABLED
;
2221 SfxItemState
SfxDispatcher::QueryState( sal_uInt16 nSID
, ::com::sun::star::uno::Any
& rAny
)
2223 SfxShell
*pShell
= 0;
2224 const SfxSlot
*pSlot
= 0;
2225 if ( GetShellAndSlot_Impl( nSID
, &pShell
, &pSlot
, sal_False
, sal_False
) )
2227 const SfxPoolItem
* pItem( 0 );
2229 pItem
= pShell
->GetSlotState( nSID
);
2231 return SFX_ITEM_DISABLED
;
2234 ::com::sun::star::uno::Any aState
;
2235 if ( !pItem
->ISA(SfxVoidItem
) )
2237 sal_uInt16
nSubId( 0 );
2238 SfxItemPool
& rPool
= pShell
->GetPool();
2239 sal_uInt16 nWhich
= rPool
.GetWhich( nSID
);
2240 if ( rPool
.GetMetric( nWhich
) == SFX_MAPUNIT_TWIP
)
2241 nSubId
|= CONVERT_TWIPS
;
2242 pItem
->QueryValue( aState
, (sal_uInt8
)nSubId
);
2246 return SFX_ITEM_AVAILABLE
;
2250 return SFX_ITEM_DISABLED
;
2253 sal_Bool
SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell
) const
2255 sal_uInt16 nShellCount
= pImp
->aStack
.size();
2256 if ( nShell
< nShellCount
)
2258 SfxShell
* pShell
= *( pImp
->aStack
.rbegin() + nShell
);
2259 if( pShell
->ISA( SfxModule
) || pShell
->ISA( SfxApplication
) || pShell
->ISA( SfxViewFrame
) )
2262 return pImp
->bReadOnly
;
2264 else if ( pImp
->pParent
)
2265 return pImp
->pParent
->IsReadOnlyShell_Impl( nShell
- nShellCount
);
2269 void SfxDispatcher::RemoveShell_Impl( SfxShell
& rShell
)
2273 sal_uInt16 nCount
= pImp
->aStack
.size();
2274 for ( sal_uInt16 n
=0; n
<nCount
; ++n
)
2276 if ( pImp
->aStack
[n
] == &rShell
)
2278 pImp
->aStack
.erase( pImp
->aStack
.begin() + n
);
2279 rShell
.SetDisableFlags( 0 );
2280 rShell
.DoDeactivate_Impl(pImp
->pFrame
, sal_True
);
2285 if ( !SFX_APP()->IsDowning() )
2287 pImp
->bUpdated
= sal_False
;
2288 pImp
->pCachedServ1
= 0;
2289 pImp
->pCachedServ2
= 0;
2290 InvalidateBindings_Impl(sal_True
);
2294 void SfxDispatcher::InvalidateBindings_Impl( sal_Bool bModify
)
2297 if ( IsAppDispatcher() )
2299 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst();
2301 pFrame
= SfxViewFrame::GetNext( *pFrame
) )
2302 pFrame
->GetBindings().InvalidateAll(bModify
);
2306 SfxDispatcher
*pDisp
= GetBindings()->GetDispatcher_Impl();
2309 if ( pDisp
== this )
2311 GetBindings()->InvalidateAll( bModify
);
2315 pDisp
= pDisp
->pImp
->pParent
;
2320 sal_Bool
SfxDispatcher::IsUpdated_Impl() const
2322 return pImp
->bUpdated
;
2325 void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags
)
2327 pImp
->nDisableFlags
= nFlags
;
2328 for ( SfxShellStack_Impl::const_reverse_iterator it
= pImp
->aStack
.rbegin(); it
!= pImp
->aStack
.rend(); ++it
)
2329 (*it
)->SetDisableFlags( nFlags
);
2332 sal_uInt32
SfxDispatcher::GetDisableFlags() const
2334 return pImp
->nDisableFlags
;
2337 SfxModule
* SfxDispatcher::GetModule() const
2339 for ( sal_uInt16 nShell
= 0;; ++nShell
)
2341 SfxShell
*pSh
= GetShell(nShell
);
2344 if ( pSh
->ISA(SfxModule
) )
2345 return (SfxModule
*) pSh
;
2349 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */