summaryrefslogtreecommitdiff
path: root/sfx2/source/control/dispatch.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/control/dispatch.cxx')
-rw-r--r--sfx2/source/control/dispatch.cxx3180
1 files changed, 3180 insertions, 0 deletions
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
new file mode 100644
index 000000000000..444be02127b3
--- /dev/null
+++ b/sfx2/source/control/dispatch.cxx
@@ -0,0 +1,3180 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <svl/itempool.hxx>
+#include <svl/itemiter.hxx>
+#include <svl/whiter.hxx>
+#include <svl/intitem.hxx>
+#ifndef _SFXEITEM_HXX //autogen
+#include <svl/eitem.hxx>
+#endif
+#include <svl/undo.hxx>
+#ifndef _WRKWIN_HXX //autogen
+#include <vcl/wrkwin.hxx>
+#endif
+#include <svtools/ttprops.hxx>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h> // wg. bsearch
+
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+#include <svtools/helpopt.hxx>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#ifndef GCC
+#endif
+
+// wg. nAutoPageID
+#include "appdata.hxx"
+#include "sfxhelp.hxx"
+#include <sfx2/dispatch.hxx>
+#include <sfx2/minstack.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/hintpost.hxx>
+#include "slotserv.hxx"
+#include <sfx2/ipclient.hxx>
+#include "sfxtypes.hxx"
+#include <sfx2/macrconf.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/msgpool.hxx>
+#include <sfx2/module.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/sfxuno.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/mnumgr.hxx>
+#include "workwin.hxx"
+
+namespace css = ::com::sun::star;
+
+//==================================================================
+DBG_NAME(SfxDispatcherFlush)
+DBG_NAME(SfxDispatcherFillState)
+
+//==================================================================
+typedef SfxRequest* SfxRequestPtr;
+SV_IMPL_PTRARR( SfxItemPtrArray, SfxPoolItemPtr );
+SV_DECL_PTRARR_DEL( SfxRequestPtrArray, SfxRequestPtr, 4, 4 )
+SV_IMPL_PTRARR( SfxRequestPtrArray, SfxRequestPtr );
+
+DECL_PTRSTACK(SfxShellStack_Impl, SfxShell*, 8, 4 );
+//==================================================================
+
+struct SfxToDo_Impl
+{
+ SfxShell* pCluster;
+ bool bPush;
+ bool bDelete;
+ bool bUntil;
+
+ SfxToDo_Impl()
+ : pCluster(0)
+ , bPush(false)
+ , bDelete(false)
+ , bUntil(false)
+ {}
+ SfxToDo_Impl( bool bOpPush, bool bOpDelete, bool bOpUntil, SfxShell& rCluster )
+ : pCluster(&rCluster)
+ , bPush(bOpPush)
+ , bDelete(bOpDelete)
+ , bUntil(bOpUntil)
+ {}
+ ~SfxToDo_Impl(){}
+
+ bool operator==( const SfxToDo_Impl& rWith ) const
+ { return pCluster==rWith.pCluster && bPush==rWith.bPush; }
+};
+
+DECL_OBJSTACK(SfxToDoStack_Impl, SfxToDo_Impl, 8, 4);
+IMPL_OBJSTACK(SfxToDoStack_Impl, SfxToDo_Impl);
+
+struct SfxObjectBars_Impl
+{
+ sal_uInt32 nResId; // Resource - und ConfigId der Toolbox
+ sal_uInt16 nMode; // spezielle Sichtbarkeitsflags
+ String aName;
+ SfxInterface* pIFace;
+
+ SfxObjectBars_Impl() :
+ nResId( 0 )
+ {}
+};
+
+//------------------------------------------------------------------
+
+struct SfxDispatcher_Impl
+{
+ SfxRequestPtrArray aReqArr;
+ const SfxSlotServer* pCachedServ1; // zuletzt gerufene Message
+ const SfxSlotServer* pCachedServ2; // vorletzt gerufene Message
+ SfxShellStack_Impl aStack; // aktive Funktionalitaet
+ Timer aTimer; // fuers flushen
+ SfxToDoStack_Impl aToDoStack; // nicht abgearb. Push/Pop
+ SfxViewFrame* pFrame; // 0 oder zugeh"or. Frame
+ SfxDispatcher* pParent; // z.B. AppDispatcher, ggf. 0
+ SfxHintPosterRef xPoster; // asynchrones Execute
+ sal_Bool bFlushing; // sal_True waehrend Flush //?
+ sal_Bool bUpdated; // Update_Impl gelaufen
+ sal_Bool bLocked; // kein Execute
+ sal_Bool bInvalidateOnUnlock;// da fragte jemand
+ sal_Bool bActive; // nicht verwechseln mit gesetzt!
+ sal_Bool* pInCallAliveFlag; // dem Stack den Dtor anzeigen
+ SfxObjectBars_Impl aObjBars[SFX_OBJECTBAR_MAX];
+ SfxObjectBars_Impl aFixedObjBars[SFX_OBJECTBAR_MAX];
+ SvULongs aChildWins;
+ sal_uInt16 nActionLevel; // in EnterAction
+ sal_uInt32 nEventId; // EventId UserEvent
+ sal_Bool bUILocked; // Update abgeklemmt (!zappeln)
+ sal_Bool bNoUI; // UI nur vom Parent Dispatcher
+ sal_Bool bReadOnly; // Dokument ist ReadOnly
+ sal_Bool bQuiet; // nur parent dispatcher verwenden
+ sal_Bool bModal; // nur Slots vom Parent-Dispatcher
+
+ sal_Bool bFilterEnabling; // sal_True=filter enabled slots, 2==ReadOnlyDoc uebersteuert
+ sal_uInt16 nFilterCount; // Anzahl der SIDs in pFilterSIDs
+ const sal_uInt16* pFilterSIDs; // sortiertes Array von SIDs
+ sal_uInt16 nStandardMode; // ExecuteMode f. PlugInDispatcher
+ SvUShorts* pDisableList;
+ sal_uInt32 nDisableFlags;
+};
+
+#define NO_OBJECTBAR 0
+#define OWN_OBJECTBAR 1
+#define OTHER_OBJECTBAR 2
+
+//------------------------------------------------------------------
+
+#define SFX_FLUSH_TIMEOUT 50
+
+//====================================================================
+sal_Bool SfxDispatcher::IsLocked( sal_uInt16 ) const
+
+/* [Beschreibung]
+
+ Mit dieser Methode kann festgestellt werden, ob der SfxDispatcher
+ gesperrt oder freigegeben ist. Ein gesperrter SfxDispatcher
+ f"uhrt keine <SfxRequest>s mehr aus und liefert keine
+ Status-Informationen mehr. Er verh"alt sich so als w"aren alle
+ Slots disabled.
+
+ Der Dispatcher gilt auch als gesperrt, wenn alle Dispatcher
+ gelockt sind (<SfxApplication::LockDispatcher()>) oder der zugeh"orige
+ Top-Frame im modal-mode ist und der angegebene Slot Frame-spezifisch
+ (also nicht von der Application) bedient wird.
+*/
+
+{
+ return pImp->bLocked;
+}
+
+//--------------------------------------------------------------------
+sal_Bool SfxDispatcher::IsAppDispatcher() const
+
+/* [Beschreibung]
+
+ Mit dieser Methode l"a\st sich festellen, ob der SfxDispacher der
+ Applikations-Dispatcher ist.
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Es ist der Applikations-Dispatcher.
+
+ sal_False
+ Es ist ein Dispatcher eines SfxViewFrame.
+*/
+
+{
+ return !pImp->pFrame;
+}
+
+//--------------------------------------------------------------------
+int SfxDispatcher::Call_Impl( SfxShell& rShell, const SfxSlot &rSlot, SfxRequest &rReq, sal_Bool bRecord )
+
+/* [Beschreibung]
+
+ Hilfsfunktion zum pr"ufen, ob ein Slot executed werden darf und
+ der Execution selbst.
+*/
+
+{
+ SFX_STACK(SfxDispatcher::Call_Impl);
+
+ // darf der Slot gerufen werden (i.S.v. enabled)
+ if ( rSlot.IsMode(SFX_SLOT_FASTCALL) || rShell.CanExecuteSlot_Impl(rSlot) )
+ {
+ if ( GetFrame() )
+ {
+ // ggf. Recording anwerfen
+ com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame(
+ GetFrame()->GetFrame().GetFrameInterface(),
+ com::sun::star::uno::UNO_QUERY);
+
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet(
+ xFrame,
+ com::sun::star::uno::UNO_QUERY);
+
+ if ( xSet.is() )
+ {
+ com::sun::star::uno::Any aProp = xSet->getPropertyValue(::rtl::OUString::createFromAscii("DispatchRecorderSupplier"));
+ com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier;
+ com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder;
+ aProp >>= xSupplier;
+ if(xSupplier.is())
+ xRecorder = xSupplier->getDispatchRecorder();
+
+ if ( bRecord && xRecorder.is() && !rSlot.IsMode(SFX_SLOT_NORECORD) )
+ rReq.Record_Impl( rShell, rSlot, xRecorder, GetFrame() );
+ }
+ }
+
+ // Alles holen, was gebraucht wird, da der Slot den Execute evtl. nicht
+ // "uberlebt, falls es ein 'Pseudoslot' f"ur Macros oder Verben ist
+ sal_Bool bAutoUpdate = rSlot.IsMode(SFX_SLOT_AUTOUPDATE);
+
+ // API-Call-Klammerung und Document-Lock w"ahrend des Calls
+ {
+ // 'this' mu\s im Dtor bescheid sagen
+ sal_Bool bThisDispatcherAlive = sal_True;
+ sal_Bool *pOldInCallAliveFlag = pImp->pInCallAliveFlag;
+ pImp->pInCallAliveFlag = &bThisDispatcherAlive;
+
+ SfxViewFrame* pView = GetFrame();
+ if ( !pView )
+ pView = SfxViewFrame::Current();
+ if ( pView )
+ {
+ rtl::OString aCmd(".uno:");
+ aCmd += rSlot.GetUnoName();
+ SfxHelp::OpenHelpAgent( &pView->GetFrame(), aCmd );
+ }
+
+ SfxExecFunc pFunc = rSlot.GetExecFnc();
+ rShell.CallExec( pFunc, rReq );
+
+ // falls 'this' noch lebt
+ if ( bThisDispatcherAlive )
+ pImp->pInCallAliveFlag = pOldInCallAliveFlag;
+ else
+ {
+ if ( pOldInCallAliveFlag )
+ {
+ // auch verschachtelte Stack-Frames sch"utzen
+ *pOldInCallAliveFlag = sal_False;
+ }
+
+ // do nothing after this object is dead
+ return rReq.IsDone();
+ }
+ }
+
+ if ( rReq.IsDone() )
+ {
+ SfxBindings *pBindings = GetBindings();
+
+ // bei AutoUpdate sofort updaten; "Pseudoslots" d"urfen nicht
+ // Autoupdate sein!
+ if ( bAutoUpdate && pBindings )
+ {
+ const SfxSlot* pSlave = rSlot.GetLinkedSlot();
+ if (pSlave)
+ {
+ // bei Enum-Slots irgendeinen gebundenen Slave-Slot nehmen
+ while (!pBindings->IsBound(pSlave->GetSlotId()) && pSlave != &rSlot )
+ pSlave = pSlave->GetLinkedSlot();
+ pBindings->Invalidate(pSlave->GetSlotId());
+ pBindings->Update(pSlave->GetSlotId());
+ }
+ else
+ {
+ pBindings->Invalidate(rSlot.GetSlotId());
+ pBindings->Update(rSlot.GetSlotId());
+ }
+ }
+
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+//====================================================================
+void SfxDispatcher::Construct_Impl( SfxDispatcher* pParent )
+{
+ pImp = new SfxDispatcher_Impl;
+ bFlushed = sal_True;
+ SfxApplication *pSfxApp = SFX_APP();
+
+ pImp->pCachedServ1 = 0;
+ pImp->pCachedServ2 = 0;
+ pImp->bFlushing = sal_False;
+ pImp->bUpdated = sal_False;
+ pImp->bLocked = sal_False;
+ pImp->bActive = sal_False;
+ pImp->pParent = NULL;
+ pImp->bUILocked = sal_False;
+ pImp->bNoUI = sal_False;
+ pImp->bReadOnly = sal_False;
+ pImp->bQuiet = sal_False;
+ pImp->bModal = sal_False;
+ pImp->pInCallAliveFlag = 0;
+ pImp->bFilterEnabling = sal_False;
+ pImp->nFilterCount = 0;
+ pImp->pFilterSIDs = 0;
+ pImp->nStandardMode = 0;
+ pImp->pDisableList = pSfxApp->GetDisabledSlotList_Impl();
+ pImp->nDisableFlags = 0;
+
+ pImp->pParent = pParent;
+
+ pImp->bInvalidateOnUnlock = sal_False;
+ pImp->nActionLevel = 0;
+
+ for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
+ pImp->aObjBars[n].nResId = 0;
+
+ GenLink aGenLink( LINK(this, SfxDispatcher, PostMsgHandler) );
+
+ pImp->xPoster = new SfxHintPoster(aGenLink);
+
+ pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
+ pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
+}
+
+SfxDispatcher::SfxDispatcher( SfxDispatcher* pParent )
+{
+ Construct_Impl( pParent );
+ pImp->pFrame = 0;
+}
+
+SfxDispatcher::SfxDispatcher( SfxViewFrame *pViewFrame )
+
+/* [Beschreibung]
+
+ Der Konstruktor der Klasse SfxDispatcher legt einen leeren Stack
+ von <SfxShell>-Pointern an. Er ist initial nicht gelockt und gilt als
+ geflusht.
+*/
+
+{
+ if ( pViewFrame )
+ {
+ SfxViewFrame *pFrame = pViewFrame->GetParentViewFrame();
+ if ( pFrame )
+ Construct_Impl( pFrame->GetDispatcher() );
+ else
+ Construct_Impl( 0 );
+ }
+ else
+ Construct_Impl( 0 );
+ pImp->pFrame = pViewFrame;
+}
+
+//====================================================================
+SfxDispatcher::~SfxDispatcher()
+
+/* [Beschreibung]
+
+ Der Destruktor der Klasse SfxDispatcher darf nicht gerufen werden,
+ wenn die SfxDispatcher-Instanz aktiv ist. Es d"urfen sich allerdings
+ noch <SfxShell>-Pointer auf dem Stack befinden.
+*/
+
+{
+#ifdef DBG_UTIL
+ ByteString sTemp( "Delete Dispatcher " );
+ sTemp += ByteString::CreateFromInt64( (sal_uIntPtr)this );
+ DBG_TRACE( sTemp.GetBuffer() );
+ DBG_ASSERT( !pImp->bActive, "deleting active Dispatcher" );
+#endif
+
+ // Damit in LeaveRegistrations kein Timer per Reschedule in PlugComm
+ // zuschlaegt
+ pImp->aTimer.Stop();
+ pImp->xPoster->SetEventHdl( Link() );
+
+ // die Stack-Varialblem in Call_Impl benachrichtigen
+ if ( pImp->pInCallAliveFlag )
+ *pImp->pInCallAliveFlag = sal_False;
+
+ // Bindings und App besorgen
+ SfxApplication *pSfxApp = SFX_APP();
+ SfxBindings* pBindings = GetBindings();
+
+// if (pImp->nEventId)
+// pSfxApp->RemoveEventHdl(pImp->nEventId);
+
+ // wenn noch nicht flushed, die Bindings wiederbeleben
+ if ( pBindings && !pSfxApp->IsDowning() && !bFlushed )
+ pBindings->DLEAVEREGISTRATIONS();
+
+ // ggf. bei den Bindings abmelden
+ while ( pBindings )
+ {
+ if ( pBindings->GetDispatcher_Impl() == this)
+ pBindings->SetDispatcher(0);
+ pBindings = pBindings->GetSubBindings_Impl();
+ }
+
+ delete pImp;
+}
+
+//====================================================================
+void SfxDispatcher::Pop
+(
+ SfxShell& rShell, /* Die vom Stack zu nehmende SfxShell-Instanz. */
+
+ sal_uInt16 nMode /* SFX_SHELL_POP_UNTIL
+ Es werden auch alle "uber 'rShell' liegenenden
+ SfxShell's vom Stack genommen.
+
+ SFX_SHELL_POP_DELETE
+ Alle tats"achlich vom Stack genommenen
+ SfxShells werden gel"oscht.
+
+ SFX_SHELL_PUSH (InPlace use only)
+ Die Shell wird gepusht. */
+)
+/* [Beschreibung]
+
+ Mit dieser Methode wird eine oder mehrere <SfxShell> vom SfxDispatcher
+ gepoppt. Die SfxShell wird zun"achst zum poppen vermerkt und
+ es wird ein Timer aufgesetzt. Erst bei Ablauf des Timers wird
+ tats"achlich gepoppt (<SfxDispatcher::Flush()>) und die <SfxBindings>
+ werden invalidiert. W"ahrend der Timer l"auft gleichen sich
+ entgegengesetzte Push und Pop Befehle mit derselben SfxShell aus.
+*/
+
+{
+ DBG_MEMTEST();
+ DBG_ASSERT( rShell.GetInterface(),
+ "pushing SfxShell without previous RegisterInterface()" );
+ DBG_ASSERT( pImp->nActionLevel == 0, "Push or Pop within Action" );
+// DBG_ASSERT( SFX_APP()->IsInAsynchronCall_Impl(),
+// "Dispatcher Push/Pop in synchron-call-stack" );
+
+ bool bDelete = (nMode & SFX_SHELL_POP_DELETE) == SFX_SHELL_POP_DELETE;
+ bool bUntil = (nMode & SFX_SHELL_POP_UNTIL) == SFX_SHELL_POP_UNTIL;
+ bool bPush = (nMode & SFX_SHELL_PUSH) == SFX_SHELL_PUSH;
+
+ SfxApplication *pSfxApp = SFX_APP();
+
+#ifdef DBG_UTIL
+ ByteString aMsg( "-SfxDispatcher(" );
+ aMsg += ByteString::CreateFromInt64( (sal_uIntPtr) this );
+ aMsg += bPush ? ")::Push(" : ")::Pop(";
+ if ( rShell.GetInterface() )
+ aMsg += rShell.GetInterface()->GetClassName();
+ else
+ aMsg += ByteString::CreateFromInt64( (sal_uIntPtr) &rShell );
+ aMsg += bDelete ? ") with delete" : ")";
+ if ( bUntil ) aMsg += " (up to)";
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+
+ // gleiche Shell wie on-Top des ToDo-Stacks?
+ if ( pImp->aToDoStack.Count() && pImp->aToDoStack.Top().pCluster == &rShell )
+ {
+ // inverse Actions heben sich auf
+ if ( pImp->aToDoStack.Top().bPush != bPush )
+ pImp->aToDoStack.Pop();
+ else
+ {
+ DBG_ASSERT( bPush, "SfxInterface pushed more than once" );
+ DBG_ASSERT( !bPush, "SfxInterface popped more than once" );
+ }
+ }
+ else
+ {
+ // ::com::sun::star::chaos::Action merken
+ pImp->aToDoStack.Push( SfxToDo_Impl(bPush, bDelete, bUntil, rShell) );
+ if ( bFlushed )
+ {
+ DBG_TRACE("Unflushed dispatcher!");
+ bFlushed = sal_False;
+ pImp->bUpdated = sal_False;
+
+ // Bindings schlafen legen
+ SfxBindings* pBindings = GetBindings();
+ if ( pBindings )
+ pBindings->DENTERREGISTRATIONS();
+ }
+ }
+
+ if ( !pSfxApp->IsDowning() && pImp->aToDoStack.Count() )
+ {
+ //! if (SFX_APP()->AnyInput(INPUT_KEYBOARD | INPUT_MOUSE) )
+ //! AnyInput haut nicht hin; hier muss noch ein Kriterium gefunden
+ //! werden. Solange wieder immer mit Timer.
+
+ if (sal_True)
+ {
+ // Kein sofortiges Update gewuenscht
+ pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
+ pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
+ pImp->aTimer.Start();
+ }
+ else
+ {
+ // Schnellstmoegliches Update (sollte Normalfall sein)
+ pImp->aTimer.Stop();
+ GetpApp()->PostUserEvent(pImp->nEventId, (void*)0);
+ }
+ }
+ else
+ {
+ // doch nichts zu tun
+ pImp->aTimer.Stop();
+
+ // ggf. Bindings wieder aufwecken
+ if ( !pImp->aToDoStack.Count() )
+ {
+ SfxBindings* pBindings = GetBindings();
+ if ( pBindings )
+ pBindings->DLEAVEREGISTRATIONS();
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( SfxDispatcher, EventHdl_Impl, void *, pvoid )
+
+/* [Beschreibung]
+
+ Dieser Handler wird nach <SfxDispatcher::Invalidate()> oder Bewegungen
+ auf dem Stack (<SfxDispatcher::Push()> und <SfxDispatcher::Pop()) gerufen.
+
+ Er flusht den Stack, falls er dirty ist, f"uhrt also die ausstehenden
+ Push und Pop Befehle tats"achlich aus.
+*/
+
+{
+ (void)pvoid; // unused
+ DBG_MEMTEST();
+
+ Flush();
+ Update_Impl();
+ SfxBindings* pBindings = GetBindings();
+ if ( pBindings )
+ pBindings->StartUpdate_Impl(sal_False);
+ return 0;
+}
+IMPL_LINK_INLINE_END( SfxDispatcher, EventHdl_Impl, void *, pvoid )
+
+//--------------------------------------------------------------------
+sal_Bool SfxDispatcher::CheckVirtualStack( const SfxShell& rShell, sal_Bool bDeep )
+
+/* [Beschreibung]
+
+ Mit dieser Methode kann gepr"uft werden, ob sich die <SfxShell> rShell
+ auf dem Stack befindet, wenn er geflusht w"are. Dabei wird der
+ SfxDispatcher jedoch nicht tats"achlich geflusht.
+
+ Diese Methode ist u.a. dazu gedacht, Assertions zu erm"oglichen, ohne
+ als Seiteneffekt den SfxDispathcer flushen zu m"ussen.
+*/
+
+{
+ DBG_MEMTEST();
+ SFX_STACK(SfxDispatcher::CheckVirtualStack);
+
+ SfxShellStack_Impl aStack( pImp->aStack );
+ for ( short nToDo = pImp->aToDoStack.Count()-1; nToDo >= 0; --nToDo )
+ {
+ SfxToDo_Impl aToDo( pImp->aToDoStack.Top(nToDo) );
+ if ( aToDo.bPush )
+ aStack.Push( (SfxShell*) aToDo.pCluster );
+ else
+ {
+ SfxShell* pPopped = 0;
+ do
+ {
+ DBG_ASSERT( aStack.Count(), "popping from empty stack" );
+ pPopped = aStack.Pop();
+ }
+ while ( aToDo.bUntil && pPopped != aToDo.pCluster );
+ DBG_ASSERT( pPopped == aToDo.pCluster, "popping unpushed SfxInterface" );
+ }
+ }
+
+ sal_Bool bReturn;
+ if ( bDeep )
+ bReturn = aStack.Contains(&rShell);
+ else
+ bReturn = aStack.Top() == &rShell;
+ return bReturn;
+}
+
+//--------------------------------------------------------------------
+sal_uInt16 SfxDispatcher::GetShellLevel( const SfxShell& rShell )
+
+/* [Beschreibung]
+
+ Ermittelt die Position einer SfxShell im Stack des Dispatchers.
+ Dazu wird dieser ggf. zuvor geflusht.
+
+
+ [Rueckgabewert]
+
+ sal_uInt16 == USRT_MAX
+ Die SfxShell befindet sich nicht auf
+ diesem SfxDispatcher.
+
+ < USHRT_MAX
+ Position der SfxShell auf dem Dispatcher
+ von oben mit 0 beginnend gez"ahlt.
+*/
+
+{
+ DBG_MEMTEST();
+ SFX_STACK(SfxDispatcher::GetShellLevel);
+ Flush();
+
+ for ( sal_uInt16 n = 0; n < pImp->aStack.Count(); ++n )
+ if ( pImp->aStack.Top( n ) == &rShell )
+ return n;
+ if ( pImp->pParent )
+ {
+ sal_uInt16 nRet = pImp->pParent->GetShellLevel(rShell);
+ if ( nRet == USHRT_MAX )
+ return nRet;
+ return nRet + pImp->aStack.Count();
+ }
+
+ return USHRT_MAX;
+}
+
+//--------------------------------------------------------------------
+SfxShell *SfxDispatcher::GetShell(sal_uInt16 nIdx) const
+
+/* [Beschreibung]
+
+ Liefert einen Pointer auf die <SfxShell>, welche sich an der Position
+ nIdx (von oben, letzt-gepushte liegt bei 0) auf dem Stack befindet.
+
+ Dabei wird der SfxDispatcher nicht geflusht.
+
+ Ist der Stack nicht tief genug, wird ein 0-Pointer zur"uckgegeben.
+*/
+
+{
+ DBG_MEMTEST();
+
+ sal_uInt16 nShellCount = pImp->aStack.Count();
+ if ( nIdx < nShellCount )
+ return pImp->aStack.Top(nIdx);
+ else if ( pImp->pParent )
+ return pImp->pParent->GetShell( nIdx - nShellCount );
+ return 0;
+}
+
+//--------------------------------------------------------------------
+SfxBindings* SfxDispatcher::GetBindings() const
+
+/* [Beschreibung]
+
+ Diese Methode liefert einen Pointer auf die <SfxBindings> Instanz
+ zur"uck, an die der SfxDispatcher gerade gebunden ist. Ein SfxDispatcher
+ ist nur dann an SfxBindings gebunden, wenn er <UI-aktiv> ist. Ist
+ er nicht UI-aktiv, wird ein 0-Pointer zur"uckgegeben.
+
+ Der zur"uckgegebene Pointer ist nur im <unmittelbaren Kontext> des
+ Methodenaufrufs g"ultig.
+*/
+
+{
+ if ( pImp->pFrame )
+ return &pImp->pFrame->GetBindings();
+ else
+ return NULL;
+}
+
+//--------------------------------------------------------------------
+SfxViewFrame* SfxDispatcher::GetFrame() const
+
+/* [Beschreibung]
+
+ Liefert einen Pointer auf die <SfxViewFrame> Instanz, der dieser
+ SfxDispatcher geh"ort. Falls es sich um den Applikations-Dispatcher
+ handelt, wird ein 0-Pointer zur"uckgegeben.
+*/
+
+{
+ DBG_MEMTEST();
+ return pImp->pFrame;
+}
+
+//--------------------------------------------------------------------
+void SfxDispatcher::DoActivate_Impl( sal_Bool bMDI, SfxViewFrame* /* pOld */ )
+
+/* [Beschreibung]
+
+ Diese Methode steuert das Aktivieren eines Dispatchers.
+
+ Da der Applikations-Dispatcher immer aktiv ist, entweder als
+ Unterdispatcher des <SfxViewFrame>-Dispatchers oder selbst, wird
+ er nie als ganzes Aktiviert, sondern nur seine einzelnen <SfxShell>s
+ bei <SfxDispatcher::Push(SfxShell&)>.
+
+ Beim Aktivieren eines SfxDispatchers wird an allen auf seinem
+ Stack befindlichen SfxShells, beginnend mit der untersten, der Handler
+ <SfxShell::Activate(sal_Bool)> gerufen.
+*/
+
+{
+ DBG_MEMTEST();
+ SFX_STACK(SfxDispatcher::DoActivate);
+ if ( bMDI )
+ {
+ #ifdef DBG_UTIL
+ ByteString sTemp("Activate Dispatcher ");
+ sTemp += ByteString::CreateFromInt64( (sal_uIntPtr) this );
+ DBG_TRACE(sTemp.GetBuffer());
+ DBG_ASSERT( !pImp->bActive, "Activate-Fehler" );
+ #endif
+ pImp->bActive = sal_True;
+ pImp->bUpdated = sal_False;
+ SfxBindings* pBindings = GetBindings();
+ if ( pBindings )
+ {
+ pBindings->SetDispatcher(this);
+ pBindings->SetActiveFrame( pImp->pFrame->GetFrame().GetFrameInterface() );
+ }
+ }
+ else
+ {
+ #ifdef DBG_UTIL
+ ByteString sTemp("Non-MDI-Activate Dispatcher");
+ sTemp += ByteString::CreateFromInt64( (sal_uIntPtr) this );
+ DBG_TRACE( sTemp.GetBuffer() );
+ #endif
+ }
+
+ if ( IsAppDispatcher() )
+ return;
+
+ for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
+ pImp->aStack.Top( (sal_uInt16) i )->DoActivate_Impl(pImp->pFrame, bMDI);
+
+ if ( bMDI && pImp->pFrame )
+ {
+ //SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
+ SfxBindings *pBind = GetBindings();
+ while ( pBind )
+ {
+ pBind->HidePopupCtrls_Impl( FALSE );
+ pBind = pBind->GetSubBindings_Impl();
+ }
+
+ pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( FALSE, FALSE, 1 );
+ }
+
+ if ( pImp->aToDoStack.Count() )
+ {
+ if (sal_True)
+ {
+ // Kein sofortiges Update gewuenscht
+ pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
+ pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
+ pImp->aTimer.Start();
+ }
+ else
+ {
+ // Schnellstmoegliches Update (sollte Normalfall sein)
+ pImp->aTimer.Stop();
+ GetpApp()->PostUserEvent(pImp->nEventId, (void*)0);
+ }
+ }
+}
+
+void SfxDispatcher::DoParentActivate_Impl()
+{
+ for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
+ pImp->aStack.Top( (sal_uInt16) i )->ParentActivate();
+}
+
+//--------------------------------------------------------------------
+void SfxDispatcher::DoDeactivate_Impl( sal_Bool bMDI, SfxViewFrame* pNew )
+
+/* [Beschreibung]
+
+ Diese Methode steuert das Deaktivieren eines Dispatchers.
+
+ Da der Applikations-Dispatcher immer aktiv ist, entweder als
+ Unterdispatcher des <SfxViewFrame>-Dispatchers oder selbst, wird
+ er nie als ganzes Deaktiviert, sondern nur seine einzelnen <SfxShell>s
+ bei <SfxDispatcher::Pop(SfxShell&)>.
+
+ Beim Deaktivieren eines SfxDispatchers wird an allen auf seinem
+ Stack befindlichen SfxShells, beginnend mit der obersten, der Handler
+ <SfxShell::Deactivate(sal_Bool)> gerufen.
+*/
+
+{
+ DBG_MEMTEST();
+ SFX_STACK(SfxDispatcher::DoDeactivate);
+
+ SfxApplication *pSfxApp = SFX_APP();
+
+ if ( bMDI )
+ {
+ DBG_TRACE(ByteString("Deactivate Dispatcher ").Append(ByteString::CreateFromInt64( (sal_uIntPtr) this )).GetBuffer());
+ DBG_ASSERT( pImp->bActive, "Deactivate-Fehler" );
+ pImp->bActive = sal_False;
+
+ if ( pImp->pFrame && !(pImp->pFrame->GetObjectShell()->IsInPlaceActive() ) )
+ {
+ SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
+ if ( pWorkWin )
+ {
+ for (sal_uInt16 n=0; n<pImp->aChildWins.Count();)
+ {
+ SfxChildWindow *pWin = pWorkWin->GetChildWindow_Impl( (sal_uInt16) ( pImp->aChildWins[n] & 0xFFFF ) );
+ if (!pWin || (pWin && pWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT))
+ pImp->aChildWins.Remove(n);
+ else
+ n++;
+ }
+ }
+ }
+ }
+ else {
+ DBG_TRACE( ByteString ("Non-MDI-DeActivate Dispatcher").Append(ByteString::CreateFromInt64( (sal_uIntPtr) this )).GetBuffer() );
+ }
+
+ if ( IsAppDispatcher() && !pSfxApp->IsDowning() )
+ return;
+
+ for ( sal_uInt16 i = 0; i < pImp->aStack.Count(); ++i )
+ pImp->aStack.Top(i)->DoDeactivate_Impl(pImp->pFrame, bMDI);
+
+ BOOL bHidePopups = bMDI && pImp->pFrame;
+ if ( pNew && pImp->pFrame )
+ {
+ com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xOldFrame(
+ pNew->GetFrame().GetFrameInterface()->getCreator(), com::sun::star::uno::UNO_QUERY );
+
+ com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xMyFrame(
+ GetFrame()->GetFrame().GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
+
+ if ( xOldFrame == xMyFrame )
+ bHidePopups = FALSE;
+ }
+
+ if ( bHidePopups )
+ {
+ //SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
+ SfxBindings *pBind = GetBindings();
+ while ( pBind )
+ {
+ pBind->HidePopupCtrls_Impl( TRUE );
+ pBind = pBind->GetSubBindings_Impl();
+ }
+
+ pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( TRUE, FALSE, 1 );
+ }
+
+ Flush();
+}
+
+void SfxDispatcher::DoParentDeactivate_Impl()
+{
+ for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
+ pImp->aStack.Top( (sal_uInt16) i )->ParentDeactivate();
+}
+
+//--------------------------------------------------------------------
+int SfxDispatcher::GetShellAndSlot_Impl
+(
+ sal_uInt16 nSlot, // die zu suchende Slot-Id
+ SfxShell** ppShell, // die SfxShell, welche nSlot z.Zt. bedient
+ const SfxSlot** ppSlot, // der SfxSlot, welcher nSlot z.Zt. bedient
+ sal_Bool bOwnShellsOnly,
+ sal_Bool bModal, // trotz ModalMode
+ sal_Bool bRealSlot
+)
+
+/* [Beschreibung]
+
+ Diese Methode sucht im SfxDispatcher nach der <SfxShell>, von der
+ die Slot-Id nSlot zur Zeit bedient wird. Dazu wird der Dispatcher
+ zuvor geflusht.
+
+
+ [R"uckgabewert]
+
+ int sal_True
+ Die SfxShell wurde gefunden, ppShell und ppSlot
+ sind g"ultig.
+
+ sal_True
+ Die SfxShell wurde nicht gefunden, ppShell und ppSlot
+ sind ung"ultig.
+*/
+
+{
+ SFX_STACK(SfxDispatcher::GetShellAndSlot_Impl);
+
+ Flush();
+ SfxSlotServer aSvr;
+ if ( _FindServer(nSlot, aSvr, bModal) )
+ {
+ if ( bOwnShellsOnly && aSvr.GetShellLevel() >= pImp->aStack.Count() )
+ return sal_False;
+
+ *ppShell = GetShell(aSvr.GetShellLevel());
+ *ppSlot = aSvr.GetSlot();
+ if ( 0 == (*ppSlot)->GetExecFnc() && bRealSlot )
+ *ppSlot = (*ppShell)->GetInterface()->GetRealSlot(*ppSlot);
+ // Check only real slots as enum slots don't have an execute function!
+ if ( bRealSlot && ((0 == *ppSlot) || (0 == (*ppSlot)->GetExecFnc()) ))
+ return sal_False;
+
+#ifdef DBG_UTILx
+ ByteString aMsg( nSlot );
+ aMsg += " found in ";
+ aMsg += (*ppShell)->GetInterface()->GetClassName();
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+
+ return sal_True;
+ }
+
+#ifdef DBG_UTILx
+ ByteString aMsg( nSlot );
+ aMsg += " not found";
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+
+ return sal_False;
+}
+
+/*
+struct Executer : public SfxHint
+{
+ SfxRequest *pRequest;
+ const SfxSlot* pSlot;
+ sal_uInt16 nLevel;
+
+ Executer( SfxRequest* pReq, const SfxSlot* p, sal_uInt16 n )
+ : pRequest( pReq )
+ , pSlot(p)
+ , nLevel(n)
+ {}
+ ~Executer()
+ {delete pRequest;}
+};
+*/
+
+//--------------------------------------------------------------------
+void SfxDispatcher::_Execute
+(
+ SfxShell& rShell, // zu rufende <SfxShell>
+ const SfxSlot& rSlot, // zu rufender <SfxSlot>
+ SfxRequest& rReq, // auszuf"uhrende Funktion (Id und optional Parameter)
+ SfxCallMode eCallMode // synchron, asynchron oder wie beim Slot angegeben
+)
+
+/* [Beschreibung]
+
+ Diese Methode f"uhrt einen Request "uber einen gecachten <Slot-Server>
+ aus.
+*/
+
+{
+ DBG_MEMTEST();
+ DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
+ DBG_ASSERT( !pImp->aToDoStack.Count(), "unprepared InPlace _Execute" );
+
+ if ( IsLocked( rSlot.GetSlotId() ) )
+ return;
+
+ sal_uInt16 nSlot = rSlot.GetSlotId();
+ if ( SfxMacroConfig::IsMacroSlot( nSlot ) )
+ SFX_APP()->GetMacroConfig()->RegisterSlotId( nSlot );
+
+ if ( (eCallMode & SFX_CALLMODE_ASYNCHRON) ||
+ ( !(eCallMode & SFX_CALLMODE_SYNCHRON) &&
+ rSlot.IsMode(SFX_SLOT_ASYNCHRON) ) )
+ {
+ SfxDispatcher *pDispat = this;
+ while ( pDispat )
+ {
+ sal_uInt16 nShellCount = pDispat->pImp->aStack.Count();
+ for ( sal_uInt16 n=0; n<nShellCount; n++ )
+ {
+ if ( &rShell == pDispat->pImp->aStack.Top(n) )
+ {
+ if ( eCallMode & SFX_CALLMODE_RECORD )
+ rReq.AllowRecording( TRUE );
+ pDispat->pImp->xPoster->Post(new SfxRequest(rReq));
+// pDispat->pImp->xPoster->Post(new Executer(new SfxRequest(rReq), &rSlot, n ));
+ return;
+ }
+ }
+
+ pDispat = pDispat->pImp->pParent;
+ }
+ }
+ else
+ Call_Impl( rShell, rSlot, rReq, SFX_CALLMODE_RECORD==(eCallMode&SFX_CALLMODE_RECORD) );
+}
+
+//--------------------------------------------------------------------
+void MappedPut_Impl( SfxAllItemSet &rSet, const SfxPoolItem &rItem )
+
+/* [Beschreibung]
+
+ Hilfsfunktion zum putten von rItem unter der im Pool des Item-Sets
+ rSet geltenden Which-Id.
+*/
+
+{
+ // mit ggf. gemappter Which-Id putten
+ const SfxItemPool *pPool = rSet.GetPool();
+ sal_uInt16 nWhich = rItem.Which();
+#ifdef TF_POOLABLE
+ if ( pPool->IsSlot(nWhich) )
+#else
+ if ( pPool->HasMap() && pPool->IsSlot(nWhich) )
+#endif
+ nWhich = pPool->GetWhich(nWhich);
+ rSet.Put( rItem, nWhich );
+}
+
+//--------------------------------------------------------------------
+
+#ifndef SFX_USE_BINDINGS
+#define SFX_USE_BINDINGS 0x8000
+#endif
+
+sal_uInt16 SfxDispatcher::ExecuteFunction( sal_uInt16 nSlot, SfxPoolItem **pArgs,
+ sal_uInt16 nMode )
+{
+ if ( !nMode )
+ nMode = pImp->nStandardMode;
+
+ // via Bindings/Interceptor? (dann ist der Returnwert nicht exakt)
+ sal_Bool bViaBindings = SFX_USE_BINDINGS == ( nMode & SFX_USE_BINDINGS );
+ nMode &= ~sal_uInt16(SFX_USE_BINDINGS);
+ if ( bViaBindings && GetBindings() )
+ return GetBindings()->Execute( nSlot, (const SfxPoolItem **) pArgs, nMode )
+ ? EXECUTE_POSSIBLE
+ : EXECUTE_NO;
+
+ // sonst via Dispatcher
+ if ( IsLocked(nSlot) )
+ return 0;
+ SfxShell *pShell = 0;
+ SfxCallMode eCall = SFX_CALLMODE_SYNCHRON;
+ sal_uInt16 nRet = EXECUTE_NO;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False, sal_False ) )
+ {
+ // Ausf"uhrbarkeit vorher testen
+ if ( pSlot->IsMode( SFX_SLOT_FASTCALL ) ||
+ pShell->CanExecuteSlot_Impl( *pSlot ) )
+ nRet = EXECUTE_POSSIBLE;
+
+ if ( nMode == EXECUTEMODE_ASYNCHRON )
+ eCall = SFX_CALLMODE_ASYNCHRON;
+ else if ( nMode == EXECUTEMODE_DIALOGASYNCHRON && pSlot->IsMode( SFX_SLOT_HASDIALOG ) )
+ eCall = SFX_CALLMODE_ASYNCHRON;
+ else if ( pSlot->GetMode() & SFX_SLOT_ASYNCHRON )
+ eCall = SFX_CALLMODE_ASYNCHRON;
+ sal_Bool bDone = sal_False;
+ if ( pArgs && *pArgs )
+ {
+ SfxAllItemSet aSet( pShell->GetPool() );
+ for ( SfxPoolItem **pArg = pArgs; *pArg; ++pArg )
+ MappedPut_Impl( aSet, **pArg );
+ SfxRequest aReq( nSlot, eCall, aSet );
+ _Execute( *pShell, *pSlot, aReq, eCall );
+ bDone = aReq.IsDone();
+ }
+ else
+ {
+ SfxRequest aReq( nSlot, eCall, pShell->GetPool() );
+ _Execute( *pShell, *pSlot, aReq, eCall );
+ bDone = aReq.IsDone();
+ }
+ }
+
+ return nRet;
+}
+
+sal_uInt16 SfxDispatcher::ExecuteFunction( sal_uInt16 nSlot, const SfxItemSet& rArgs,
+ sal_uInt16 nMode )
+{
+ if ( !nMode )
+ nMode = pImp->nStandardMode;
+
+/*
+ // at the moment not implemented
+ // via Bindings/Interceptor? (dann ist der Returnwert nicht exakt)
+ sal_Bool bViaBindings = SFX_USE_BINDINGS == ( nMode & SFX_USE_BINDINGS );
+ nMode &= ~sal_uInt16(SFX_USE_BINDINGS);
+ if ( bViaBindings && GetBindings() )
+ return GetBindings()->Execute( nSlot, rArgs, nMode )
+ ? EXECUTE_POSSIBLE
+ : EXECUTE_NO;
+*/
+ // sonst via Dispatcher
+ if ( IsLocked(nSlot) )
+ return 0;
+ SfxShell *pShell = 0;
+ SfxCallMode eCall = SFX_CALLMODE_SYNCHRON;
+ sal_uInt16 nRet = EXECUTE_NO;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False, sal_False ) )
+ {
+ // Ausf"uhrbarkeit vorher testen
+ if ( pSlot->IsMode( SFX_SLOT_FASTCALL ) ||
+ pShell->CanExecuteSlot_Impl( *pSlot ) )
+ nRet = EXECUTE_POSSIBLE;
+
+ if ( nMode == EXECUTEMODE_ASYNCHRON )
+ eCall = SFX_CALLMODE_ASYNCHRON;
+ else if ( nMode == EXECUTEMODE_DIALOGASYNCHRON && pSlot->IsMode( SFX_SLOT_HASDIALOG ) )
+ eCall = SFX_CALLMODE_ASYNCHRON;
+ else if ( pSlot->GetMode() & SFX_SLOT_ASYNCHRON )
+ eCall = SFX_CALLMODE_ASYNCHRON;
+ sal_Bool bDone = sal_False;
+ SfxRequest aReq( nSlot, eCall, rArgs );
+ _Execute( *pShell, *pSlot, aReq, eCall );
+ bDone = aReq.IsDone();
+ }
+
+ return nRet;
+}
+
+sal_uInt16 SfxDispatcher::GetSlotId( const String& rCommand )
+{
+ const SfxSlot *pSlot = GetSlot( rCommand );
+ if ( pSlot )
+ return pSlot->GetSlotId();
+ return 0;
+}
+
+const SfxSlot* SfxDispatcher::GetSlot( const String& rCommand )
+{
+ // Anzahl der Shells auf den verkettenten Dispatchern z"ahlen
+ Flush();
+ sal_uInt16 nTotCount = pImp->aStack.Count();
+ if ( pImp->pParent )
+ {
+ SfxDispatcher *pParent = pImp->pParent;
+ while ( pParent )
+ {
+ nTotCount = nTotCount + pParent->pImp->aStack.Count();
+ pParent = pParent->pImp->pParent;
+ }
+ }
+
+ const SfxSlot *pSlot=NULL;
+ sal_uInt16 nFirstShell = 0;
+ for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
+ {
+ SfxShell *pObjShell = GetShell(i);
+ SfxInterface *pIFace = pObjShell->GetInterface();
+ pSlot = pIFace->GetSlot( rCommand );
+ if ( pSlot )
+ return pSlot;
+ }
+
+ return 0;
+}
+
+//--------------------------------------------------------------------
+int SfxExecuteItem::operator==( const SfxPoolItem& rItem ) const
+{
+ SfxExecuteItem& rArg = (SfxExecuteItem& )rItem;
+ sal_uInt16 nCount = Count();
+ if( nCount != rArg.Count() )
+ return sal_False;
+ while( nCount -- )
+ if( *GetObject( nCount ) != *rArg.GetObject( nCount ) )
+ return sal_False;
+ return eCall == rArg.eCall;
+}
+
+//--------------------------------------------------------------------
+SfxPoolItem* SfxExecuteItem::Clone( SfxItemPool* ) const
+{
+ return new SfxExecuteItem( *this );
+}
+
+//--------------------------------------------------------------------
+SfxExecuteItem::SfxExecuteItem( const SfxExecuteItem& rArg )
+ : SfxItemPtrArray(), SfxPoolItem( rArg ), nModifier( 0 )
+{
+ eCall = rArg.eCall;
+ nSlot = rArg.nSlot;
+ sal_uInt16 nCount = rArg.Count();
+ for( sal_uInt16 nPos = 0; nPos < nCount; nPos++ )
+ Insert( rArg[ nPos ]->Clone(), nPos );
+}
+
+//--------------------------------------------------------------------
+SfxExecuteItem::SfxExecuteItem(
+ sal_uInt16 nWhichId, sal_uInt16 nSlotP, SfxCallMode eModeP,
+ const SfxPoolItem* pArg1, ... ) :
+ SfxPoolItem( nWhichId ), nSlot( nSlotP ), eCall( eModeP ), nModifier( 0 )
+{
+ va_list pVarArgs;
+ va_start( pVarArgs, pArg1 );
+ for ( const SfxPoolItem *pArg = pArg1; pArg;
+ pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
+ Insert( pArg->Clone(), Count() );
+ va_end(pVarArgs);
+}
+
+//--------------------------------------------------------------------
+SfxExecuteItem::SfxExecuteItem(
+ sal_uInt16 nWhichId, sal_uInt16 nSlotP, SfxCallMode eModeP )
+ : SfxPoolItem( nWhichId ), nSlot( nSlotP ), eCall( eModeP ), nModifier( 0 )
+{
+}
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxDispatcher::Execute( const SfxExecuteItem& rItem )
+{
+ const SfxPoolItem** pPtr = new const SfxPoolItem*[ rItem.Count() + 1 ];
+ for( sal_uInt16 nPos = rItem.Count(); nPos--; )
+ pPtr[ nPos ] = rItem.GetObject( nPos );
+ pPtr[ rItem.Count() ] = 0;
+ const SfxPoolItem* pRet = Execute(
+ rItem.GetSlot(), rItem.GetCallMode(), pPtr, rItem.GetModifier() );
+
+ delete [] (SfxPoolItem**)pPtr;
+
+ return pRet;
+}
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxDispatcher::Execute(
+ USHORT nSlot,
+ SfxCallMode nCall,
+ SfxItemSet* pArgs,
+ SfxItemSet* pInternalArgs,
+ USHORT nModi)
+{
+ if ( IsLocked(nSlot) )
+ return 0;
+
+ SfxShell *pShell = 0;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
+ SFX_CALLMODE_MODAL==(nCall&SFX_CALLMODE_MODAL) ) )
+ {
+ SfxAllItemSet aSet( pShell->GetPool() );
+ if ( pArgs )
+ {
+ SfxItemIter aIter(*pArgs);
+ for ( const SfxPoolItem *pArg = aIter.FirstItem();
+ pArg;
+ pArg = aIter.NextItem() )
+ MappedPut_Impl( aSet, *pArg );
+ }
+ SfxRequest aReq( nSlot, nCall, aSet );
+ if (pInternalArgs)
+ aReq.SetInternalArgs_Impl( *pInternalArgs );
+ aReq.SetModifier( nModi );
+
+ _Execute( *pShell, *pSlot, aReq, nCall );
+ return aReq.GetReturnValue();
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxDispatcher::Execute
+(
+ sal_uInt16 nSlot, // die Id der auszufuehrenden Funktion
+ SfxCallMode eCall, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
+ const SfxPoolItem **pArgs, // 0-terminiertes C-Array von Parametern
+ sal_uInt16 nModi,
+ const SfxPoolItem **pInternalArgs // 0-terminiertes C-Array von Parametern
+)
+
+/* [Beschreibung]
+
+ Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
+
+
+ [R"uckgabewert]
+
+ const SfxPoolItem* Pointer auf ein bis zum n"achsten Durchlauf
+ der Message-Loop g"ultiges SfxPoolItem,
+ welches den R"uckgabewert enth"alt.
+
+ Oder ein 0-Pointer, wenn die Funktion nicht
+ ausgef"uhrt wurde (z.B. Abbruch durch den
+ Benutzer).
+*/
+
+{
+ if ( IsLocked(nSlot) )
+ return 0;
+
+ SfxShell *pShell = 0;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
+ SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
+ {
+ SfxRequest* pReq;
+ if ( pArgs && *pArgs )
+ {
+ SfxAllItemSet aSet( pShell->GetPool() );
+ for ( const SfxPoolItem **pArg = pArgs; *pArg; ++pArg )
+ MappedPut_Impl( aSet, **pArg );
+ pReq = new SfxRequest( nSlot, eCall, aSet );
+ }
+ else
+ pReq = new SfxRequest( nSlot, eCall, pShell->GetPool() );
+ pReq->SetModifier( nModi );
+ if( pInternalArgs && *pInternalArgs)
+ {
+ SfxAllItemSet aSet( SFX_APP()->GetPool() );
+ for ( const SfxPoolItem **pArg = pInternalArgs; *pArg; ++pArg )
+ aSet.Put( **pArg );
+ pReq->SetInternalArgs_Impl( aSet );
+ }
+ _Execute( *pShell, *pSlot, *pReq, eCall );
+ const SfxPoolItem* pRet = pReq->GetReturnValue();
+ delete pReq; return pRet;
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxDispatcher::Execute
+(
+ sal_uInt16 nSlot, // die Id der auszufuehrenden Funktion
+ SfxCallMode eCall, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
+ const SfxItemSet &rArgs // <SfxItemSet> mit Parametern
+)
+
+/* [Beschreibung]
+
+ Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
+
+
+ [R"uckgabewert]
+
+ const SfxPoolItem* Pointer auf ein bis zum n"achsten Durchlauf
+ der Message-Loop g"ultiges SfxPoolItem,
+ welches den R"uckgabewert enth"alt.
+
+ Oder ein 0-Pointer, wenn die Funktion nicht
+ ausgef"uhrt wurde (z.B. Abbruch durch den
+ Benutzer).
+*/
+
+{
+ return Execute( nSlot, eCall, 0, rArgs );
+}
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxDispatcher::Execute
+(
+ USHORT nSlot,
+ SfxCallMode eCall,
+ USHORT nModi,
+ const SfxItemSet &rArgs
+)
+{
+ if ( IsLocked(nSlot) )
+ return 0;
+
+ SfxShell *pShell = 0;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
+ SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
+ {
+ SfxAllItemSet aSet( pShell->GetPool() );
+ SfxItemIter aIter(rArgs);
+ for ( const SfxPoolItem *pArg = aIter.FirstItem();
+ pArg;
+ pArg = aIter.NextItem() )
+ MappedPut_Impl( aSet, *pArg );
+ SfxRequest aReq( nSlot, eCall, aSet );
+ aReq.SetModifier( nModi );
+ _Execute( *pShell, *pSlot, aReq, eCall );
+ return aReq.GetReturnValue();
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxDispatcher::_Execute
+(
+ sal_uInt16 nSlot, // die Id der auszufuehrenden Funktion
+ SfxCallMode eCall, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
+ va_list pVarArgs, // Parameterliste ab 2. Parameter
+ const SfxPoolItem* pArg1 // erster Parameter
+)
+
+/* [Beschreibung]
+
+ Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
+
+
+ [R"uckgabewert]
+
+ const SfxPoolItem* Pointer auf ein bis zum n"achsten Durchlauf
+ der Message-Loop g"ultiges SfxPoolItem,
+ welches den R"uckgabewert enth"alt.
+
+ Oder ein 0-Pointer, wenn die Funktion nicht
+ ausgef"uhrt wurde (z.B. Abbruch durch den
+ Benutzer).
+*/
+
+{
+ if ( IsLocked(nSlot) )
+ return 0;
+
+ SfxShell *pShell = 0;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
+ SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
+ {
+ SfxAllItemSet aSet( pShell->GetPool() );
+
+ for ( const SfxPoolItem *pArg = pArg1;
+ pArg;
+ pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
+ MappedPut_Impl( aSet, *pArg );
+
+ SfxRequest aReq( nSlot, eCall, aSet );
+ _Execute( *pShell, *pSlot, aReq, eCall );
+ return aReq.GetReturnValue();
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxDispatcher::Execute
+(
+ sal_uInt16 nSlot, // die Id der auszufuehrenden Funktion
+ SfxCallMode eCall, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
+ const SfxPoolItem* pArg1, // erster Parameter
+ ... // 0-terminiertes Liste Parametern
+)
+
+/* [Beschreibung]
+
+ Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
+
+
+ [Anmerkung]
+
+ Die Parameter werden kopiert, k"onnen daher als Adresse von
+ Stack-Objekten "ubergeben werden.
+
+
+ [R"uckgabewert]
+
+ const SfxPoolItem* Pointer auf ein bis zum n"achsten Durchlauf
+ der Message-Loop g"ultiges SfxPoolItem,
+ welches den R"uckgabewert enth"alt.
+
+ Oder ein 0-Pointer, wenn die Funktion nicht
+ ausgef"uhrt wurde (z.B. Abbruch durch den
+ Benutzer).
+
+
+ [Beispiel]
+
+ pDispatcher->Execute( SID_OPENDOCUMENT, SFX_CALLMODE_SYNCHRON,
+ &SfxStringItem( SID_FILE_NAME, "\\tmp\\temp.sdd" ),
+ &SfxStringItem( SID_FILTER_NAME, "StarDraw Presentation" ),
+ &SfxBoolItem( SID_DOC_READONLY, sal_False ),
+ 0L );
+*/
+
+{
+ if ( IsLocked(nSlot) )
+ return 0;
+
+ SfxShell *pShell = 0;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
+ SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
+ {
+ SfxAllItemSet aSet( pShell->GetPool() );
+
+ va_list pVarArgs;
+ va_start( pVarArgs, pArg1 );
+ for ( const SfxPoolItem *pArg = pArg1;
+ pArg;
+ pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
+ MappedPut_Impl( aSet, *pArg );
+ va_end(pVarArgs);
+
+ SfxRequest aReq( nSlot, eCall, aSet );
+ _Execute( *pShell, *pSlot, aReq, eCall );
+ return aReq.GetReturnValue();
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------
+
+IMPL_LINK( SfxDispatcher, PostMsgHandler, SfxRequest*, pReq )
+
+/* [Beschreibung]
+
+ Hilfsmethode zum Empfangen der asynchron auszuf"uhrenden <SfxRequest>s.
+*/
+
+{
+ DBG_MEMTEST();
+ DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
+ SFX_STACK(SfxDispatcher::PostMsgHandler);
+
+ // ist auch der Pool noch nicht gestorben?
+// SfxRequest* pReq = pExec->pRequest;
+ if ( !pReq->IsCancelled() )
+ {
+ if ( !IsLocked(pReq->GetSlot()) )
+ {
+ Flush();
+ SfxSlotServer aSvr;
+ if ( _FindServer(pReq->GetSlot(), aSvr, HACK(x) sal_True ) )
+// SfxShell *pShell = GetShell(pExec->nLevel);
+// if ( pShell && pShell->GetInterface()->GetSlot( pExec->pSlot->GetSlotId() ) )
+ {
+ const SfxSlot *pSlot = aSvr.GetSlot();
+ SfxShell *pSh = GetShell(aSvr.GetShellLevel());
+
+ DBG( SfxApplication *pSfxApp = SFX_APP() );
+ DBG( pSfxApp->EnterAsynchronCall_Impl() );
+
+ // Wenn pSlot ein "Pseudoslot" f"ur Macros oder Verben ist, kann
+ // er im Call_Impl zerst"ort werden, also nicht mehr benutzen!
+ pReq->SetSynchronCall( sal_False );
+ Call_Impl( *pSh, *pSlot, *pReq, pReq->AllowsRecording() ); //! woher bRecord?
+// Call_Impl( *pShell, *pExec->pSlot, *pReq, sal_True ); //! woher bRecord?
+ DBG( pSfxApp->LeaveAsynchronCall_Impl() );
+ }
+
+// delete pExec;
+ }
+ else
+ {
+// pImp->xPoster->Post(pExec);
+ if ( pImp->bLocked )
+ pImp->aReqArr.Insert( new SfxRequest(*pReq), pImp->aReqArr.Count() );
+ else
+ pImp->xPoster->Post(new SfxRequest(*pReq));
+ }
+ }
+// else
+// delete pExec;
+
+ delete pReq;
+ return 0;
+}
+//--------------------------------------------------------------------
+void SfxDispatcher::EnterAction( const String& rName )
+
+// marks the beginning of a block of actions
+
+{
+ DBG_MEMTEST();
+ Flush();
+ DBG_ASSERT( pImp->aStack.Count() > 0, "EnterAction on empty dispatcher stack" );
+ if ( ++pImp->nActionLevel == 1 )
+ {
+ SfxUndoManager *pUndoMgr = GetShell(0)->GetUndoManager();
+ if ( pUndoMgr )
+ pUndoMgr->EnterListAction( rName, rName HACK(RepeatComment), 0 HACK(ID) );
+ }
+}
+//--------------------------------------------------------------------
+void SfxDispatcher::LeaveAction()
+
+// marks the end of a block of actions
+
+{
+ DBG_MEMTEST();
+ DBG_ASSERT( pImp->nActionLevel > 0, "EnterAction without LeaveAction" );
+ if ( --pImp->nActionLevel == 0 )
+ {
+ SfxUndoManager *pUndoMgr = GetShell(0)->GetUndoManager();
+ if ( pUndoMgr )
+ pUndoMgr->LeaveListAction();
+ }
+}
+
+//--------------------------------------------------------------------
+void SfxDispatcher::SetMenu_Impl()
+{
+ if ( pImp->pFrame )
+ {
+ SfxViewFrame* pTop = pImp->pFrame->GetTopViewFrame();
+ if ( pTop && pTop->GetBindings().GetDispatcher() == this )
+ {
+ SfxFrame& rFrame = pTop->GetFrame();
+ if ( rFrame.IsMenuBarOn_Impl() )
+ {
+ com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
+ com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
+ aValue >>= xLayoutManager;
+ if ( xLayoutManager.is() )
+ {
+ rtl::OUString aMenuBarURL( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ));
+ if ( !xLayoutManager->isElementVisible( aMenuBarURL ) )
+ xLayoutManager->createElement( aMenuBarURL );
+ }
+ }
+ }
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+void SfxDispatcher::Update_Impl( sal_Bool bForce )
+{
+ SFX_STACK(SfxDispatcher::Update_Impl);
+
+ Flush();
+
+ if ( !pImp->pFrame || pImp->bUILocked )
+ return;
+
+ SFX_APP(); // -Wall is this required???
+ SfxDispatcher *pDisp = this;
+ sal_Bool bUpdate = bForce;
+ while ( pDisp && pDisp->pImp->pFrame )
+ {
+ SfxWorkWindow *pWork = pDisp->pImp->pFrame->GetFrame().GetWorkWindow_Impl();
+ SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
+ if ( pAct == pDisp || pAct == this )
+ {
+ if ( !bUpdate )
+ bUpdate = !pDisp->pImp->bUpdated;
+ pDisp->pImp->bUpdated = sal_True;
+ }
+ else
+ break;
+
+ pDisp = pDisp->pImp->pParent;
+ }
+
+ if ( !bUpdate || pImp->pFrame->GetFrame().IsClosing_Impl() )
+ return;
+
+ SfxViewFrame* pTop = pImp->pFrame ? pImp->pFrame->GetTopViewFrame() : NULL;
+ sal_Bool bUIActive = pTop && pTop->GetBindings().GetDispatcher() == this;
+
+ if ( !bUIActive && pTop && GetBindings() == &pTop->GetBindings() )
+ // keep own tools internally for collecting
+ GetBindings()->GetDispatcher()->pImp->bUpdated = sal_False;
+
+ SfxBindings* pBindings = GetBindings();
+ if ( pBindings )
+ pBindings->DENTERREGISTRATIONS();
+
+ com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame = pBindings->GetActiveFrame();
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xPropSet( xFrame, com::sun::star::uno::UNO_QUERY );
+ com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )) );
+ aValue >>= xLayoutManager;
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ if ( xLayoutManager.is() )
+ xLayoutManager->lock();
+
+ sal_Bool bIsIPActive = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
+ SfxInPlaceClient *pClient = pImp->pFrame ? pImp->pFrame->GetViewShell()->GetUIActiveClient() : NULL;
+ if ( bUIActive && /* !bIsIPActive && */ ( !pClient || !pClient->IsObjectUIActive() ) )
+ SetMenu_Impl();
+
+ SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
+ SfxWorkWindow *pTaskWin = pImp->pFrame->GetTopFrame().GetWorkWindow_Impl();
+ pTaskWin->ResetStatusBar_Impl();
+
+ SfxDispatcher *pDispat = this;
+ while ( pDispat )
+ {
+ SfxWorkWindow *pWork = pDispat->pImp->pFrame->GetFrame().GetWorkWindow_Impl();
+ SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
+ if ( pAct == pDispat || pAct == this )
+ {
+ pWork->ResetObjectBars_Impl();
+ pWork->ResetChildWindows_Impl();
+ }
+
+ pDispat = pDispat->pImp->pParent;
+ }
+
+ sal_Bool bIsActive = sal_False;
+ SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
+ pDispat = this;
+ while ( pActDispat && !bIsActive )
+ {
+ if ( pDispat == pActDispat )
+ bIsActive = sal_True;
+ pActDispat = pActDispat->pImp->pParent;
+ }
+
+ _Update_Impl( bUIActive, !bIsIPActive, bIsIPActive, pTaskWin );
+ if ( bUIActive || bIsActive )
+ pWorkWin->UpdateObjectBars_Impl();
+
+ if ( pBindings )
+ pBindings->DLEAVEREGISTRATIONS();
+
+ if ( xLayoutManager.is() )
+ xLayoutManager->unlock();
+
+ return;
+}
+
+void SfxDispatcher::_Update_Impl( sal_Bool bUIActive, sal_Bool bIsMDIApp, sal_Bool bIsIPOwner, SfxWorkWindow *pTaskWin )
+{
+ SFX_APP();
+ SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
+ sal_Bool bIsActive = sal_False;
+ sal_Bool bIsTaskActive = sal_False;
+ SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
+ SfxDispatcher *pDispat = this;
+ while ( pActDispat && !bIsActive )
+ {
+ if ( pDispat == pActDispat )
+ bIsActive = sal_True;
+ pActDispat = pActDispat->pImp->pParent;
+ }
+
+ if ( pImp->pParent && !pImp->bQuiet /* && bUIActive */ )
+ pImp->pParent->_Update_Impl( bUIActive, bIsMDIApp, bIsIPOwner, pTaskWin );
+
+ for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
+ pImp->aObjBars[n].nResId = 0;
+ pImp->aChildWins.Remove(0, pImp->aChildWins.Count());
+
+ // bQuiet : own shells aren't considered for UI and SlotServer
+ // bNoUI: own Shells aren't considered fors UI
+ if ( pImp->bQuiet || pImp->bNoUI || (pImp->pFrame && pImp->pFrame->GetObjectShell()->IsPreview()) )
+ return;
+
+ sal_uInt32 nStatBarId=0;
+ SfxShell *pStatusBarShell = NULL;
+
+ SfxSlotPool* pSlotPool = &SfxSlotPool::GetSlotPool( GetFrame() );
+ sal_uInt16 nTotCount = pImp->aStack.Count();
+ for ( sal_uInt16 nShell = nTotCount; nShell > 0; --nShell )
+ {
+ SfxShell *pShell = GetShell( nShell-1 );
+ SfxInterface *pIFace = pShell->GetInterface();
+
+ // don't consider shells if "Hidden" oder "Quiet"
+ sal_Bool bReadOnlyShell = IsReadOnlyShell_Impl( nShell-1 );
+ sal_uInt16 nNo;
+ for ( nNo = 0; pIFace && nNo<pIFace->GetObjectBarCount(); ++nNo )
+ {
+ sal_uInt16 nPos = pIFace->GetObjectBarPos(nNo);
+ if ( bReadOnlyShell && !( nPos & SFX_VISIBILITY_READONLYDOC ) )
+ continue;
+
+ // check wether toolbar needs activation of a special feature
+ sal_uInt32 nFeature = pIFace->GetObjectBarFeature(nNo);
+ if ( nFeature && !pShell->HasUIFeature( nFeature ) )
+ continue;
+
+ // check for toolboxes that are exclusively for a viewer
+ if ( pImp->pFrame)
+ {
+ BOOL bViewerTbx = SFX_VISIBILITY_VIEWER == ( nPos & SFX_VISIBILITY_VIEWER );
+ SfxObjectShell* pSh = pImp->pFrame->GetObjectShell();
+ SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, sal_False );
+ BOOL bIsViewer = pItem && pItem->GetValue();
+ if ( bIsViewer != bViewerTbx )
+ continue;
+ }
+
+ // always register toolbars, allows to switch them on
+ sal_Bool bVisible = pIFace->IsObjectBarVisible(nNo);
+ if ( !bVisible )
+ nPos &= SFX_POSITION_MASK;
+
+ SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos & SFX_POSITION_MASK];
+ rBar.nMode = nPos;
+ rBar.nResId = pIFace->GetObjectBarResId(nNo).GetId();
+ const String *pName = pIFace->GetObjectBarName(nNo);
+ if ( pName )
+ rBar.aName = *pName;
+ else
+ rBar.aName.Erase();
+ rBar.pIFace = pIFace;
+
+ if ( bUIActive || bIsActive )
+ {
+ pWorkWin->SetObjectBar_Impl(
+ nPos, rBar.nResId, rBar.pIFace, &rBar.aName );
+ }
+
+ if ( !bVisible )
+ rBar.nResId = 0;
+ }
+
+ for ( nNo=0; pIFace && nNo<pIFace->GetChildWindowCount(); nNo++ )
+ {
+ sal_uInt32 nId = pIFace->GetChildWindowId(nNo);
+ const SfxSlot *pSlot = pSlotPool->GetSlot( (sal_uInt16) nId );
+ DBG_ASSERT( pSlot, "Childwindow slot missing!");
+ if ( bReadOnlyShell )
+ {
+ // only show ChildWindows if their slot is allowed for readonly documents
+ if ( pSlot && !pSlot->IsMode( SFX_SLOT_READONLYDOC ) )
+ continue;
+ }
+
+ sal_uInt32 nFeature = pIFace->GetChildWindowFeature(nNo);
+ if ( nFeature && !pShell->HasUIFeature( nFeature ) )
+ continue;
+
+ // slot decides wether a ChildWindow is shown when document is OLE server or OLE client
+ sal_uInt16 nMode = SFX_VISIBILITY_STANDARD;
+ if( pSlot )
+ {
+ if ( pSlot->IsMode(SFX_SLOT_CONTAINER) )
+ {
+ if ( pWorkWin->IsVisible_Impl( SFX_VISIBILITY_CLIENT ) )
+ nMode |= SFX_VISIBILITY_CLIENT;
+ }
+ else
+ {
+ if ( pWorkWin->IsVisible_Impl( SFX_VISIBILITY_SERVER ) )
+ nMode |= SFX_VISIBILITY_SERVER;
+ }
+ }
+
+ if ( bUIActive || bIsActive )
+ pWorkWin->SetChildWindowVisible_Impl( nId, sal_True, nMode );
+ if ( bUIActive || bIsActive || !pWorkWin->IsFloating( (sal_uInt16) ( nId & 0xFFFF ) ) )
+ pImp->aChildWins.Insert( nId, pImp->aChildWins.Count());
+ }
+
+ if ( bIsMDIApp || bIsIPOwner )
+ {
+ sal_uInt32 nId = pIFace->GetStatusBarResId().GetId();
+ if ( nId )
+ {
+ nStatBarId = nId;
+ pStatusBarShell = pShell;
+ }
+ }
+ }
+
+ for ( sal_uInt16 nPos=0; nPos<SFX_OBJECTBAR_MAX; nPos++ )
+ {
+ SfxObjectBars_Impl& rFixed = pImp->aFixedObjBars[nPos];
+ if ( rFixed.nResId )
+ {
+ SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos];
+ rBar = rFixed;
+ pWorkWin->SetObjectBar_Impl( rFixed.nMode,
+ rFixed.nResId, rFixed.pIFace, &rFixed.aName );
+ }
+ }
+
+ if ( pTaskWin && ( bIsMDIApp || bIsIPOwner ) )
+ {
+ SfxDispatcher *pActDispatcher = pTaskWin->GetBindings().GetDispatcher_Impl();
+ SfxDispatcher *pDispatcher = this;
+ while ( pActDispatcher && !bIsTaskActive )
+ {
+ if ( pDispatcher == pActDispatcher )
+ bIsTaskActive = sal_True;
+ pActDispatcher = pActDispatcher->pImp->pParent;
+ }
+
+ if ( bIsTaskActive && nStatBarId && pImp->pFrame )
+ {
+ // internal frames also may control statusbar
+ SfxBindings& rBindings = pImp->pFrame->GetBindings();
+ pImp->pFrame->GetFrame().GetWorkWindow_Impl()->SetStatusBar_Impl( nStatBarId, pStatusBarShell, rBindings );
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+void SfxDispatcher::FlushImpl()
+
+/* [Beschreibung]
+
+ Hilfsmethode zum Ausf"uhren der ausstehenden Push- und Pop-Befehle.
+*/
+
+{
+ DBG_PROFSTART(SfxDispatcherFlush);
+ DBG_MEMTEST();
+ SFX_STACK(SfxDispatcher::FlushImpl);
+
+ DBG_TRACE("Flushing dispatcher!");
+
+#ifdef DBG_UTIL
+ ByteString aMsg( "SfxDispatcher(" );
+ aMsg += ByteString::CreateFromInt64( (sal_uIntPtr) this );
+ aMsg += ")::Flush()";
+#endif
+
+ pImp->aTimer.Stop();
+
+ if ( pImp->pParent )
+ pImp->pParent->Flush();
+
+// if ( pImp->bQuiet )
+// return;
+
+ pImp->bFlushing = !pImp->bFlushing;
+ if ( !pImp->bFlushing )
+ {
+ pImp->bFlushing = sal_True;
+ DBG_PROFSTOP(SfxDispatcherFlush);
+//!
+#ifdef DBG_UTIL_MESSEHACK_AUSKOMMENT
+ DBG_ERROR( "reentering SfxDispatcher::Flush()" );
+ aMsg += " reentering, aborted";
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+ return;
+ }
+
+ SfxApplication *pSfxApp = SFX_APP();
+
+ // in der 1. Runde den echten Stack 'um'bauen
+ SfxToDoStack_Impl aToDoCopy;
+ sal_Bool bModify = sal_False;
+ short nToDo;
+ for ( nToDo = pImp->aToDoStack.Count()-1; nToDo >= 0; --nToDo )
+ {
+ bModify = sal_True;
+
+ SfxToDo_Impl aToDo( pImp->aToDoStack.Top(nToDo) );
+ if ( aToDo.bPush )
+ {
+ // tats"aechlich pushen
+ DBG_ASSERT( !pImp->aStack.Contains( aToDo.pCluster ),
+ "pushed SfxShell already on stack" );
+ pImp->aStack.Push( aToDo.pCluster );
+ aToDo.pCluster->SetDisableFlags( pImp->nDisableFlags );
+
+ // die bewegte Shell merken
+ aToDoCopy.Push( aToDo );
+ }
+ else
+ {
+ // tats"aechlich poppen
+ SfxShell* pPopped = 0;
+ FASTBOOL bFound = sal_False;
+ do
+ {
+ DBG_ASSERT( pImp->aStack.Count(), "popping from empty stack" );
+ pPopped = pImp->aStack.Pop();
+ pPopped->SetDisableFlags( 0 );
+ bFound = pPopped == aToDo.pCluster;
+
+ // die bewegte Shell merken
+ aToDoCopy.Push( SfxToDo_Impl( sal_False, aToDo.bDelete, sal_False, *pPopped) );
+ }
+ while ( aToDo.bUntil && !bFound );
+ DBG_ASSERT( bFound, "wrong SfxShell popped" );
+ }
+
+ if ( nToDo == 0 )
+ pImp->aToDoStack.Clear();
+ }
+
+ // ggf. Bindings invalidieren
+ if ( !pSfxApp->IsDowning() )
+ {
+ if ( bModify )
+ {
+ pImp->pCachedServ1 = 0;
+ pImp->pCachedServ2 = 0;
+ }
+
+ InvalidateBindings_Impl( bModify );
+ }
+
+ pImp->bFlushing = sal_False;
+ pImp->bUpdated = sal_False; // nicht nur bei bModify, falls Doc/Template-Config
+ bFlushed = sal_True;
+ DBG_TRACE("Successfully flushed dispatcher!");
+
+ // in der 2. Runde die Shells aktivieren und ggf. l"oschen
+ for ( nToDo = aToDoCopy.Count()-1; nToDo >= 0; --nToDo )
+ {
+ SfxToDo_Impl aToDo( aToDoCopy.Top(nToDo) );
+ if ( aToDo.bPush )
+ {
+ if ( pImp->bActive )
+ aToDo.pCluster->DoActivate_Impl(pImp->pFrame, sal_True);
+ }
+ else
+ if ( pImp->bActive )
+ aToDo.pCluster->DoDeactivate_Impl(pImp->pFrame, sal_True);
+ }
+ for ( nToDo = aToDoCopy.Count()-1; nToDo >= 0; --nToDo )
+ {
+ SfxToDo_Impl aToDo( aToDoCopy.Top(nToDo) );
+ if ( aToDo.bDelete ) delete aToDo.pCluster;
+ }
+ sal_Bool bAwakeBindings = aToDoCopy.Count() != 0;
+ if( bAwakeBindings )
+ aToDoCopy.Clear();
+
+ // Wenn bei Activate/Deactivate/Delete weitere Stackbewegungen erfolgt sind :
+ if (!bFlushed)
+ // falls jemand Push/Pop gerufen hat, wurde auch EnterReg gerufen!
+ FlushImpl();
+
+ if( bAwakeBindings && GetBindings() )
+ GetBindings()->DLEAVEREGISTRATIONS();
+ DBG_PROFSTOP(SfxDispatcherFlush);
+
+ for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
+ pImp->aFixedObjBars[n].nResId = 0;
+
+#ifdef DBG_UTIL
+ aMsg += " done";
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+}
+
+//--------------------------------------------------------------------
+void SfxDispatcher::SetSlotFilter
+(
+ HACK(hier muss mal ein enum rein)
+ sal_Bool bEnable, /* sal_True:
+ nur angegebene Slots enablen,
+ alle anderen disablen
+
+ sal_False:
+ die angegebenen Slots disablen,
+ alle anderen zun"achst enablen
+ */
+ sal_uInt16 nCount, // Anzahl der SIDs im folgenden Array
+ const sal_uInt16* pSIDs // sortiertes Array von 'nCount' SIDs
+)
+
+/* [Beschreibung]
+
+ Mit dieser Methode wird ein Filter gesetzt, mit dem gezielt Slots
+ enabled bzw. disabled werden k"onnen. Das "ubergebene Array mu\s
+ bis zum Dtor bzw. n"achsten <SetSlotFilter()> erhalten bleiben, es
+ wird nicht vom Dispatcher gel"oscht, es kann daher static sein.
+
+ In ReadOnly-Dokumenten kann man mit 'bEnable==2' quasi das ReadOnlyDoc
+ Flag von Slots "ubersteuern, dieser werden also wieder gefunden. Auf
+ andere Slots hat das dann keine Auswirkung.
+
+
+ [Beispiel]
+
+ gezieltes disablen der Slots 1, 2 und 3:
+
+ static sal_uInt16 __READONLY_DATA pSIDs[] = { 1, 2, 3 };
+ pDisp->SetSlotFilter( sal_False, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
+
+ nur die Slots 5, 6 und 7 zulassen:
+
+ static sal_uInt16 __READONLY_DATA pSIDs[] = { 5, 6, 7 };
+ pDisp->SetSlotFilter( sal_True, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
+
+ Filter ausschalten:
+
+ pDisp->SetSlotFilter();
+*/
+
+{
+#ifdef DBG_UTIL
+ // Array "uberpr"ufen
+ for ( sal_uInt16 n = 1; n < nCount; ++n )
+ DBG_ASSERT( pSIDs[n] > pSIDs[n-1], "SetSlotFilter: SIDs not sortet" );
+#endif
+
+ if ( pImp->pFilterSIDs )
+ pImp->pFilterSIDs = 0;
+
+ pImp->bFilterEnabling = bEnable;
+ pImp->nFilterCount = nCount;
+ pImp->pFilterSIDs = pSIDs;
+
+ GetBindings()->InvalidateAll(sal_True);
+}
+
+//--------------------------------------------------------------------
+EXTERN_C
+#if defined( PM2 ) && (!defined( CSET ) && !defined ( MTW ) && !defined( WTC ))
+int _stdcall
+#else
+#ifdef WNT
+int _cdecl
+#else
+int
+#endif
+#endif
+
+SfxCompareSIDs_Impl( const void* pSmaller, const void* pBigger )
+{
+ DBG_MEMTEST();
+ return ( (long) *((sal_uInt16*)pSmaller) ) - ( (long) *((sal_uInt16*)pBigger) );
+}
+
+//--------------------------------------------------------------------
+sal_Bool SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID ) const
+
+/* [Beschreibung]
+
+ Sucht 'nSID' in dem mit <SetSlotFilter()> gesetzten Filter und
+ liefert sal_True, falls die SID erlaubt ist, bzw. sal_False, falls sie
+ durch den Filter disabled ist.
+
+ [R"uckgabewert]
+ sal_Bool 0 => disabled
+ 1 => enabled
+ 2 => enabled even if ReadOnlyDoc
+*/
+
+{
+ // kein Filter?
+ if ( 0 == pImp->nFilterCount )
+ // => alle SIDs erlaubt
+ return sal_True;
+
+ // suchen
+ sal_Bool bFound = 0 != bsearch( &nSID, pImp->pFilterSIDs, pImp->nFilterCount,
+ sizeof(sal_uInt16), SfxCompareSIDs_Impl );
+
+ // even if ReadOnlyDoc
+ if ( 2 == pImp->bFilterEnabling )
+ return bFound ? 2 : 1;
+ // sonst je nach Negativ/Positiv Filter
+ return pImp->bFilterEnabling ? bFound : !bFound;
+}
+
+//--------------------------------------------------------------------
+sal_Bool SfxDispatcher::_TryIntercept_Impl
+(
+ sal_uInt16 nSlot, // zu suchende Slot-Id
+ SfxSlotServer& rServer, // zu f"uellende <SfxSlotServer>-Instanz
+ sal_Bool bSelf
+)
+{
+ // Eventuell geh"ort der parent auch zu einer Komponente
+ SfxDispatcher *pParent = pImp->pParent;
+ sal_uInt16 nLevels = pImp->aStack.Count();
+ while ( pParent && pParent->pImp->pFrame )
+ {
+ if ( pParent->pImp->pFrame->GetFrame().HasComponent() )
+ {
+ // Components d"urfen intercepten
+ if ( pParent->_TryIntercept_Impl( nSlot, rServer, sal_True ) )
+ {
+ // Die eigenen Shells zum Shelllevel hinzuz"ahlen
+ rServer.SetShellLevel( rServer.GetShellLevel() + nLevels );
+ return sal_True;
+ }
+ else
+ // Keine weitere Interception
+ break;
+ }
+ else
+ nLevels = nLevels + pParent->pImp->aStack.Count();
+
+ pParent = pParent->pImp->pParent;
+ }
+
+ if ( bSelf )
+ {
+ // Die ComponentViewShell befragen
+ Flush();
+ SfxShell *pObjShell = GetShell(0);
+ SfxInterface *pIFace = pObjShell->GetInterface();
+ const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
+
+ if ( pSlot )
+ {
+ rServer.SetSlot(pSlot);
+ rServer.SetShellLevel(0);
+#ifdef DBG_UTILx
+ String aMsg( nSlot );
+ aMsg += " intercepted";
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+sal_Bool SfxDispatcher::_FindServer
+(
+ sal_uInt16 nSlot, // zu suchende Slot-Id
+ SfxSlotServer& rServer, // zu f"uellnde <SfxSlotServer>-Instanz
+ sal_Bool bModal // trotz ModalMode
+)
+
+/* [Beschreibung]
+
+ Diese Hilfsmethode sucht den <Slot-Server>, der nSlot zur Zeit bedient.
+ Als Ergebnis wird rServer entsprechend gef"ullt.
+
+ Falls bekannt, kann das SfxInterface mitgegeben werden, von welchem
+ nSlot momentan bedient wird.
+
+ Vor der Suche nach nSlot wird der SfxDispatcher geflusht.
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Der Slot wurde gefunden, rServer ist g"ultig.
+
+ sal_False
+ Der Slot wird momentan nicht bedient, rServer
+ ist ung"ultig.
+*/
+
+{
+ SFX_STACK(SfxDispatcher::_FindServer);
+
+ // Dispatcher gelockt? (SID_HELP_PI trotzdem durchlassen)
+ SfxApplication *pSfxApp = SFX_APP();
+ if ( IsLocked(nSlot) )
+ {
+ pImp->bInvalidateOnUnlock = sal_True;
+ return sal_False;
+ }
+
+ // Anzahl der Shells auf den verkettenten Dispatchern z"ahlen
+ Flush();
+ sal_uInt16 nTotCount = pImp->aStack.Count();
+ if ( pImp->pParent )
+ {
+ SfxDispatcher *pParent = pImp->pParent;
+ while ( pParent )
+ {
+ nTotCount = nTotCount + pParent->pImp->aStack.Count();
+ pParent = pParent->pImp->pParent;
+ }
+ }
+
+ // Makro-Slot?
+ if ( SfxMacroConfig::IsMacroSlot( nSlot ) )
+ {
+ const SfxMacroInfo* pInfo = pSfxApp->GetMacroConfig()->GetMacroInfo(nSlot);
+ if ( pInfo )
+ {
+ const SfxSlot* pSlot = pInfo->GetSlot();
+ if ( pSlot )
+ {
+ rServer.SetShellLevel(nTotCount-1);
+ rServer.SetSlot( pSlot );
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+ }
+ // Verb-Slot?
+ else if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
+ {
+ for ( sal_uInt16 nShell = 0;; ++nShell )
+ {
+ SfxShell *pSh = GetShell(nShell);
+ if ( pSh == NULL )
+ return false;
+ if ( pSh->ISA(SfxViewShell) )
+ {
+ const SfxSlot* pSlot = pSh->GetVerbSlot_Impl(nSlot);
+ if ( pSlot )
+ {
+ rServer.SetShellLevel(nShell);
+ rServer.SetSlot( pSlot );
+ return true;
+ }
+ }
+ }
+ }
+
+ // SID gegen gesetzten Filter pr"ufen
+ sal_uInt16 nSlotEnableMode=0;
+ if ( pImp->pFrame )
+ {
+ nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
+ if ( 0 == nSlotEnableMode )
+ return sal_False;
+ }
+
+ // im Quiet-Mode nur Parent-Dispatcher
+ if ( pImp->bQuiet )
+ {
+ if ( pImp->pParent )
+ {
+ sal_Bool bRet = pImp->pParent->_FindServer( nSlot, rServer, bModal );
+ rServer.SetShellLevel
+ ( rServer.GetShellLevel() + pImp->aStack.Count() );
+ return bRet;
+ }
+ else
+ return sal_False;
+ }
+
+ sal_Bool bReadOnly = ( 2 != nSlotEnableMode && pImp->bReadOnly );
+// ( pImp->pFrame && pImp->pFrame->GetObjectShell() );
+// pImp->pFrame->GetObjectShell()->IsLoading() );
+
+ // durch alle Shells der verketteten Dispatchern von oben nach unten suchen
+#ifdef DBG_UTILx
+ String aStack( "Stack:" );
+#endif
+ sal_uInt16 nFirstShell = pImp->bModal && !bModal ? pImp->aStack.Count() : 0;
+ for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
+ {
+ SfxShell *pObjShell = GetShell(i);
+ SfxInterface *pIFace = pObjShell->GetInterface();
+ const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
+
+ if ( pSlot && pSlot->nDisableFlags && ( pSlot->nDisableFlags & pObjShell->GetDisableFlags() ) != 0 )
+ return sal_False;
+
+ if ( pSlot && !( pSlot->nFlags & SFX_SLOT_READONLYDOC ) && bReadOnly )
+ return sal_False;
+
+ if ( pSlot )
+ {
+ // Slot geh"ort zum Container?
+ FASTBOOL bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
+ FASTBOOL bIsInPlace = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
+
+ // Shell geh"ort zum Server?
+ // AppDispatcher oder IPFrame-Dispatcher
+ FASTBOOL bIsServerShell = !pImp->pFrame || bIsInPlace;
+
+ // Nat"urlich sind ServerShell-Slots auch ausf"uhrbar, wenn sie auf
+ // einem Container-Dispatcher ohne IPClient ausgef"uhrt werden sollen.
+ if ( !bIsServerShell )
+ {
+ SfxViewShell *pViewSh = pImp->pFrame->GetViewShell();
+ bIsServerShell = !pViewSh || !pViewSh->GetUIActiveClient();
+ }
+
+ // Shell geh"ort zum Container?
+ // AppDispatcher oder kein IPFrameDispatcher
+ FASTBOOL bIsContainerShell = !pImp->pFrame || !bIsInPlace;
+ // Shell und Slot passen zusammen
+ if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
+ ( !bIsContainerSlot && bIsServerShell ) ) )
+ pSlot = 0;
+ }
+
+#ifdef DBG_UTILx
+ if ( pSlot )
+ {
+ String aMsg( nSlot );
+ aMsg += " found in ";
+ aMsg += pObjShell->GetInterface()->GetClassName();
+ DbgTrace( aMsg.GetBuffer() );
+ }
+ else
+ {
+ aStack += " ";
+ aStack += pObjShell->GetInterface()->GetClassName();
+ }
+#endif
+ if ( pSlot && !IsAllowed( nSlot ) )
+ {
+ pSlot = NULL;
+ }
+
+ if ( pSlot )
+ {
+ rServer.SetSlot(pSlot);
+ rServer.SetShellLevel(i);
+ return sal_True;
+ }
+ }
+
+#ifdef DBG_UTILx
+ String aMsg( nSlot );
+ aMsg += " not found in ";
+ aMsg += aStack;
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+ return sal_False;
+}
+
+sal_Bool SfxDispatcher::HasSlot_Impl( sal_uInt16 nSlot )
+{
+ Flush();
+ sal_uInt16 nTotCount = pImp->aStack.Count();
+
+ if ( pImp->pParent && !pImp->pParent->pImp->pFrame )
+ {
+ // the last frame also uses the AppDispatcher
+ nTotCount = nTotCount + pImp->aStack.Count();
+ }
+
+ if ( SfxMacroConfig::IsMacroSlot( nSlot ) )
+ // Makro-Slot?
+ return sal_True;
+ else if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
+ {
+ // Verb-Slot?
+ for ( sal_uInt16 nShell = 0;; ++nShell )
+ {
+ SfxShell *pSh = GetShell(nShell);
+ if ( pSh == NULL )
+ return false;
+ if ( pSh->ISA(SfxViewShell) )
+ return true;
+ }
+ }
+
+ // SID gegen gesetzten Filter pr"ufen
+ sal_uInt16 nSlotEnableMode=0;
+ if ( pImp->pFrame )
+ {
+ nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
+ if ( 0 == nSlotEnableMode )
+ return sal_False;
+ }
+
+ // im Quiet-Mode nur Parent-Dispatcher
+ if ( pImp->bQuiet )
+ return sal_False;
+
+ sal_Bool bReadOnly = ( 2 != nSlotEnableMode && pImp->bReadOnly );
+// ( pImp->pFrame && pImp->pFrame->GetObjectShell());
+// pImp->pFrame->GetObjectShell()->IsLoading() );
+
+ for ( sal_uInt16 i=0 ; i < nTotCount; ++i )
+ {
+ SfxShell *pObjShell = GetShell(i);
+ SfxInterface *pIFace = pObjShell->GetInterface();
+ const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
+ if ( pSlot && pSlot->nDisableFlags && ( pSlot->nDisableFlags & pObjShell->GetDisableFlags() ) != 0 )
+ return sal_False;
+
+ if ( pSlot && !( pSlot->nFlags & SFX_SLOT_READONLYDOC ) && bReadOnly )
+ return sal_False;
+
+ if ( pSlot )
+ {
+ // Slot geh"ort zum Container?
+ FASTBOOL bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
+ FASTBOOL bIsInPlace = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
+
+ // Shell geh"ort zum Server?
+ // AppDispatcher oder IPFrame-Dispatcher
+ FASTBOOL bIsServerShell = !pImp->pFrame || bIsInPlace;
+
+ // Nat"urlich sind ServerShell-Slots auch ausf"uhrbar, wenn sie auf
+ // einem Container-Dispatcher ohne IPClient ausgef"uhrt werden sollen.
+ if ( !bIsServerShell )
+ {
+ SfxViewShell *pViewSh = pImp->pFrame->GetViewShell();
+ bIsServerShell = !pViewSh || !pViewSh->GetUIActiveClient();
+ }
+
+ // Shell geh"ort zum Container?
+ // AppDispatcher oder kein IPFrameDispatcher
+ FASTBOOL bIsContainerShell = !pImp->pFrame || !bIsInPlace;
+
+ // Shell und Slot passen zusammen
+ if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
+ ( !bIsContainerSlot && bIsServerShell ) ) )
+ pSlot = 0;
+ }
+
+ if ( pSlot && !IsAllowed( nSlot ) )
+ pSlot = NULL;
+
+ if ( pSlot )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+
+
+//--------------------------------------------------------------------
+sal_Bool SfxDispatcher::_FillState
+(
+ const SfxSlotServer& rSvr, // abzufragende <Slot-Server>
+ SfxItemSet& rState, // zu f"ullendes <SfxItemSet>
+ const SfxSlot* pRealSlot // ggf. der tats"achliche Slot
+)
+
+/* [Beschreibung]
+
+ Hilfsmethode zum Abfragen des Status des <Slot-Server>s rSvr.
+ In rState m"ussen die gew"unschten Slots-Ids (teilweise in Which-Ids
+ des betreffenden Pools umgewandelt) vorhanden sein.
+
+ Der SfxDispatcher wird vor der Abfrage geflusht.
+*/
+
+{
+ SFX_STACK(SfxDispatcher::_FillState);
+
+ DBG_PROFSTART(SfxDispatcherFillState);
+
+ const SfxSlot *pSlot = rSvr.GetSlot();
+ if ( pSlot && IsLocked( pSlot->GetSlotId() ) )
+ {
+ pImp->bInvalidateOnUnlock = sal_True;
+ DBG_PROFSTOP(SfxDispatcherFillState);
+ return sal_False;
+ }
+
+ if ( pSlot )
+ {
+ DBG_ASSERT(bFlushed, "Dispatcher not flushed after retrieving slot servers!");
+ if ( !bFlushed )
+ return FALSE;
+ // Flush();
+
+ // Objekt ermitteln und Message an diesem Objekt aufrufen
+ SfxShell *pSh = GetShell(rSvr.GetShellLevel());
+ DBG_ASSERT(pSh, "ObjektShell nicht gefunden");
+
+ SfxStateFunc pFunc;
+
+ if (pRealSlot)
+ pFunc = pRealSlot->GetStateFnc();
+ else
+ pFunc = pSlot->GetStateFnc();
+
+ pSh->CallState( pFunc, rState );
+#ifdef DBG_UTIL
+ // pr"ufen, ob IDL (SlotMap) und aktuelle Items "ubereinstimmen
+ if ( DbgIsAssertWarning() && rState.Count() )
+ {
+ SfxInterface *pIF = pSh->GetInterface();
+ SfxItemIter aIter( rState );
+ for ( const SfxPoolItem *pItem = aIter.FirstItem();
+ pItem;
+ pItem = aIter.NextItem() )
+ if ( !IsInvalidItem(pItem) && !pItem->ISA(SfxVoidItem) )
+ {
+ sal_uInt16 nSlotId = rState.GetPool()->GetSlotId(pItem->Which());
+ if ( !pItem->IsA(pIF->GetSlot(nSlotId)->GetType()->Type()) )
+ {
+ ByteString aMsg( "item-type unequal to IDL (=> no BASIC)" );
+ aMsg += "\nwith SID: ";
+ aMsg += ByteString::CreateFromInt32( nSlotId );
+ aMsg += "\nin ";
+ aMsg += pIF->GetClassName();
+ DbgOut( aMsg.GetBuffer(), DBG_OUT_ERROR, __FILE__, __LINE__);
+ }
+ }
+ }
+#endif
+
+ DBG_PROFSTOP(SfxDispatcherFillState);
+ return sal_True;
+ }
+
+ DBG_PROFSTOP(SfxDispatcherFillState);
+ return sal_False;
+}
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxDispatcher::_Execute( const SfxSlotServer &rSvr )
+
+/* [Beschreibung]
+
+ Diese Methode f"uhrt einen Request "uber einen gecachten <Slot-Server>
+ aus.
+*/
+
+{
+ const SfxSlot *pSlot = rSvr.GetSlot();
+ if ( IsLocked( pSlot->GetSlotId() ) )
+ return 0;
+
+ if ( pSlot )
+ {
+ Flush();
+
+ sal_uInt16 nSlot = pSlot->GetSlotId();
+ if ( SfxMacroConfig::IsMacroSlot( nSlot ) )
+ SFX_APP()->GetMacroConfig()->RegisterSlotId( nSlot );
+
+ if ( pSlot->IsMode(SFX_SLOT_ASYNCHRON) )
+ //! ignoriert rSvr
+ {
+ SfxShell *pShell = GetShell( rSvr.GetShellLevel() );
+ SfxDispatcher *pDispat = this;
+ while ( pDispat )
+ {
+ sal_uInt16 nShellCount = pDispat->pImp->aStack.Count();
+ for ( sal_uInt16 n=0; n<nShellCount; n++ )
+ if ( pShell == pDispat->pImp->aStack.Top(n) )
+ {
+ pDispat->pImp->xPoster->Post(
+ new SfxRequest( pSlot->GetSlotId(),
+ SFX_CALLMODE_RECORD, pShell->GetPool() ) );
+// pDispat->pImp->xPoster->Post(new Executer(
+// new SfxRequest( pSlot->GetSlotId(),
+// SFX_CALLMODE_RECORD, pShell->GetPool() ),
+// pSlot, n ));
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ // Objekt ermitteln und Message an diesem Objekt aufrufen
+ SfxShell *pSh = GetShell(rSvr.GetShellLevel());
+ SfxRequest aReq( pSlot->GetSlotId(), SFX_CALLMODE_RECORD, pSh->GetPool() );
+ if ( Call_Impl( *pSh, *pSlot, aReq, sal_True ) ) // von Bindings immer recorden
+ return aReq.GetReturnValue();
+ }
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------
+void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId,
+ Window *pWin, const Point *pPos,
+ const SfxPoolItem *, ... )
+{
+ ExecutePopup( nConfigId, pWin, pPos );
+}
+
+SfxPopupMenuManager* SfxDispatcher::Popup( sal_uInt16 nConfigId,Window *pWin, const Point *pPos )
+{
+ SfxDispatcher &rDisp = *SFX_APP()->GetDispatcher_Impl();
+ sal_uInt16 nShLevel = 0;
+ SfxShell *pSh;
+ nShLevel=0;
+
+ if ( rDisp.pImp->bQuiet )
+ {
+ nConfigId = 0;
+ nShLevel = rDisp.pImp->aStack.Count();
+ }
+
+ Window *pWindow = pWin ? pWin : rDisp.pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
+ for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
+ {
+ const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId();
+ if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) )
+ {
+ return SfxPopupMenuManager::Popup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
+ }
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------
+void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId, Window *pWin, const Point *pPos )
+{
+ SfxDispatcher &rDisp = *SFX_APP()->GetDispatcher_Impl();
+ sal_uInt16 nShLevel = 0;
+ SfxShell *pSh;
+/*
+ const SvVerbList *pVerbList = 0;
+ sal_uInt16 nMaxShellLevel = rDisp.pImp->aStack.Count();
+ for ( pSh = rDisp.GetShell(nShLevel);
+ pSh && nShLevel < nMaxShellLevel ;
+ ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
+ {
+ if ( pSh->GetVerbs() )
+ {
+ pVerbList = pSh->GetVerbs();
+ break;
+ }
+ }
+*/
+ nShLevel=0;
+ if ( rDisp.pImp->bQuiet )
+ {
+ nConfigId = 0;
+ nShLevel = rDisp.pImp->aStack.Count();
+ }
+
+ Window *pWindow = pWin ? pWin : rDisp.pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
+ for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
+ {
+ const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId();
+ if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) )
+ {
+ //SfxPopupMenuManager aPop( rResId.GetId(), *rDisp.GetBindings() );
+ //aPop.SetResMgr(rResId.GetResMgr());
+ //aPop.AddClipboardFunctions();
+ //aPop.Initialize();
+ //if ( pVerbList && pVerbList->Count() )
+ // aPop.InsertVerbs(pVerbList);
+ //aPop.RemoveDisabledEntries();
+ //aPop.Execute( pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
+ SfxPopupMenuManager::ExecutePopup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
+ return;
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+void SfxDispatcher::ExecutePopup( const ResId &rId, Window *pWin, const Point *pPos )
+{
+ Window *pWindow = pWin ? pWin : pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
+/*
+ SfxPopupMenuManager aPop( rId, *GetBindings() );
+ aPop.AddClipboardFunctions();
+ aPop.Initialize();
+ aPop.RemoveDisabledEntries();
+ aPop.Execute( pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
+*/
+ SfxPopupMenuManager::ExecutePopup( rId, GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
+}
+
+//--------------------------------------------------------------------
+void SfxDispatcher::Lock( sal_Bool bLock )
+
+/* [Beschreibung]
+
+ Mit dieser Methode kann der SfxDispatcher gesperrt und freigegeben
+ werden. Ein gesperrter SfxDispatcher f"uhrt keine <SfxRequest>s mehr
+ aus und liefert keine Status-Informationen mehr. Er verh"alt sich
+ so als w"aren alle Slots disabled.
+*/
+
+{
+ SfxBindings* pBindings = GetBindings();
+ if ( !bLock && pImp->bLocked && pImp->bInvalidateOnUnlock )
+ {
+ if ( pBindings )
+ pBindings->InvalidateAll(sal_True);
+ pImp->bInvalidateOnUnlock = sal_False;
+ }
+ else if ( pBindings )
+ pBindings->InvalidateAll(sal_False);
+ pImp->bLocked = bLock;
+ if ( !bLock )
+ {
+ USHORT nCount = pImp->aReqArr.Count();
+ for ( USHORT i=0; i<nCount; i++ )
+ pImp->xPoster->Post( pImp->aReqArr[i] );
+ pImp->aReqArr.Remove( 0, nCount );
+ }
+}
+
+sal_uInt32 SfxDispatcher::GetObjectBarId( sal_uInt16 nPos ) const
+{
+ return pImp->aObjBars[nPos].nResId;
+}
+
+//--------------------------------------------------------------------
+void SfxDispatcher::ResetObjectBars_Impl()
+
+/* [Beschreibung]
+
+ Mit dieser Methode werden alle Objectbar-Anforderungen, die dieser
+ Dispatcher an das AppWindow hat, beseitigt.
+*/
+{
+ for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
+ pImp->aObjBars[n].nResId = 0;
+ pImp->aChildWins.Remove(0, pImp->aChildWins.Count());
+}
+
+
+//--------------------------------------------------------------------
+void SfxDispatcher::DebugOutput_Impl() const
+{
+#ifdef DBG_UTIL
+
+ sal_uInt16 nOld = (sal_uInt16) DbgGetData()->nTraceOut;
+ DbgGetData()->nTraceOut = DBG_OUT_FILE;
+
+ if (bFlushed)
+ DBG_TRACE("Flushed");
+ if (pImp->bUpdated)
+ DBG_TRACE("Updated");
+
+ for ( sal_uInt16 nShell = pImp->aStack.Count(); nShell > 0; --nShell )
+ {
+ SfxShell *pShell = GetShell(nShell-1);
+ const SfxInterface *pIFace = pShell->GetInterface();
+ DBG_TRACE (pIFace->GetClassName());
+ }
+
+ DbgGetData()->nTraceOut = nOld;
+
+#endif
+}
+
+void SfxDispatcher::LockUI_Impl( sal_Bool bLock )
+{
+ sal_Bool bWasLocked = pImp->bUILocked;
+ pImp->bUILocked = bLock;
+ if ( !bLock && bWasLocked )
+ Update_Impl( sal_True );
+}
+
+//-------------------------------------------------------------------------
+void SfxDispatcher::HideUI( sal_Bool bHide )
+{
+// if ( !bHide && pImp->bReadOnly )
+// bHide = sal_True;
+ sal_Bool bWasHidden = pImp->bNoUI;
+ pImp->bNoUI = bHide;
+ if ( pImp->pFrame )
+ {
+ SfxViewFrame* pTop = pImp->pFrame->GetTopViewFrame();
+ if ( pTop && pTop->GetBindings().GetDispatcher() == this )
+ {
+ SfxFrame& rFrame = pTop->GetFrame();
+ if ( rFrame.IsMenuBarOn_Impl() )
+ {
+ com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
+ com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
+ aValue >>= xLayoutManager;
+ if ( xLayoutManager.is() )
+ xLayoutManager->setVisible( !bHide );
+ }
+ }
+ }
+ }
+
+ if ( bHide != bWasHidden )
+ Update_Impl( sal_True );
+}
+
+void SfxDispatcher::SetReadOnly_Impl( sal_Bool bOn )
+{
+ pImp->bReadOnly = bOn;
+// pImp->bNoUI = bOn;
+}
+
+sal_Bool SfxDispatcher::GetReadOnly_Impl() const
+{
+ return pImp->bReadOnly;
+}
+
+//-------------------------------------------------------------------------
+void SfxDispatcher::SetQuietMode_Impl( sal_Bool bOn )
+
+/* [Beschreibung]
+
+ Bei 'bOn' stellt sich dieser Dispatcher quasi tot und leitet alles
+ an den Parent-Dispatcher weiter.
+*/
+
+{
+ pImp->bQuiet = bOn;
+ SfxBindings* pBindings = GetBindings();
+ if ( pBindings )
+ pBindings->InvalidateAll(sal_True);
+}
+
+//-------------------------------------------------------------------------
+void SfxDispatcher::SetModalMode_Impl( sal_Bool bOn )
+
+/* [Beschreibung]
+
+ Bei 'bOn' werden nur noch Slots des Parent-Dispatchers gefunden.
+*/
+
+{
+ pImp->bModal = bOn;
+ SfxBindings* pBindings = GetBindings();
+ if ( pBindings )
+ pBindings->InvalidateAll(sal_True);
+}
+
+void SfxDispatcher::SetExecuteMode( sal_uInt16 nMode )
+{
+ pImp->nStandardMode = nMode;
+}
+
+SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSlot, const SfxPoolItem* &rpState )
+{
+ SfxShell *pShell = 0;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False, sal_False ) )
+ {
+ rpState = pShell->GetSlotState(nSlot);
+ if ( !rpState )
+ return SFX_ITEM_DISABLED;
+ else
+ return SFX_ITEM_AVAILABLE;
+ }
+
+ return SFX_ITEM_DISABLED;
+}
+
+SfxItemState SfxDispatcher::QueryState( USHORT nSID, ::com::sun::star::uno::Any& rAny )
+{
+ SfxShell *pShell = 0;
+ const SfxSlot *pSlot = 0;
+ if ( GetShellAndSlot_Impl( nSID, &pShell, &pSlot, sal_False, sal_False ) )
+ {
+ const SfxPoolItem* pItem( 0 );
+
+ pItem = pShell->GetSlotState( nSID );
+ if ( !pItem )
+ return SFX_ITEM_DISABLED;
+ else
+ {
+ ::com::sun::star::uno::Any aState;
+ if ( !pItem->ISA(SfxVoidItem) )
+ {
+ USHORT nSubId( 0 );
+ SfxItemPool& rPool = pShell->GetPool();
+ USHORT nWhich = rPool.GetWhich( nSID );
+ if ( rPool.GetMetric( nWhich ) == SFX_MAPUNIT_TWIP )
+ nSubId |= CONVERT_TWIPS;
+ pItem->QueryValue( aState, (BYTE)nSubId );
+ }
+ rAny = aState;
+
+ return SFX_ITEM_AVAILABLE;
+ }
+ }
+
+ return SFX_ITEM_DISABLED;
+}
+
+sal_Bool SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell ) const
+{
+ sal_uInt16 nShellCount = pImp->aStack.Count();
+ if ( nShell < nShellCount )
+ {
+ SfxShell* pShell = pImp->aStack.Top( nShell );
+ if( pShell->ISA( SfxModule ) || pShell->ISA( SfxApplication ) || pShell->ISA( SfxViewFrame ) )
+ return sal_False;
+ else
+ return pImp->bReadOnly;
+ }
+ else if ( pImp->pParent )
+ return pImp->pParent->IsReadOnlyShell_Impl( nShell - nShellCount );
+ return sal_True;
+}
+
+// Ein dirty trick, um an die Methoden der private base class von
+// SfxShellStack_Impl heranzukommen
+class StackAccess_Impl : public SfxShellStack_Implarr_
+{};
+
+void SfxDispatcher::InsertShell_Impl( SfxShell& rShell, sal_uInt16 nPos )
+{
+ Flush();
+
+ // Der cast geht, weil SfxShellStack_Impl keine eigenen member hat
+ ((StackAccess_Impl*) (&pImp->aStack))->Insert( nPos, &rShell );
+ rShell.SetDisableFlags( pImp->nDisableFlags );
+ rShell.DoActivate_Impl(pImp->pFrame, sal_True);
+
+ if ( !SFX_APP()->IsDowning() )
+ {
+ pImp->bUpdated = sal_False;
+ pImp->pCachedServ1 = 0;
+ pImp->pCachedServ2 = 0;
+ InvalidateBindings_Impl(sal_True);
+ }
+}
+
+void SfxDispatcher::RemoveShell_Impl( SfxShell& rShell )
+{
+ Flush();
+
+ // Der cast geht, weil SfxShellStack_Impl keine eigenen member hat
+ StackAccess_Impl& rStack = *((StackAccess_Impl*) (&pImp->aStack));
+ sal_uInt16 nCount = rStack.Count();
+ for ( sal_uInt16 n=0; n<nCount; ++n )
+ {
+ if ( rStack[n] == &rShell )
+ {
+ rStack.Remove( n );
+ rShell.SetDisableFlags( 0 );
+ rShell.DoDeactivate_Impl(pImp->pFrame, sal_True);
+ break;
+ }
+ }
+
+ if ( !SFX_APP()->IsDowning() )
+ {
+ pImp->bUpdated = sal_False;
+ pImp->pCachedServ1 = 0;
+ pImp->pCachedServ2 = 0;
+ InvalidateBindings_Impl(sal_True);
+ }
+}
+
+sal_Bool SfxDispatcher::IsAllowed
+(
+ sal_uInt16 nSlot
+) const
+/*
+ [Beschreibung]
+ Die Methode prueft, ob der Zugriff auf diese Schnittstelle erlaubt ist.
+ */
+{
+ if ( !pImp->pDisableList )
+ {
+ return sal_True;
+ }
+
+ // BinSearch in der DisableListe
+ SvUShorts& rList = *pImp->pDisableList;
+ sal_uInt16 nCount = rList.Count();
+ sal_uInt16 nLow = 0, nMid = 0, nHigh;
+ sal_Bool bFound = sal_False;
+ nHigh = nCount - 1;
+
+ while ( !bFound && nLow <= nHigh )
+ {
+ nMid = (nLow + nHigh) >> 1;
+ DBG_ASSERT( nMid < nCount, "bsearch ist buggy" );
+
+ int nDiff = (int) nSlot - (int) rList[nMid];
+ if ( nDiff < 0)
+ {
+ if ( nMid == 0 )
+ break;
+ nHigh = nMid - 1;
+ }
+ else if ( nDiff > 0 )
+ {
+ nLow = nMid + 1;
+ if ( nLow == 0 )
+ break;
+ }
+ else
+ bFound = sal_True;
+ }
+
+#ifdef _DEBUG
+ // Slot in der Liste gefunden ?
+ sal_uInt16 nPos = bFound ? nMid : nLow;
+
+ DBG_ASSERT( nPos <= nCount, "" );
+ DBG_ASSERT( nPos == nCount || nSlot <= rList[nPos], "" );
+ DBG_ASSERT( nPos == 0 || nSlot > rList[nPos-1], "" );
+ DBG_ASSERT( ( (nPos+1) >= nCount ) || nSlot < rList[nPos+1], "" );
+#endif
+
+ return !bFound;
+}
+
+void SfxDispatcher::InvalidateBindings_Impl( sal_Bool bModify )
+{
+ // App-Dispatcher?
+ if ( IsAppDispatcher() )
+ {
+ for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst();
+ pFrame;
+ pFrame = SfxViewFrame::GetNext( *pFrame ) )
+ pFrame->GetBindings().InvalidateAll(bModify);
+ }
+ else
+ {
+ SfxDispatcher *pDisp = GetBindings()->GetDispatcher_Impl();
+ while ( pDisp )
+ {
+ if ( pDisp == this )
+ {
+ GetBindings()->InvalidateAll( bModify );
+ break;
+ }
+
+ pDisp = pDisp->pImp->pParent;
+ }
+ }
+}
+
+sal_Bool SfxDispatcher::IsUpdated_Impl() const
+{
+ return pImp->bUpdated;
+}
+
+void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags )
+{
+ pImp->nDisableFlags = nFlags;
+ for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
+ pImp->aStack.Top( (sal_uInt16) i )->SetDisableFlags( nFlags );
+}
+
+sal_uInt32 SfxDispatcher::GetDisableFlags() const
+{
+ return pImp->nDisableFlags;
+}
+
+SfxModule* SfxDispatcher::GetModule() const
+{
+ for ( sal_uInt16 nShell = 0;; ++nShell )
+ {
+ SfxShell *pSh = GetShell(nShell);
+ if ( pSh == NULL )
+ return 0;
+ if ( pSh->ISA(SfxModule) )
+ return (SfxModule*) pSh;
+ }
+}