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 <com/sun/star/beans/XPropertySet.hpp>
21 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
22 #include <com/sun/star/frame/XLayoutManager.hpp>
23 #include <svl/itempool.hxx>
24 #include <svl/itemiter.hxx>
25 #include <svl/whiter.hxx>
26 #include <svl/intitem.hxx>
27 #include <svl/eitem.hxx>
28 #include <svl/undo.hxx>
29 #include <vcl/wrkwin.hxx>
32 #include <stdlib.h> // due to bsearch
35 #include <svtools/helpopt.hxx>
38 #include "appdata.hxx"
39 #include "sfx2/sfxhelp.hxx"
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/msg.hxx>
42 #include <sfx2/objface.hxx>
43 #include <sfx2/bindings.hxx>
44 #include <sfx2/request.hxx>
45 #include <sfx2/app.hxx>
46 #include <sfx2/hintpost.hxx>
47 #include "slotserv.hxx"
48 #include <sfx2/ipclient.hxx>
49 #include "sfxtypes.hxx"
50 #include <sfx2/viewfrm.hxx>
51 #include <sfx2/viewsh.hxx>
52 #include <sfx2/childwin.hxx>
53 #include <sfx2/docfac.hxx>
54 #include <sfx2/msgpool.hxx>
55 #include <sfx2/module.hxx>
56 #include <sfx2/sfxuno.hxx>
57 #include <sfx2/docfile.hxx>
58 #include <sfx2/mnumgr.hxx>
59 #include "workwin.hxx"
60 #include <rtl/strbuf.hxx>
65 DBG_NAME(SfxDispatcherFlush
)
66 DBG_NAME(SfxDispatcherFillState
)
68 typedef std::vector
<SfxRequest
*> SfxRequestPtrArray
;
70 struct SfxObjectBars_Impl
72 sal_uInt32 nResId
; // Resource - and ConfigId of the Toolbox
73 sal_uInt16 nMode
; // special visibility flags
77 SfxObjectBars_Impl() : nResId(0), nMode(0), pIFace(NULL
) {}
80 //------------------------------------------------------------------
82 struct SfxDispatcher_Impl
84 //When the dispatched is locked, SfxRequests accumulate in aReqArr for
85 //later dispatch when unlocked via Post
87 //The pointers are typically deleted in Post, only if we never get around
88 //to posting them do we delete the unposted requests.
89 SfxRequestPtrArray aReqArr
;
92 for (SfxRequestPtrArray::iterator aI
= aReqArr
.begin(), aEnd
= aReqArr
.end(); aI
!= aEnd
; ++aI
)
95 const SfxSlotServer
* pCachedServ1
; // last called message
96 const SfxSlotServer
* pCachedServ2
; // penultimate called Message
97 SfxShellStack_Impl aStack
; // active functionality
98 Timer aTimer
; // for Flush
99 std::deque
<SfxToDo_Impl
> aToDoStack
; // not processed Push/Pop
100 SfxViewFrame
* pFrame
; // NULL or associated Frame
101 SfxDispatcher
* pParent
; // AppDispatcher, NULL if possible
102 SfxHintPosterRef xPoster
; // Execute asynchronous
103 sal_Bool bFlushing
; // sal_True during Flush //?
104 sal_Bool bUpdated
; // Update_Impl has run
105 sal_Bool bLocked
; // No Execute
106 sal_Bool bInvalidateOnUnlock
; // because someone asked
107 sal_Bool bActive
; // not to be confused with set!
108 sal_Bool
* pInCallAliveFlag
; // view the Destructor Stack
109 SfxObjectBars_Impl aObjBars
[SFX_OBJECTBAR_MAX
];
110 SfxObjectBars_Impl aFixedObjBars
[SFX_OBJECTBAR_MAX
];
111 std::vector
<sal_uInt32
> aChildWins
;
112 sal_uInt32 nEventId
; // EventId UserEvent
113 sal_Bool bNoUI
; // UI only from Parent Dispatcher
114 sal_Bool bReadOnly
; // Document is ReadOnly
115 sal_Bool bQuiet
; // Only use parent dispatcher
116 sal_Bool bModal
; // Only slots from parent dispatcher
118 sal_Bool bFilterEnabling
; // sal_True=filter enabled slots,
119 // 2==ReadOnlyDoc overturned
120 sal_uInt16 nFilterCount
; // Number of SIDs in pFilterSIDs
121 const sal_uInt16
* pFilterSIDs
; // sorted Array of SIDs
122 sal_uInt32 nDisableFlags
;
125 //------------------------------------------------------------------
127 #define SFX_FLUSH_TIMEOUT 50
129 //====================================================================
130 sal_Bool
SfxDispatcher::IsLocked( sal_uInt16
) const
134 With this method it can be determined whether the SfxDispatcher is
135 locked or unlocked. A locked SfxDispatcher does not perform <SfxRequest>s
136 and no longer provides any status information. It behaves as if all the
139 The dispatcher is also marked as blocked, if all Dispatcher are locked
140 (<SfxApplication::LockDispatcher()>) or the associated top frame is in the
141 modal-mode and if the specified slot are handled as frame-specific
142 (ie, not served by the application).
146 return pImp
->bLocked
;
149 //--------------------------------------------------------------------
150 sal_Bool
SfxDispatcher::IsAppDispatcher() const
154 With this method it can be determined if the SfxDispacher is the
155 applications dispatcher.
159 sal_Bool sal_True it is the application dispatcher.
160 sal_Fals it is a SfxViewFrame dispatcher.
164 return !pImp
->pFrame
;
167 //--------------------------------------------------------------------
168 int SfxDispatcher::Call_Impl( SfxShell
& rShell
, const SfxSlot
&rSlot
, SfxRequest
&rReq
, sal_Bool bRecord
)
172 Helper function to check whether a slot can be executed and
173 check the execution itself
177 SFX_STACK(SfxDispatcher::Call_Impl
);
179 // The slot may be called (meaning enabled)
180 if ( rSlot
.IsMode(SFX_SLOT_FASTCALL
) || rShell
.CanExecuteSlot_Impl(rSlot
) )
184 // Recording may start
185 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xFrame(
186 GetFrame()->GetFrame().GetFrameInterface(),
187 com::sun::star::uno::UNO_QUERY
);
189 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xSet(
191 com::sun::star::uno::UNO_QUERY
);
195 com::sun::star::uno::Any aProp
= xSet
->getPropertyValue(OUString("DispatchRecorderSupplier"));
196 com::sun::star::uno::Reference
< com::sun::star::frame::XDispatchRecorderSupplier
> xSupplier
;
197 com::sun::star::uno::Reference
< com::sun::star::frame::XDispatchRecorder
> xRecorder
;
200 xRecorder
= xSupplier
->getDispatchRecorder();
202 if ( bRecord
&& xRecorder
.is() && !rSlot
.IsMode(SFX_SLOT_NORECORD
) )
203 rReq
.Record_Impl( rShell
, rSlot
, xRecorder
, GetFrame() );
206 // Get all that is needed, because the slot may not have survived the
207 // Execute if it is a 'pseudo slot' for macros or verbs.
208 sal_Bool bAutoUpdate
= rSlot
.IsMode(SFX_SLOT_AUTOUPDATE
);
210 // API-call parentheses and document-lock during the calls
212 // 'this' must respond in the Destructor
213 sal_Bool bThisDispatcherAlive
= sal_True
;
214 sal_Bool
*pOldInCallAliveFlag
= pImp
->pInCallAliveFlag
;
215 pImp
->pInCallAliveFlag
= &bThisDispatcherAlive
;
217 SfxExecFunc pFunc
= rSlot
.GetExecFnc();
218 rShell
.CallExec( pFunc
, rReq
);
220 // If 'this' is still alive
221 if ( bThisDispatcherAlive
)
222 pImp
->pInCallAliveFlag
= pOldInCallAliveFlag
;
225 if ( pOldInCallAliveFlag
)
227 // also protect nested stack frames
228 *pOldInCallAliveFlag
= sal_False
;
231 // do nothing after this object is dead
232 return rReq
.IsDone();
238 SfxBindings
*pBindings
= GetBindings();
240 // When AutoUpdate update immediately; "Pseudoslots" must not be
242 if ( bAutoUpdate
&& pBindings
)
244 const SfxSlot
* pSlave
= rSlot
.GetLinkedSlot();
247 // When enum slots take any bound slave slot
248 while (!pBindings
->IsBound(pSlave
->GetSlotId()) && pSlave
!= &rSlot
)
249 pSlave
= pSlave
->GetLinkedSlot();
250 pBindings
->Invalidate(pSlave
->GetSlotId());
251 pBindings
->Update(pSlave
->GetSlotId());
255 pBindings
->Invalidate(rSlot
.GetSlotId());
256 pBindings
->Update(rSlot
.GetSlotId());
267 //====================================================================
268 void SfxDispatcher::Construct_Impl( SfxDispatcher
* pParent
)
270 pImp
= new SfxDispatcher_Impl
;
273 pImp
->pCachedServ1
= 0;
274 pImp
->pCachedServ2
= 0;
275 pImp
->bFlushing
= sal_False
;
276 pImp
->bUpdated
= sal_False
;
277 pImp
->bLocked
= sal_False
;
278 pImp
->bActive
= sal_False
;
279 pImp
->pParent
= NULL
;
280 pImp
->bNoUI
= sal_False
;
281 pImp
->bReadOnly
= sal_False
;
282 pImp
->bQuiet
= sal_False
;
283 pImp
->bModal
= sal_False
;
284 pImp
->pInCallAliveFlag
= 0;
285 pImp
->bFilterEnabling
= sal_False
;
286 pImp
->nFilterCount
= 0;
287 pImp
->pFilterSIDs
= 0;
288 pImp
->nDisableFlags
= 0;
290 pImp
->pParent
= pParent
;
292 pImp
->bInvalidateOnUnlock
= sal_False
;
294 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
295 pImp
->aObjBars
[n
].nResId
= 0;
297 GenLink
aGenLink( LINK(this, SfxDispatcher
, PostMsgHandler
) );
299 pImp
->xPoster
= new SfxHintPoster(aGenLink
);
301 pImp
->aTimer
.SetTimeout(SFX_FLUSH_TIMEOUT
);
302 pImp
->aTimer
.SetTimeoutHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
305 SfxDispatcher::SfxDispatcher( SfxDispatcher
* pParent
)
307 Construct_Impl( pParent
);
311 SfxDispatcher::SfxDispatcher( SfxViewFrame
*pViewFrame
)
315 The constructor of the SfxDispatcher class places a stack of empty
316 <SfxShell> pointers. It is not initially locked and is considered flushed.
322 SfxViewFrame
*pFrame
= pViewFrame
->GetParentViewFrame();
324 Construct_Impl( pFrame
->GetDispatcher() );
330 pImp
->pFrame
= pViewFrame
;
333 //====================================================================
334 SfxDispatcher::~SfxDispatcher()
338 The destructor of the SfxDispatcher class should not be called when the
339 SfxDispatcher instance is active. It may, however, still be a <SfxShell>
340 pointer on the stack.
345 OStringBuffer
sTemp(RTL_CONSTASCII_STRINGPARAM("Delete Dispatcher "));
346 sTemp
.append(reinterpret_cast<sal_Int64
>(this));
347 OSL_TRACE("%s", sTemp
.getStr());
348 DBG_ASSERT( !pImp
->bActive
, "deleting active Dispatcher" );
351 // So that no timer by Reschedule in PlugComm strikes the LeaveRegistrations
353 pImp
->xPoster
->SetEventHdl( Link() );
355 // Notify the stack varialbles in Call_Impl
356 if ( pImp
->pInCallAliveFlag
)
357 *pImp
->pInCallAliveFlag
= sal_False
;
359 // Get bindings and application
360 SfxApplication
*pSfxApp
= SFX_APP();
361 SfxBindings
* pBindings
= GetBindings();
363 // When not flushed, revive the bindings
364 if ( pBindings
&& !pSfxApp
->IsDowning() && !bFlushed
)
365 pBindings
->DLEAVEREGISTRATIONS();
367 // may unregister the bindings
370 if ( pBindings
->GetDispatcher_Impl() == this)
371 pBindings
->SetDispatcher(0);
372 pBindings
= pBindings
->GetSubBindings_Impl();
378 //====================================================================
379 void SfxDispatcher::Pop
381 SfxShell
& rShell
, /* the stack to take the SfxShell instance. */
383 sal_uInt16 nMode
/* SFX_SHELL_POP_UNTIL
384 Also all 'rShell' of SfxShells are taken from the
388 All SfxShells actually taken from the stack
391 SFX_SHELL_PUSH (InPlace use only)
392 The Shell is pushed. */
396 With this method, one or more <SfxShell> are poped from the SfxDispatcher.
397 The SfxShell is marked for popping and a timer is set up. Only when the
398 timer has reached the end, the pop is actually performed
399 ( <SfxDispatcher::Flush()> ) and the <SfxBindings> is invalidated.
400 While the timer is running the opposing push and pop commands on one
401 SfxShell cancel each other out.
405 DBG_ASSERT( rShell
.GetInterface(),
406 "pushing SfxShell without previous RegisterInterface()" );
408 bool bDelete
= (nMode
& SFX_SHELL_POP_DELETE
) == SFX_SHELL_POP_DELETE
;
409 bool bUntil
= (nMode
& SFX_SHELL_POP_UNTIL
) == SFX_SHELL_POP_UNTIL
;
410 bool bPush
= (nMode
& SFX_SHELL_PUSH
) == SFX_SHELL_PUSH
;
412 SfxApplication
*pSfxApp
= SFX_APP();
416 "-SfxDispatcher(" << this << (bPush
? ")::Push(" : ")::Pop(")
417 << (rShell
.GetInterface()
418 ? rShell
.GetInterface()->GetClassName() : SAL_STREAM(&rShell
))
419 << (bDelete
? ") with delete" : ")")
420 << (bUntil
? " (up to)" : ""));
422 // same shell as on top of the to-do stack?
423 if(pImp
->aToDoStack
.size() && pImp
->aToDoStack
.front().pCluster
== &rShell
)
425 // cancel inverse actions
426 if ( pImp
->aToDoStack
.front().bPush
!= bPush
)
427 pImp
->aToDoStack
.pop_front();
430 DBG_ASSERT( bPush
, "SfxInterface pushed more than once" );
431 DBG_ASSERT( !bPush
, "SfxInterface popped more than once" );
436 // Remember ::com::sun::star::chaos::Action
437 pImp
->aToDoStack
.push_front( SfxToDo_Impl(bPush
, bDelete
, bUntil
, rShell
) );
440 OSL_TRACE("Unflushed dispatcher!");
441 bFlushed
= sal_False
;
442 pImp
->bUpdated
= sal_False
;
444 // Put bindings to sleep
445 SfxBindings
* pBindings
= GetBindings();
447 pBindings
->DENTERREGISTRATIONS();
451 if(!pSfxApp
->IsDowning() && !pImp
->aToDoStack
.empty())
453 // No immediate update is requested
454 pImp
->aTimer
.SetTimeout(SFX_FLUSH_TIMEOUT
);
455 pImp
->aTimer
.SetTimeoutHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
456 pImp
->aTimer
.Start();
463 // Bindings may wake up again
464 if(pImp
->aToDoStack
.empty())
466 SfxBindings
* pBindings
= GetBindings();
468 pBindings
->DLEAVEREGISTRATIONS();
473 //--------------------------------------------------------------------
475 IMPL_LINK_INLINE_START( SfxDispatcher
, EventHdl_Impl
, void *, pvoid
)
479 This handler is called after <SfxDispatcher::Invalidate()> or after
480 changes on the stack (<SfxDispatcher::Push()> and <SfxDispatcher::Pop())
482 It flushes the Stack, if it is dirty, thus it actually excecutes the
483 pending Push and Pop commands.
487 (void)pvoid
; // unused
491 SfxBindings
* pBindings
= GetBindings();
493 pBindings
->StartUpdate_Impl(sal_False
);
496 IMPL_LINK_INLINE_END( SfxDispatcher
, EventHdl_Impl
, void *, pvoid
)
498 //--------------------------------------------------------------------
499 sal_Bool
SfxDispatcher::CheckVirtualStack( const SfxShell
& rShell
, sal_Bool bDeep
)
503 With this method it can be tested whether the <SfxShell> rShell is on the
504 stack, when it was flushed. This way the SfxDispatcher is not actually
507 This method is intended among other things to make assertions possible
508 without the side effect of having to flush the SfxDispathcer.
512 SFX_STACK(SfxDispatcher::CheckVirtualStack
);
514 SfxShellStack_Impl
aStack( pImp
->aStack
);
515 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= pImp
->aToDoStack
.rbegin(); i
!= pImp
->aToDoStack
.rend(); ++i
)
518 aStack
.push_back(i
->pCluster
);
521 SfxShell
* pPopped(NULL
);
524 DBG_ASSERT( !aStack
.empty(), "popping from empty stack" );
525 pPopped
= aStack
.back();
528 while(i
->bUntil
&& pPopped
!= i
->pCluster
);
529 DBG_ASSERT(pPopped
== i
->pCluster
, "popping unpushed SfxInterface");
535 bReturn
= std::find(aStack
.begin(), aStack
.end(), &rShell
) != aStack
.end();
537 bReturn
= aStack
.back() == &rShell
;
541 //--------------------------------------------------------------------
542 sal_uInt16
SfxDispatcher::GetShellLevel( const SfxShell
& rShell
)
546 Determines the position of a given SfxShell in the stack of the dispatcher.
547 If possible this is flushed before.
551 sal_uInt16 == USRT_MAX
552 The SfxShell is not on this SfxDispatcher.
555 Position of the SfxShell on the Dispatcher
556 from the top count stating with 0.
560 SFX_STACK(SfxDispatcher::GetShellLevel
);
563 for ( sal_uInt16 n
= 0; n
< pImp
->aStack
.size(); ++n
)
564 if ( *( pImp
->aStack
.rbegin() + n
) == &rShell
)
568 sal_uInt16 nRet
= pImp
->pParent
->GetShellLevel(rShell
);
569 if ( nRet
== USHRT_MAX
)
571 return nRet
+ pImp
->aStack
.size();
577 //--------------------------------------------------------------------
578 SfxShell
*SfxDispatcher::GetShell(sal_uInt16 nIdx
) const
582 Returns a pointer to the <SfxShell> which is at the position nIdx
583 (from the top, last pushed is 0) on the stack.
585 Thus the SfxDispatcher is not flushed.
587 Is the stack not deep enough a NULL-Pointer is returned.
591 sal_uInt16 nShellCount
= pImp
->aStack
.size();
592 if ( nIdx
< nShellCount
)
593 return *(pImp
->aStack
.rbegin() + nIdx
);
594 else if ( pImp
->pParent
)
595 return pImp
->pParent
->GetShell( nIdx
- nShellCount
);
599 //--------------------------------------------------------------------
600 SfxBindings
* SfxDispatcher::GetBindings() const
604 This method returns a pointer to the <SfxBinding> Instance on which the
605 SfxDispatcher is curretly bound. A SfxDispatcher is only bound to
606 the SfxBindings when it is <UI-aktiv>. If it is not UI-active,
607 a NULL-pointer is returned.
609 The returned pointer is only valid in the immediate context of the method
615 return &pImp
->pFrame
->GetBindings();
620 //--------------------------------------------------------------------
621 SfxViewFrame
* SfxDispatcher::GetFrame() const
625 Returns a pointer to the <SfxViewFrame> instance, which belongs to
626 this SfxDispatcher. If it is about the application dispatcher,
627 a NULL-pointer is returned.
634 //--------------------------------------------------------------------
635 void SfxDispatcher::DoActivate_Impl( sal_Bool bMDI
, SfxViewFrame
* /* pOld */ )
639 This method controls the activation of a dispatcher.
641 Since the application dispatcher is always active, either as a sub
642 dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
643 activated as a whole, instead only its individual <SfxShell>s at
644 <SfxDispatcher::Push(SfxShell&)>.
646 When activating a SfxDispatcher all of the SfxShells located on its stack
647 are called with the handler <SfxShell::Activate(sal_Bool)>, starting with
652 SFX_STACK(SfxDispatcher::DoActivate
);
657 RTL_CONSTASCII_STRINGPARAM("Activate Dispatcher "));
658 sTemp
.append(reinterpret_cast<sal_Int64
>(this));
659 OSL_TRACE("%s", sTemp
.getStr());
660 DBG_ASSERT( !pImp
->bActive
, "Activation error" );
662 pImp
->bActive
= sal_True
;
663 pImp
->bUpdated
= sal_False
;
664 SfxBindings
* pBindings
= GetBindings();
667 pBindings
->SetDispatcher(this);
668 pBindings
->SetActiveFrame( pImp
->pFrame
->GetFrame().GetFrameInterface() );
675 RTL_CONSTASCII_STRINGPARAM("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(RTL_CONSTASCII_STRINGPARAM("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(RTL_CONSTASCII_STRINGPARAM("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 String
& 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()
1218 SfxViewFrame
* pTop
= pImp
->pFrame
->GetTopViewFrame();
1219 if ( pTop
&& pTop
->GetBindings().GetDispatcher() == this )
1221 SfxFrame
& rFrame
= pTop
->GetFrame();
1222 if ( rFrame
.IsMenuBarOn_Impl() )
1224 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( rFrame
.GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
1225 if ( xPropSet
.is() )
1227 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1228 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue( OUString( "LayoutManager" ));
1229 aValue
>>= xLayoutManager
;
1230 if ( xLayoutManager
.is() )
1232 OUString
aMenuBarURL( "private:resource/menubar/menubar" );
1233 if ( !xLayoutManager
->isElementVisible( aMenuBarURL
) )
1234 xLayoutManager
->createElement( aMenuBarURL
);
1242 //--------------------------------------------------------------------
1243 void SfxDispatcher::Update_Impl( sal_Bool bForce
)
1245 SFX_STACK(SfxDispatcher::Update_Impl
);
1249 if ( !pImp
->pFrame
)
1252 SFX_APP(); // -Wall is this required???
1253 SfxDispatcher
*pDisp
= this;
1254 sal_Bool bUpdate
= bForce
;
1255 while ( pDisp
&& pDisp
->pImp
->pFrame
)
1257 SfxWorkWindow
*pWork
= pDisp
->pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1258 SfxDispatcher
*pAct
= pWork
->GetBindings().GetDispatcher_Impl();
1259 if ( pAct
== pDisp
|| pAct
== this )
1262 bUpdate
= !pDisp
->pImp
->bUpdated
;
1263 pDisp
->pImp
->bUpdated
= sal_True
;
1268 pDisp
= pDisp
->pImp
->pParent
;
1271 if ( !bUpdate
|| pImp
->pFrame
->GetFrame().IsClosing_Impl() )
1274 SfxViewFrame
* pTop
= pImp
->pFrame
? pImp
->pFrame
->GetTopViewFrame() : NULL
;
1275 sal_Bool bUIActive
= pTop
&& pTop
->GetBindings().GetDispatcher() == this;
1277 if ( !bUIActive
&& pTop
&& GetBindings() == &pTop
->GetBindings() )
1278 // keep own tools internally for collecting
1279 GetBindings()->GetDispatcher()->pImp
->bUpdated
= sal_False
;
1281 SfxBindings
* pBindings
= GetBindings();
1283 pBindings
->DENTERREGISTRATIONS();
1285 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xFrame
= pBindings
->GetActiveFrame();
1286 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( xFrame
, com::sun::star::uno::UNO_QUERY
);
1287 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1288 if ( xPropSet
.is() )
1292 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue( OUString( "LayoutManager" ) );
1293 aValue
>>= xLayoutManager
;
1295 catch (const com::sun::star::uno::Exception
&)
1300 if ( xLayoutManager
.is() )
1301 xLayoutManager
->lock();
1303 sal_Bool bIsIPActive
= pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
1304 SfxInPlaceClient
*pClient
= pImp
->pFrame
? pImp
->pFrame
->GetViewShell()->GetUIActiveClient() : NULL
;
1305 if ( bUIActive
&& /* !bIsIPActive && */ ( !pClient
|| !pClient
->IsObjectUIActive() ) )
1308 SfxWorkWindow
*pWorkWin
= pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1309 SfxWorkWindow
*pTaskWin
= pImp
->pFrame
->GetTopFrame().GetWorkWindow_Impl();
1310 pTaskWin
->ResetStatusBar_Impl();
1312 SfxDispatcher
*pDispat
= this;
1315 SfxWorkWindow
*pWork
= pDispat
->pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1316 SfxDispatcher
*pAct
= pWork
->GetBindings().GetDispatcher_Impl();
1317 if ( pAct
== pDispat
|| pAct
== this )
1319 pWork
->ResetObjectBars_Impl();
1320 pWork
->ResetChildWindows_Impl();
1323 pDispat
= pDispat
->pImp
->pParent
;
1326 sal_Bool bIsActive
= sal_False
;
1327 SfxDispatcher
*pActDispat
= pWorkWin
->GetBindings().GetDispatcher_Impl();
1329 while ( pActDispat
&& !bIsActive
)
1331 if ( pDispat
== pActDispat
)
1332 bIsActive
= sal_True
;
1333 pActDispat
= pActDispat
->pImp
->pParent
;
1336 _Update_Impl( bUIActive
, !bIsIPActive
, bIsIPActive
, pTaskWin
);
1337 if ( bUIActive
|| bIsActive
)
1338 pWorkWin
->UpdateObjectBars_Impl();
1341 pBindings
->DLEAVEREGISTRATIONS();
1343 if ( xLayoutManager
.is() )
1344 xLayoutManager
->unlock();
1349 void SfxDispatcher::_Update_Impl( sal_Bool bUIActive
, sal_Bool bIsMDIApp
, sal_Bool bIsIPOwner
, SfxWorkWindow
*pTaskWin
)
1352 SfxWorkWindow
*pWorkWin
= pImp
->pFrame
->GetFrame().GetWorkWindow_Impl();
1353 sal_Bool bIsActive
= sal_False
;
1354 sal_Bool bIsTaskActive
= sal_False
;
1355 SfxDispatcher
*pActDispat
= pWorkWin
->GetBindings().GetDispatcher_Impl();
1356 SfxDispatcher
*pDispat
= this;
1357 while ( pActDispat
&& !bIsActive
)
1359 if ( pDispat
== pActDispat
)
1360 bIsActive
= sal_True
;
1361 pActDispat
= pActDispat
->pImp
->pParent
;
1364 if ( pImp
->pParent
&& !pImp
->bQuiet
/* && bUIActive */ )
1365 pImp
->pParent
->_Update_Impl( bUIActive
, bIsMDIApp
, bIsIPOwner
, pTaskWin
);
1367 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
1368 pImp
->aObjBars
[n
].nResId
= 0;
1369 pImp
->aChildWins
.clear();
1371 // bQuiet : own shells aren't considered for UI and SlotServer
1372 // bNoUI: own Shells aren't considered fors UI
1373 if ( pImp
->bQuiet
|| pImp
->bNoUI
|| (pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsPreview()) )
1376 sal_uInt32 nStatBarId
=0;
1377 SfxShell
*pStatusBarShell
= NULL
;
1379 SfxSlotPool
* pSlotPool
= &SfxSlotPool::GetSlotPool( GetFrame() );
1380 sal_uInt16 nTotCount
= pImp
->aStack
.size();
1381 for ( sal_uInt16 nShell
= nTotCount
; nShell
> 0; --nShell
)
1383 SfxShell
*pShell
= GetShell( nShell
-1 );
1384 SfxInterface
*pIFace
= pShell
->GetInterface();
1386 // don't consider shells if "Hidden" oder "Quiet"
1387 sal_Bool bReadOnlyShell
= IsReadOnlyShell_Impl( nShell
-1 );
1389 for ( nNo
= 0; pIFace
&& nNo
<pIFace
->GetObjectBarCount(); ++nNo
)
1391 sal_uInt16 nPos
= pIFace
->GetObjectBarPos(nNo
);
1392 if ( bReadOnlyShell
&& !( nPos
& SFX_VISIBILITY_READONLYDOC
) )
1395 // check whether toolbar needs activation of a special feature
1396 sal_uInt32 nFeature
= pIFace
->GetObjectBarFeature(nNo
);
1397 if ( nFeature
&& !pShell
->HasUIFeature( nFeature
) )
1400 // check for toolboxes that are exclusively for a viewer
1403 sal_Bool bViewerTbx
= SFX_VISIBILITY_VIEWER
== ( nPos
& SFX_VISIBILITY_VIEWER
);
1404 SfxObjectShell
* pSh
= pImp
->pFrame
->GetObjectShell();
1405 SFX_ITEMSET_ARG( pSh
->GetMedium()->GetItemSet(), pItem
, SfxBoolItem
, SID_VIEWONLY
, sal_False
);
1406 sal_Bool bIsViewer
= pItem
&& pItem
->GetValue();
1407 if ( bIsViewer
!= bViewerTbx
)
1411 // always register toolbars, allows to switch them on
1412 sal_Bool bVisible
= pIFace
->IsObjectBarVisible(nNo
);
1414 nPos
&= SFX_POSITION_MASK
;
1416 SfxObjectBars_Impl
& rBar
= pImp
->aObjBars
[nPos
& SFX_POSITION_MASK
];
1418 rBar
.nResId
= pIFace
->GetObjectBarResId(nNo
).GetId();
1419 const String
*pName
= pIFace
->GetObjectBarName(nNo
);
1421 rBar
.aName
= *pName
;
1424 rBar
.pIFace
= pIFace
;
1426 if ( bUIActive
|| bIsActive
)
1428 pWorkWin
->SetObjectBar_Impl(
1429 nPos
, rBar
.nResId
, rBar
.pIFace
, &rBar
.aName
);
1436 for ( nNo
=0; pIFace
&& nNo
<pIFace
->GetChildWindowCount(); nNo
++ )
1438 sal_uInt32 nId
= pIFace
->GetChildWindowId(nNo
);
1439 const SfxSlot
*pSlot
= pSlotPool
->GetSlot( (sal_uInt16
) nId
);
1440 SAL_WARN_IF( !pSlot
, "sfx2.control", "Childwindow slot missing: " << nId
);
1441 if ( bReadOnlyShell
)
1443 // only show ChildWindows if their slot is allowed for readonly documents
1444 if ( pSlot
&& !pSlot
->IsMode( SFX_SLOT_READONLYDOC
) )
1448 sal_uInt32 nFeature
= pIFace
->GetChildWindowFeature(nNo
);
1449 if ( nFeature
&& !pShell
->HasUIFeature( nFeature
) )
1452 // slot decides whether a ChildWindow is shown when document is OLE server or OLE client
1453 sal_uInt16 nMode
= SFX_VISIBILITY_STANDARD
;
1456 if ( pSlot
->IsMode(SFX_SLOT_CONTAINER
) )
1458 if ( pWorkWin
->IsVisible_Impl( SFX_VISIBILITY_CLIENT
) )
1459 nMode
|= SFX_VISIBILITY_CLIENT
;
1463 if ( pWorkWin
->IsVisible_Impl( SFX_VISIBILITY_SERVER
) )
1464 nMode
|= SFX_VISIBILITY_SERVER
;
1468 if ( bUIActive
|| bIsActive
)
1469 pWorkWin
->SetChildWindowVisible_Impl( nId
, sal_True
, nMode
);
1470 if ( bUIActive
|| bIsActive
|| !pWorkWin
->IsFloating( (sal_uInt16
) ( nId
& 0xFFFF ) ) )
1471 pImp
->aChildWins
.push_back( nId
);
1474 if ( bIsMDIApp
|| bIsIPOwner
)
1476 sal_uInt32 nId
= pIFace
->GetStatusBarResId().GetId();
1480 pStatusBarShell
= pShell
;
1485 for ( sal_uInt16 nPos
=0; nPos
<SFX_OBJECTBAR_MAX
; nPos
++ )
1487 SfxObjectBars_Impl
& rFixed
= pImp
->aFixedObjBars
[nPos
];
1488 if ( rFixed
.nResId
)
1490 SfxObjectBars_Impl
& rBar
= pImp
->aObjBars
[nPos
];
1492 pWorkWin
->SetObjectBar_Impl( rFixed
.nMode
,
1493 rFixed
.nResId
, rFixed
.pIFace
, &rFixed
.aName
);
1497 if ( pTaskWin
&& ( bIsMDIApp
|| bIsIPOwner
) )
1499 SfxDispatcher
*pActDispatcher
= pTaskWin
->GetBindings().GetDispatcher_Impl();
1500 SfxDispatcher
*pDispatcher
= this;
1501 while ( pActDispatcher
&& !bIsTaskActive
)
1503 if ( pDispatcher
== pActDispatcher
)
1504 bIsTaskActive
= sal_True
;
1505 pActDispatcher
= pActDispatcher
->pImp
->pParent
;
1508 if ( bIsTaskActive
&& nStatBarId
&& pImp
->pFrame
)
1510 // internal frames also may control statusbar
1511 SfxBindings
& rBindings
= pImp
->pFrame
->GetBindings();
1512 pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->SetStatusBar_Impl( nStatBarId
, pStatusBarShell
, rBindings
);
1517 //--------------------------------------------------------------------
1518 void SfxDispatcher::FlushImpl()
1522 Helper method to execute the outstanding push and pop commands.
1526 DBG_PROFSTART(SfxDispatcherFlush
);
1527 SFX_STACK(SfxDispatcher::FlushImpl
);
1529 OSL_TRACE("Flushing dispatcher!");
1531 pImp
->aTimer
.Stop();
1533 if ( pImp
->pParent
)
1534 pImp
->pParent
->Flush();
1536 pImp
->bFlushing
= !pImp
->bFlushing
;
1537 if ( !pImp
->bFlushing
)
1539 pImp
->bFlushing
= sal_True
;
1540 DBG_PROFSTOP(SfxDispatcherFlush
);
1544 SfxApplication
*pSfxApp
= SFX_APP();
1546 // Re-build the true stack in the first round
1547 std::deque
<SfxToDo_Impl
> aToDoCopy
;
1548 sal_Bool bModify
= sal_False
;
1549 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= pImp
->aToDoStack
.rbegin(); i
!= pImp
->aToDoStack
.rend(); ++i
)
1556 DBG_ASSERT( std::find(pImp
->aStack
.begin(), pImp
->aStack
.end(), i
->pCluster
) == pImp
->aStack
.end(),
1557 "pushed SfxShell already on stack" );
1558 pImp
->aStack
.push_back(i
->pCluster
);
1559 i
->pCluster
->SetDisableFlags(pImp
->nDisableFlags
);
1561 // Mark the moved shell
1562 aToDoCopy
.push_front(*i
);
1567 SfxShell
* pPopped
= 0;
1568 bool bFound
= false;
1571 DBG_ASSERT( !pImp
->aStack
.empty(), "popping from empty stack" );
1572 pPopped
= pImp
->aStack
.back();
1573 pImp
->aStack
.pop_back();
1574 pPopped
->SetDisableFlags( 0 );
1575 bFound
= (pPopped
== i
->pCluster
);
1577 // Mark the moved Shell
1578 aToDoCopy
.push_front(SfxToDo_Impl(sal_False
, i
->bDelete
, sal_False
, *pPopped
));
1580 while(i
->bUntil
&& !bFound
);
1581 DBG_ASSERT( bFound
, "wrong SfxShell popped" );
1584 pImp
->aToDoStack
.clear();
1586 // Invalidate bindings, if possible
1587 if ( !pSfxApp
->IsDowning() )
1591 pImp
->pCachedServ1
= 0;
1592 pImp
->pCachedServ2
= 0;
1595 InvalidateBindings_Impl( bModify
);
1598 pImp
->bFlushing
= sal_False
;
1599 pImp
->bUpdated
= sal_False
; // not only when bModify, if Doc/Template-Config
1600 bFlushed
= sal_True
;
1601 OSL_TRACE("Successfully flushed dispatcher!");
1603 //fdo#70703 FlushImpl may call back into itself so use aToDoCopyStack to talk
1604 //to outer levels of ourself. If DoActivate_Impl/DoDeactivate_Impl deletes
1605 //an entry, then they will walk back up aToDoCopyStack and set outer
1606 //levels's entries to bDeleted
1607 aToDoCopyStack
.push_back(aToDoCopy
);
1608 std::deque
<SfxToDo_Impl
>& rToDoCopy
= aToDoCopyStack
.back();
1609 // Activate the Shells and possible delete them in the 2nd round
1610 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= rToDoCopy
.rbegin(); i
!= rToDoCopy
.rend(); ++i
)
1617 i
->pCluster
->DoActivate_Impl(pImp
->pFrame
, sal_True
);
1619 i
->pCluster
->DoDeactivate_Impl(pImp
->pFrame
, sal_True
);
1622 aToDoCopy
= aToDoCopyStack
.back();
1623 aToDoCopyStack
.pop_back();
1625 for(std::deque
<SfxToDo_Impl
>::reverse_iterator i
= aToDoCopy
.rbegin(); i
!= aToDoCopy
.rend(); ++i
)
1627 if (i
->bDelete
&& !i
->bDeleted
)
1629 if (!aToDoCopyStack
.empty())
1631 //fdo#70703 if there is an outer FlushImpl then inform it that
1632 //we have deleted this cluster
1633 for (std::deque
< std::deque
<SfxToDo_Impl
> >::iterator aI
= aToDoCopyStack
.begin();
1634 aI
!= aToDoCopyStack
.end(); ++aI
)
1636 std::deque
<SfxToDo_Impl
> &v
= *aI
;
1637 for(std::deque
<SfxToDo_Impl
>::iterator aJ
= v
.begin(); aJ
!= v
.end(); ++aJ
)
1639 if (aJ
->pCluster
== i
->pCluster
)
1640 aJ
->bDeleted
= true;
1647 sal_Bool bAwakeBindings
= !aToDoCopy
.empty();
1648 if( bAwakeBindings
)
1651 // If more changes have occurred on the stach when
1652 // Activate/Deactivate/Delete:
1654 // If Push/Pop hs been called by someone, theb also EnterReg was called!
1657 if( bAwakeBindings
&& GetBindings() )
1658 GetBindings()->DLEAVEREGISTRATIONS();
1659 DBG_PROFSTOP(SfxDispatcherFlush
);
1661 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
1662 pImp
->aFixedObjBars
[n
].nResId
= 0;
1664 SAL_INFO("sfx2.control", "SfxDispatcher(" << this << ")::Flush() done");
1667 //--------------------------------------------------------------------
1668 void SfxDispatcher::SetSlotFilter
1670 // HACK(hier muss mal ein enum rein) ???
1671 sal_Bool bEnable
, /* sal_True:
1672 only enable specified slots,
1676 disable specified slots,
1677 first enable all other
1679 sal_uInt16 nCount
, // Number of SIDs in the following Array
1680 const sal_uInt16
* pSIDs
// sorted Array of 'nCount' SIDs
1685 With this method a filter set, the target slots can be enabled or disabled.
1686 The passed array must be retained until the destructor or the next
1687 <SetSlotFilter()>, it is not deleted from the dispatcher, so it can thus be
1690 In read-only documents the quasi ReadOnlyDoc Flag of slots can be
1691 overturned by the use of 'bEnable == 2', so this will be displayed again.
1692 On the other slots it has no effect.
1696 Targeted disabling of Slots 1, 2 and 3:
1698 static sal_uInt16 const pSIDs[] = { 1, 2, 3 };
1699 pDisp->SetSlotFilter( sal_False, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
1701 only permit Slots 5, 6 and 7:
1703 static sal_uInt16 const pSIDs[] = { 5, 6, 7 };
1704 pDisp->SetSlotFilter( sal_True, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
1708 pDisp->SetSlotFilter();
1714 for ( sal_uInt16 n
= 1; n
< nCount
; ++n
)
1715 DBG_ASSERT( pSIDs
[n
] > pSIDs
[n
-1], "SetSlotFilter: SIDs not sorted" );
1718 if ( pImp
->pFilterSIDs
)
1719 pImp
->pFilterSIDs
= 0;
1721 pImp
->bFilterEnabling
= bEnable
;
1722 pImp
->nFilterCount
= nCount
;
1723 pImp
->pFilterSIDs
= pSIDs
;
1725 GetBindings()->InvalidateAll(sal_True
);
1728 //--------------------------------------------------------------------
1736 SfxCompareSIDs_Impl( const void* pSmaller
, const void* pBigger
)
1738 return ( (long) *((sal_uInt16
*)pSmaller
) ) - ( (long) *((sal_uInt16
*)pBigger
) );
1741 //--------------------------------------------------------------------
1742 sal_Bool
SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID
) const
1746 Searches for 'nSID' in the Filter set by <SetSlotFilter()> and
1747 returns sal_True, if the SIDis allowed, or sal_False, if it is
1748 disabled by the Filter.
1751 sal_Bool 0 => disabled
1753 2 => enabled even if ReadOnlyDoc
1758 if ( 0 == pImp
->nFilterCount
)
1759 // => all SIDs allowed
1763 sal_Bool bFound
= 0 != bsearch( &nSID
, pImp
->pFilterSIDs
, pImp
->nFilterCount
,
1764 sizeof(sal_uInt16
), SfxCompareSIDs_Impl
);
1766 // even if ReadOnlyDoc
1767 if ( 2 == pImp
->bFilterEnabling
)
1768 return bFound
? 2 : 1;
1769 // Otherwise after Negative/Positive Filter
1770 return pImp
->bFilterEnabling
? bFound
: !bFound
;
1773 //--------------------------------------------------------------------
1774 sal_Bool
SfxDispatcher::_TryIntercept_Impl
1776 sal_uInt16 nSlot
, // Slot-Id to search for
1777 SfxSlotServer
& rServer
, // <SfxSlotServer>-Instance to fill
1781 // Maybe the parent is also belongs to a component
1782 SfxDispatcher
*pParent
= pImp
->pParent
;
1783 sal_uInt16 nLevels
= pImp
->aStack
.size();
1784 while ( pParent
&& pParent
->pImp
->pFrame
)
1786 if ( pParent
->pImp
->pFrame
->GetFrame().HasComponent() )
1788 // Components may be intercepted
1789 if ( pParent
->_TryIntercept_Impl( nSlot
, rServer
, sal_True
) )
1791 // The own shells are added to the Shell Level
1792 rServer
.SetShellLevel( rServer
.GetShellLevel() + nLevels
);
1796 // No further Interception
1800 nLevels
= nLevels
+ pParent
->pImp
->aStack
.size();
1802 pParent
= pParent
->pImp
->pParent
;
1807 // Query the ComponentViewShell
1809 SfxShell
*pObjShell
= GetShell(0);
1810 SfxInterface
*pIFace
= pObjShell
->GetInterface();
1811 const SfxSlot
*pSlot
= pIFace
->GetSlot(nSlot
);
1815 rServer
.SetSlot(pSlot
);
1816 rServer
.SetShellLevel(0);
1824 sal_Bool
SfxDispatcher::_FindServer
1826 sal_uInt16 nSlot
, // Slot-Id to search for
1827 SfxSlotServer
& rServer
, // <SfxSlotServer>-Instance to fill
1828 sal_Bool bModal
// Dispite ModalMode
1833 This helper method searches for the <Slot-Server> which currently serves
1834 the nSlot. As the result, rServe is filled accordingly.
1836 If known the SfxInterface which is currently served by nSlot can be
1839 The SfxDispatcher is flushed while searching for nSlot.
1845 The Slot was found, rServer is valid.
1848 The Slot is currently not served, rServer is invalid.
1852 SFX_STACK(SfxDispatcher::_FindServer
);
1854 // Dispatcher locked? (nevertheless let SID_HELP_PI through)
1855 if ( IsLocked(nSlot
) )
1857 pImp
->bInvalidateOnUnlock
= sal_True
;
1861 // Count the number of Shells in the linked dispatchers.
1863 sal_uInt16 nTotCount
= pImp
->aStack
.size();
1864 if ( pImp
->pParent
)
1866 SfxDispatcher
*pParent
= pImp
->pParent
;
1869 nTotCount
= nTotCount
+ pParent
->pImp
->aStack
.size();
1870 pParent
= pParent
->pImp
->pParent
;
1875 if (nSlot
>= SID_VERB_START
&& nSlot
<= SID_VERB_END
)
1877 for ( sal_uInt16 nShell
= 0;; ++nShell
)
1879 SfxShell
*pSh
= GetShell(nShell
);
1882 if ( pSh
->ISA(SfxViewShell
) )
1884 const SfxSlot
* pSlot
= pSh
->GetVerbSlot_Impl(nSlot
);
1887 rServer
.SetShellLevel(nShell
);
1888 rServer
.SetSlot( pSlot
);
1895 // SID check against set filter
1896 sal_uInt16 nSlotEnableMode
=0;
1899 nSlotEnableMode
= IsSlotEnabledByFilter_Impl( nSlot
);
1900 if ( 0 == nSlotEnableMode
)
1904 // In Quiet-Mode only Parent-Dispatcher
1907 if ( pImp
->pParent
)
1909 sal_Bool bRet
= pImp
->pParent
->_FindServer( nSlot
, rServer
, bModal
);
1910 rServer
.SetShellLevel
1911 ( rServer
.GetShellLevel() + pImp
->aStack
.size() );
1918 sal_Bool bReadOnly
= ( 2 != nSlotEnableMode
&& pImp
->bReadOnly
);
1920 // search through all the shells of the chained dispatchers
1921 // from top to bottom
1922 sal_uInt16 nFirstShell
= pImp
->bModal
&& !bModal
? pImp
->aStack
.size() : 0;
1923 for ( sal_uInt16 i
= nFirstShell
; i
< nTotCount
; ++i
)
1925 SfxShell
*pObjShell
= GetShell(i
);
1926 SfxInterface
*pIFace
= pObjShell
->GetInterface();
1927 const SfxSlot
*pSlot
= pIFace
->GetSlot(nSlot
);
1929 if ( pSlot
&& pSlot
->nDisableFlags
&& ( pSlot
->nDisableFlags
& pObjShell
->GetDisableFlags() ) != 0 )
1932 if ( pSlot
&& !( pSlot
->nFlags
& SFX_SLOT_READONLYDOC
) && bReadOnly
)
1937 // Slot belongs to Container?
1938 bool bIsContainerSlot
= pSlot
->IsMode(SFX_SLOT_CONTAINER
);
1939 bool bIsInPlace
= pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
1941 // Shell belongs to Server?
1942 // AppDispatcher or IPFrame-Dispatcher
1943 bool bIsServerShell
= !pImp
->pFrame
|| bIsInPlace
;
1945 // Of course ShellServer-Slots are also executable even when it is
1946 // excecuted on a container dispatcher without a IPClient.
1947 if ( !bIsServerShell
)
1949 SfxViewShell
*pViewSh
= pImp
->pFrame
->GetViewShell();
1950 bIsServerShell
= !pViewSh
|| !pViewSh
->GetUIActiveClient();
1953 // Shell belongs to Container?
1954 // AppDispatcher or no IPFrameDispatcher
1955 bool bIsContainerShell
= !pImp
->pFrame
|| !bIsInPlace
;
1956 // Shell and Slot match
1957 if ( !( ( bIsContainerSlot
&& bIsContainerShell
) ||
1958 ( !bIsContainerSlot
&& bIsServerShell
) ) )
1964 rServer
.SetSlot(pSlot
);
1965 rServer
.SetShellLevel(i
);
1973 //--------------------------------------------------------------------
1974 sal_Bool
SfxDispatcher::_FillState
1976 const SfxSlotServer
& rSvr
, // <Slot-Server> to query
1977 SfxItemSet
& rState
, // <SfxItemSet> to be filled
1978 const SfxSlot
* pRealSlot
// The actual Slot if possible
1983 Helper method to obtain the status of the <Slot-Server>s rSvr.
1984 The required slots IDs (partly converted to Which-IDs of the pool)
1985 must be present in rstate.
1987 The SfxDispatcher is flushed before the query.
1991 SFX_STACK(SfxDispatcher::_FillState
);
1993 DBG_PROFSTART(SfxDispatcherFillState
);
1995 const SfxSlot
*pSlot
= rSvr
.GetSlot();
1996 if ( pSlot
&& IsLocked( pSlot
->GetSlotId() ) )
1998 pImp
->bInvalidateOnUnlock
= sal_True
;
1999 DBG_PROFSTOP(SfxDispatcherFillState
);
2005 DBG_ASSERT(bFlushed
, "Dispatcher not flushed after retrieving slot servers!");
2009 // Determine the object and call the Message of this object
2010 SfxShell
*pSh
= GetShell(rSvr
.GetShellLevel());
2011 DBG_ASSERT(pSh
, "ObjektShell not found");
2016 pFunc
= pRealSlot
->GetStateFnc();
2018 pFunc
= pSlot
->GetStateFnc();
2020 pSh
->CallState( pFunc
, rState
);
2022 // To examine the conformity of IDL (SlotMap) and current Items
2023 if ( DbgIsAssertWarning() && rState
.Count() )
2025 SfxInterface
*pIF
= pSh
->GetInterface();
2026 SfxItemIter
aIter( rState
);
2027 for ( const SfxPoolItem
*pItem
= aIter
.FirstItem();
2029 pItem
= aIter
.NextItem() )
2031 if ( !IsInvalidItem(pItem
) && !pItem
->ISA(SfxVoidItem
) )
2033 sal_uInt16 nSlotId
= rState
.GetPool()->GetSlotId(pItem
->Which());
2034 if ( !pItem
->IsA(pIF
->GetSlot(nSlotId
)->GetType()->Type()) )
2036 OStringBuffer
aMsg(RTL_CONSTASCII_STRINGPARAM(
2037 "item-type unequal to IDL (=> no BASIC)"));
2038 aMsg
.append(RTL_CONSTASCII_STRINGPARAM("\nwith SID: "));
2039 aMsg
.append(static_cast<sal_Int32
>(nSlotId
));
2040 aMsg
.append(RTL_CONSTASCII_STRINGPARAM("\nin "));
2041 aMsg
.append(pIF
->GetClassName());
2042 DbgOut(aMsg
.getStr(), DBG_OUT_ERROR
, __FILE__
, __LINE__
);
2049 DBG_PROFSTOP(SfxDispatcherFillState
);
2053 DBG_PROFSTOP(SfxDispatcherFillState
);
2057 SfxPopupMenuManager
* SfxDispatcher::Popup( sal_uInt16 nConfigId
,Window
*pWin
, const Point
*pPos
)
2059 SfxDispatcher
&rDisp
= *SFX_APP()->GetDispatcher_Impl();
2060 sal_uInt16 nShLevel
= 0;
2063 if ( rDisp
.pImp
->bQuiet
)
2066 nShLevel
= rDisp
.pImp
->aStack
.size();
2069 Window
*pWindow
= pWin
? pWin
: rDisp
.pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
2070 for ( pSh
= rDisp
.GetShell(nShLevel
); pSh
; ++nShLevel
, pSh
= rDisp
.GetShell(nShLevel
) )
2072 const ResId
& rResId
= pSh
->GetInterface()->GetPopupMenuResId();
2073 if ( ( nConfigId
== 0 && rResId
.GetId() ) || ( nConfigId
!= 0 && rResId
.GetId() == nConfigId
) )
2075 return SfxPopupMenuManager::Popup( rResId
, rDisp
.GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2082 //----------------------------------------------------------------------
2083 void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId
, Window
*pWin
, const Point
*pPos
)
2085 SfxDispatcher
&rDisp
= *SFX_APP()->GetDispatcher_Impl();
2086 sal_uInt16 nShLevel
= 0;
2089 if ( rDisp
.pImp
->bQuiet
)
2092 nShLevel
= rDisp
.pImp
->aStack
.size();
2095 Window
*pWindow
= pWin
? pWin
: rDisp
.pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
2096 for ( pSh
= rDisp
.GetShell(nShLevel
); pSh
; ++nShLevel
, pSh
= rDisp
.GetShell(nShLevel
) )
2098 const ResId
& rResId
= pSh
->GetInterface()->GetPopupMenuResId();
2099 if ( ( nConfigId
== 0 && rResId
.GetId() ) || ( nConfigId
!= 0 && rResId
.GetId() == nConfigId
) )
2101 SfxPopupMenuManager::ExecutePopup( rResId
, rDisp
.GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2107 //----------------------------------------------------------------------
2108 void SfxDispatcher::ExecutePopup( const ResId
&rId
, Window
*pWin
, const Point
*pPos
)
2110 Window
*pWindow
= pWin
? pWin
: pImp
->pFrame
->GetFrame().GetWorkWindow_Impl()->GetWindow();
2111 SfxPopupMenuManager::ExecutePopup( rId
, GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2114 //--------------------------------------------------------------------
2115 void SfxDispatcher::Lock( sal_Bool bLock
)
2119 With this method the SfxDispatcher can be locked and released. A locked
2120 SfxDispatcher does not perform <SfxRequest>s and does no longer provide
2121 status information. It behaves as if all the slots were disabled.
2125 SfxBindings
* pBindings
= GetBindings();
2126 if ( !bLock
&& pImp
->bLocked
&& pImp
->bInvalidateOnUnlock
)
2129 pBindings
->InvalidateAll(sal_True
);
2130 pImp
->bInvalidateOnUnlock
= sal_False
;
2132 else if ( pBindings
)
2133 pBindings
->InvalidateAll(sal_False
);
2134 pImp
->bLocked
= bLock
;
2137 for(size_t i
= 0; i
< pImp
->aReqArr
.size(); ++i
)
2138 pImp
->xPoster
->Post(pImp
->aReqArr
[i
]);
2139 pImp
->aReqArr
.clear();
2143 sal_uInt32
SfxDispatcher::GetObjectBarId( sal_uInt16 nPos
) const
2145 return pImp
->aObjBars
[nPos
].nResId
;
2148 //-------------------------------------------------------------------------
2149 void SfxDispatcher::HideUI( sal_Bool bHide
)
2151 sal_Bool bWasHidden
= pImp
->bNoUI
;
2152 pImp
->bNoUI
= bHide
;
2155 SfxViewFrame
* pTop
= pImp
->pFrame
->GetTopViewFrame();
2156 if ( pTop
&& pTop
->GetBindings().GetDispatcher() == this )
2158 SfxFrame
& rFrame
= pTop
->GetFrame();
2159 if ( rFrame
.IsMenuBarOn_Impl() )
2161 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( rFrame
.GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
2162 if ( xPropSet
.is() )
2164 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
2165 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue( OUString( "LayoutManager" ));
2166 aValue
>>= xLayoutManager
;
2167 if ( xLayoutManager
.is() )
2168 xLayoutManager
->setVisible( !bHide
);
2174 if ( bHide
!= bWasHidden
)
2175 Update_Impl( sal_True
);
2178 void SfxDispatcher::SetReadOnly_Impl( sal_Bool bOn
)
2180 pImp
->bReadOnly
= bOn
;
2183 sal_Bool
SfxDispatcher::GetReadOnly_Impl() const
2185 return pImp
->bReadOnly
;
2188 //-------------------------------------------------------------------------
2189 void SfxDispatcher::SetQuietMode_Impl( sal_Bool bOn
)
2193 With 'bOn' the Dispatcher is quasi dead and transfers everything to the
2199 SfxBindings
* pBindings
= GetBindings();
2201 pBindings
->InvalidateAll(sal_True
);
2204 SfxItemState
SfxDispatcher::QueryState( sal_uInt16 nSlot
, const SfxPoolItem
* &rpState
)
2206 SfxShell
*pShell
= 0;
2207 const SfxSlot
*pSlot
= 0;
2208 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
, sal_False
) )
2210 rpState
= pShell
->GetSlotState(nSlot
);
2212 return SFX_ITEM_DISABLED
;
2214 return SFX_ITEM_AVAILABLE
;
2217 return SFX_ITEM_DISABLED
;
2220 SfxItemState
SfxDispatcher::QueryState( sal_uInt16 nSID
, ::com::sun::star::uno::Any
& rAny
)
2222 SfxShell
*pShell
= 0;
2223 const SfxSlot
*pSlot
= 0;
2224 if ( GetShellAndSlot_Impl( nSID
, &pShell
, &pSlot
, sal_False
, sal_False
) )
2226 const SfxPoolItem
* pItem( 0 );
2228 pItem
= pShell
->GetSlotState( nSID
);
2230 return SFX_ITEM_DISABLED
;
2233 ::com::sun::star::uno::Any aState
;
2234 if ( !pItem
->ISA(SfxVoidItem
) )
2236 sal_uInt16
nSubId( 0 );
2237 SfxItemPool
& rPool
= pShell
->GetPool();
2238 sal_uInt16 nWhich
= rPool
.GetWhich( nSID
);
2239 if ( rPool
.GetMetric( nWhich
) == SFX_MAPUNIT_TWIP
)
2240 nSubId
|= CONVERT_TWIPS
;
2241 pItem
->QueryValue( aState
, (sal_uInt8
)nSubId
);
2245 return SFX_ITEM_AVAILABLE
;
2249 return SFX_ITEM_DISABLED
;
2252 sal_Bool
SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell
) const
2254 sal_uInt16 nShellCount
= pImp
->aStack
.size();
2255 if ( nShell
< nShellCount
)
2257 SfxShell
* pShell
= *( pImp
->aStack
.rbegin() + nShell
);
2258 if( pShell
->ISA( SfxModule
) || pShell
->ISA( SfxApplication
) || pShell
->ISA( SfxViewFrame
) )
2261 return pImp
->bReadOnly
;
2263 else if ( pImp
->pParent
)
2264 return pImp
->pParent
->IsReadOnlyShell_Impl( nShell
- nShellCount
);
2268 void SfxDispatcher::RemoveShell_Impl( SfxShell
& rShell
)
2272 sal_uInt16 nCount
= pImp
->aStack
.size();
2273 for ( sal_uInt16 n
=0; n
<nCount
; ++n
)
2275 if ( pImp
->aStack
[n
] == &rShell
)
2277 pImp
->aStack
.erase( pImp
->aStack
.begin() + n
);
2278 rShell
.SetDisableFlags( 0 );
2279 rShell
.DoDeactivate_Impl(pImp
->pFrame
, sal_True
);
2284 if ( !SFX_APP()->IsDowning() )
2286 pImp
->bUpdated
= sal_False
;
2287 pImp
->pCachedServ1
= 0;
2288 pImp
->pCachedServ2
= 0;
2289 InvalidateBindings_Impl(sal_True
);
2293 void SfxDispatcher::InvalidateBindings_Impl( sal_Bool bModify
)
2296 if ( IsAppDispatcher() )
2298 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst();
2300 pFrame
= SfxViewFrame::GetNext( *pFrame
) )
2301 pFrame
->GetBindings().InvalidateAll(bModify
);
2305 SfxDispatcher
*pDisp
= GetBindings()->GetDispatcher_Impl();
2308 if ( pDisp
== this )
2310 GetBindings()->InvalidateAll( bModify
);
2314 pDisp
= pDisp
->pImp
->pParent
;
2319 sal_Bool
SfxDispatcher::IsUpdated_Impl() const
2321 return pImp
->bUpdated
;
2324 void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags
)
2326 pImp
->nDisableFlags
= nFlags
;
2327 for ( SfxShellStack_Impl::const_reverse_iterator it
= pImp
->aStack
.rbegin(); it
!= pImp
->aStack
.rend(); ++it
)
2328 (*it
)->SetDisableFlags( nFlags
);
2331 sal_uInt32
SfxDispatcher::GetDisableFlags() const
2333 return pImp
->nDisableFlags
;
2336 SfxModule
* SfxDispatcher::GetModule() const
2338 for ( sal_uInt16 nShell
= 0;; ++nShell
)
2340 SfxShell
*pSh
= GetShell(nShell
);
2343 if ( pSh
->ISA(SfxModule
) )
2344 return (SfxModule
*) pSh
;
2348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */