/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the 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 "sfx2/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/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_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;

	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()" );

	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( sal_False );
            pBind = pBind->GetSubBindings_Impl();
        }

        pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( sal_False, sal_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);

    sal_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 = sal_False;
    }

    if ( bHidePopups )
    {
        //SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
        SfxBindings *pBind = GetBindings();
        while ( pBind )
        {
            pBind->HidePopupCtrls_Impl( sal_True );
            pBind = pBind->GetSubBindings_Impl();
        }

        pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( sal_True, sal_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;

	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( sal_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(
    sal_uInt16 nSlot,
    SfxCallMode nCall,
    SfxItemSet* pArgs,
    SfxItemSet* pInternalArgs,
    sal_uInt16 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
(
    sal_uInt16 nSlot,
    SfxCallMode eCall,
    sal_uInt16 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::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 whether 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)
			{
				sal_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 );
				sal_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 whether 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;
			bool 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)
	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;
		}
	}

	// Verb-Slot?
	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?
			bool bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
            bool bIsInPlace = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();

			// Shell geh"ort zum Server?
			// AppDispatcher oder IPFrame-Dispatcher
			bool 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
			bool 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 (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?
			bool bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
            bool bIsInPlace = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();

            // Shell geh"ort zum Server?
			// AppDispatcher oder IPFrame-Dispatcher
			bool 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
			bool 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 sal_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();

		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 )
    {
        sal_uInt16 nCount = pImp->aReqArr.Count();
        for ( sal_uInt16 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( sal_uInt16 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) )
            {
                sal_uInt16 nSubId( 0 );
                SfxItemPool& rPool = pShell->GetPool();
                sal_uInt16 nWhich = rPool.GetWhich( nSID );
                if ( rPool.GetMetric( nWhich ) == SFX_MAPUNIT_TWIP )
                    nSubId |= CONVERT_TWIPS;
                pItem->QueryValue( aState, (sal_uInt8)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;
	}
}
