/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sfx2_dispatch.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/27 19:09:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif


#ifndef _SFXITEMPOOL_HXX //autogen
#include <svtools/itempool.hxx>
#endif
#ifndef _SFXITEMITER_HXX //autogen
#include <svtools/itemiter.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _SFXEITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>				// wg. bsearch

#define _SVSTDARR_ULONGS

#pragma hdrstop

#include "sfxhelp.hxx"
#include "appdata.hxx"
#include "dispatch.hxx"
#include "minstack.hxx"
#include "request.hxx"
#include "hintpost.hxx"
#include "slotserv.hxx"
#include "interno.hxx"
#include "sfxtypes.hxx"
#include "macrconf.hxx"
#include "virtmenu.hxx"
#include "viewsh.hxx"
#include "mnumgr.hxx"
#include "ipenv.hxx"
#include "msgpool.hxx"

#ifndef _SVTOOLS_IMGDEF_HXX
#include <svtools/imgdef.hxx>
#endif

#include "tbxconf.hxx"
#include "topfrm.hxx"
#include "cfgmgr.hxx"
#include "docfile.hxx"
namespace binfilter {

//==================================================================
/*N*/ DBG_NAME(SfxDispatcherFlush)
/*N*/ DBG_NAME(SfxDispatcherFillState)

//==================================================================
/*N*/ SV_IMPL_PTRARR( SfxItemPtrArray, SfxPoolItemPtr );

/*N*/ DECL_PTRSTACK(SfxShellStack_Impl, SfxShell*, 8, 4 );
//==================================================================

/*N*/ struct SfxToDo_Impl
/*N*/ {
/*N*/ 	SfxShell*			pCluster;
/*N*/ 	sal_Bool               	bPush;
/*N*/ 	sal_Bool				bDelete;
/*N*/ 	sal_Bool				bUntil;
/*N*/ 
/*N*/ 	SfxToDo_Impl():
/*N*/ 		bPush(sal_False), bDelete(sal_False), bUntil(sal_False), pCluster(0) {}
/*N*/ 	SfxToDo_Impl( sal_Bool bOpPush, sal_Bool bOpDelete, sal_Bool bOpUntil, SfxShell& rCluster ):
/*N*/ 		bPush(bOpPush), bDelete(bOpDelete), bUntil(bOpUntil), pCluster(&rCluster) {}
/*N*/ 	~SfxToDo_Impl(){}
/*N*/ 
/*N*/ 	sal_Bool operator==( const SfxToDo_Impl& rWith ) const
/*N*/ 	{ return pCluster==rWith.pCluster && bPush==rWith.bPush; }
/*N*/ };

/*N*/ DECL_OBJSTACK(SfxToDoStack_Impl, SfxToDo_Impl, 8, 4);
/*N*/ IMPL_OBJSTACK(SfxToDoStack_Impl, SfxToDo_Impl);

/*N*/ struct SfxObjectBars_Impl
/*N*/ {
/*N*/ 	ResId				aResId;	// Resource - und ConfigId der Toolbox
/*N*/ 	sal_uInt16				nMode;	// spezielle Sichtbarkeitsflags
/*N*/ 	String   			aName;
/*N*/ 	SfxInterface*		pIFace;
/*N*/ 
/*N*/ 	SfxObjectBars_Impl() :
/*N*/ 		aResId( 0,0 )
/*N*/ 	{}
/*N*/ };

//------------------------------------------------------------------

/*N*/ struct SfxDispatcher_Impl
/*N*/ {
/*N*/ 	const SfxSlotServer* pCachedServ1;		 // zuletzt gerufene Message
/*N*/ 	const SfxSlotServer* pCachedServ2;		 // vorletzt gerufene Message
/*N*/ 	SfxShellStack_Impl		aStack; 			// aktive Funktionalitaet
/*N*/ 	Timer					aTimer; 			// fuers flushen
/*N*/ 	SfxToDoStack_Impl		aToDoStack; 		// nicht abgearb. Push/Pop
/*N*/ 	SfxViewFrame*           pFrame;         	// 0 oder zugeh"or. Frame
/*N*/ 	SfxDispatcher*			pParent;			// z.B. AppDispatcher, ggf. 0
/*N*/ 	SfxHintPosterRef		xPoster;			// asynchrones Execute
/*N*/ 	sal_Bool                    bFlushing;      	// sal_True waehrend Flush //?
/*N*/ 	sal_Bool					bFlushed;			// aToDoStack.Count() == 0
/*N*/ 	sal_Bool					bUpdated;			// Update_Impl gelaufen
/*N*/ 	sal_Bool                    bLocked;        	// kein Execute
/*N*/ 	sal_Bool					bInvalidateOnUnlock;// da fragte jemand
/*N*/ 	sal_Bool					bActive;			// nicht verwechseln mit gesetzt!
/*N*/ 	sal_Bool*   				pInCallAliveFlag;   // dem Stack den Dtor anzeigen
/*N*/ 	SfxObjectBars_Impl		aObjBars[SFX_OBJECTBAR_MAX];
/*N*/ 	SfxObjectBars_Impl		aFixedObjBars[SFX_OBJECTBAR_MAX];
/*N*/ 	SvULongs				aChildWins;
/*N*/ 	sal_uInt16					nActionLevel;   	// in EnterAction
/*N*/ 	sal_uInt32					nEventId;			// EventId UserEvent
/*N*/ 	sal_Bool					bUILocked;			// Update abgeklemmt (!zappeln)
/*N*/ 	sal_Bool					bNoUI;				// UI nur vom Parent Dispatcher
/*N*/ 	sal_Bool					bReadOnly;			// Dokument ist ReadOnly
/*N*/ 	sal_Bool					bQuiet;             // nur parent dispatcher verwenden
/*N*/ 	sal_Bool					bModal;             // nur Slots vom Parent-Dispatcher
/*N*/ 
/*N*/ 	sal_Bool					bFilterEnabling;	// sal_True=filter enabled slots, 2==ReadOnlyDoc uebersteuert
/*N*/ 	sal_uInt16					nFilterCount;		// Anzahl der SIDs in pFilterSIDs
/*N*/ 	const sal_uInt16*			pFilterSIDs;		// sortiertes Array von SIDs
/*N*/ 	sal_uInt16					nStandardMode;		// ExecuteMode f. PlugInDispatcher
/*N*/ 	SvUShorts*				pDisableList;
/*N*/ 	sal_uInt32					nDisableFlags;
/*N*/ };

#define NO_OBJECTBAR	0
#define OWN_OBJECTBAR	1
#define OTHER_OBJECTBAR 2

//------------------------------------------------------------------

#define SFX_FLUSH_TIMEOUT    50

//====================================================================
/*N*/ sal_Bool SfxDispatcher::IsLocked( sal_uInt16 nSID ) 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.
*/

/*N*/ {
/*N*/ 	return nSID != SID_BROWSE_STOP && nSID != SID_HELP_PI &&
/*N*/ 		   ( pImp->bLocked || SFX_APP()->IsDispatcherLocked() );
/*N*/ }

//--------------------------------------------------------------------
/*N*/ 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.
*/

/*N*/ {
/*N*/     return !pImp->pFrame;
/*N*/ }

//--------------------------------------------------------------------
/*N*/ 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.
*/

/*N*/ {
/*N*/ 	SFX_STACK(SfxDispatcher::Call_Impl);
/*N*/ 
/*N*/ 	// darf der Slot gerufen werden (i.S.v. enabled)
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 	if ( rSlot.IsMode(SFX_SLOT_FASTCALL) || rShell.CanExecuteSlot_Impl(rSlot) )
/*N*/ 	{
/*N*/         if ( GetFrame() )
/*N*/         {
/*N*/             // ggf. Recording anwerfen
/*N*/             ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame(
/*N*/                     GetFrame()->GetFrame()->GetFrameInterface(),
/*N*/                     ::com::sun::star::uno::UNO_QUERY);
/*N*/ 
/*N*/             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xSet(
/*N*/                     xFrame,
/*N*/                     ::com::sun::star::uno::UNO_QUERY);
/*N*/ 
/*N*/ 			if ( xSet.is() )
/*N*/ 			{
/*N*/ 				::com::sun::star::uno::Any aProp = xSet->getPropertyValue(::rtl::OUString::createFromAscii("DispatchRecorderSupplier"));
/*N*/ 	            ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchRecorderSupplier > xSupplier;
/*N*/ 	            ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchRecorder > xRecorder;
/*N*/ 	            aProp >>= xSupplier;
/*N*/ 	            if(xSupplier.is())
/*?*/ 	                xRecorder = xSupplier->getDispatchRecorder();
/*N*/ 
/*N*/ 	            if ( bRecord && xRecorder.is() && !rSlot.IsMode(SFX_SLOT_NORECORD) )
/*?*/ 	                rReq.Record_Impl( rShell, rSlot, xRecorder, GetFrame() );
/*N*/ 			}
/*N*/         }
/*N*/ 
/*N*/ 		// ggf. die Bindings locken (MI: warum?)
/*N*/ 		SfxBindings *pBindings = GetBindings();
/*N*/ #if modal_mode_sinnlos
/*N*/ 		sal_Bool bLockBindings = rSlot.GetSlotId() != SID_OPENDOC && rSlot.GetSlotId() != SID_OPENURL;
/*N*/         if ( bLockBindings && pBindings )
/*N*/ 			pBindings->DENTERREGISTRATIONS();
/*N*/ #endif
/*N*/ 
/*N*/ 		// Alles holen, was gebraucht wird, da der Slot den Execute evtl. nicht
/*N*/ 		// "uberlebt, falls es ein 'Pseudoslot' f"ur Macros oder Verben ist
/*N*/ 		sal_Bool bAutoUpdate = rSlot.IsMode(SFX_SLOT_AUTOUPDATE);
/*N*/ 		SFX_REQUEST_ARG(rReq, pOrigItem, SfxExecuteItem, SID_SUBREQUEST, sal_False);
/*N*/ 		SfxExecuteItem *pExecuteItem = pOrigItem
/*N*/ 							? (SfxExecuteItem*)pOrigItem->Clone()
/*N*/ 							: 0;
/*N*/ 
/*N*/ 		// ggf. TabPage-ID setzen und SID merken
/*N*/ 		SfxAppData_Impl *pAppData = pSfxApp->Get_Impl();
/*N*/ 		SFX_REQUEST_ARG(rReq, pTabPageItem, SfxUInt16Item, SID_TABPAGE, sal_False);
/*N*/ 		if ( pTabPageItem )
/*N*/ 		{
/*?*/ 			pAppData->nAutoTabPageId = pTabPageItem->GetValue();
/*?*/ 			rReq.RemoveItem( SID_TABPAGE ); // sonst ArgCount > 0 => Seiteneff.
/*N*/ 		}
/*N*/ 		pAppData->nExecutingSID = rReq.GetSlot();
/*N*/ 
/*N*/ 		// API-Call-Klammerung und Document-Lock w"ahrend des Calls
/*N*/ 		{
/*N*/ 			// 'this' mu\s im Dtor bescheid sagen
/*N*/ 			sal_Bool bThisDispatcherAlive = sal_True;
/*N*/ 			sal_Bool *pOldInCallAliveFlag = pImp->pInCallAliveFlag;
/*N*/ 			pImp->pInCallAliveFlag = &bThisDispatcherAlive;
/*N*/ 
/*N*/             SfxViewFrame* pView = GetFrame();
/*N*/             if ( !pView )
/*?*/                 pView = SfxViewFrame::Current();
/*N*/             if ( pView )
/*N*/               SfxHelp::OpenHelpAgent( pView->GetFrame(), rReq.GetSlot() );
/*N*/ 
/*N*/             SfxExecFunc pFunc = rSlot.GetExecFnc();
/*N*/             rShell.CallExec( pFunc, rReq );
/*N*/ 
			// falls 'this' noch lebt
/*N*/ 			if ( bThisDispatcherAlive )
/*N*/ 				pImp->pInCallAliveFlag = pOldInCallAliveFlag;
/*N*/ 			else if ( pOldInCallAliveFlag )
/*N*/ 				// auch verschachtelte Stack-Frames sch"utzen
/*?*/ 				*pOldInCallAliveFlag = sal_False;
/*N*/ 		}
/*N*/ 
/*N*/ 		// TabPage-ID und Executing-SID zurueck setzen
/*N*/ 		if ( pTabPageItem )
/*?*/ 			pAppData->nAutoTabPageId = 0;
/*N*/ 		pAppData->nExecutingSID = 0;
/*N*/ 
/*N*/ #if modal_mode_sinnlos
/*N*/ 		// ggf. Lock wieder freigeben
/*N*/ 		if ( bLockBindings )
/*N*/ 			pBindings->DLEAVEREGISTRATIONS();
/*N*/ #endif
/*N*/ 
/*N*/ 		if( pExecuteItem )
/*N*/ 		{
/*?*/ 			Execute( *pExecuteItem );
/*?*/ 			delete pExecuteItem;
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( rReq.IsDone() )
/*N*/ 		{
/*N*/ 			// bei AutoUpdate sofort updaten; "Pseudoslots" d"urfen nicht
/*N*/ 			// Autoupdate sein!
/*N*/             if ( bAutoUpdate && pBindings )
/*N*/ 			{
/*N*/ 				const SfxSlot* pSlave = rSlot.GetLinkedSlot();
/*N*/ 				if (pSlave)
/*N*/ 				{
/*?*/ 					// 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());
/*N*/ 				}
/*N*/ 				else
/*N*/ 				{
/*N*/ 					pBindings->Invalidate(rSlot.GetSlotId());
/*N*/ 					pBindings->Update(rSlot.GetSlotId());
/*N*/ 				}
/*N*/ 			}
/*N*/ 			return sal_True;
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	return sal_False;
/*N*/ }

//====================================================================
/*N*/ void SfxDispatcher::Construct_Impl( SfxDispatcher* pParent )
/*N*/ {
/*N*/ 	pImp = new SfxDispatcher_Impl;
/*N*/ 	bFlushed = sal_True;
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 
/*N*/ 	pImp->pCachedServ1 = 0;
/*N*/ 	pImp->pCachedServ2 = 0;
/*N*/ 	pImp->bFlushing = sal_False;
/*N*/ 	pImp->bUpdated = sal_False;
/*N*/ 	pImp->bLocked = sal_False;
/*N*/ 	pImp->bActive = sal_False;
/*N*/ 	pImp->pParent = NULL;
/*N*/ 	pImp->bUILocked = sal_False;
/*N*/ 	pImp->bNoUI = sal_False;
/*N*/ 	pImp->bReadOnly = sal_False;
/*N*/ 	pImp->bQuiet = sal_False;
/*N*/ 	pImp->bModal = sal_False;
/*N*/ 	pImp->pInCallAliveFlag = 0;
/*N*/ 	pImp->bFilterEnabling = sal_False;
/*N*/ 	pImp->nFilterCount = 0;
/*N*/ 	pImp->pFilterSIDs = 0;
/*N*/ 	pImp->nStandardMode = 0;
/*N*/ 	pImp->pDisableList = pSfxApp->GetDisabledSlotList_Impl();
/*N*/ 	pImp->nDisableFlags = 0;
/*N*/ 
/*N*/ 	pImp->pParent = pParent;
/*N*/ 
/*N*/ 	pImp->bInvalidateOnUnlock = sal_False;
/*N*/ 	pImp->nActionLevel = 0;
/*N*/ 
/*N*/ 	for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
/*N*/ 		pImp->aObjBars[n].aResId = ResId( 0,0 );
/*N*/ 
/*N*/ 	GenLink aGenLink( LINK(this, SfxDispatcher, PostMsgHandler) );
/*N*/ 
/*N*/ 	pImp->xPoster = new SfxHintPoster(aGenLink);
/*N*/ 
/*N*/ 	pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
/*N*/ 	pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
/*N*/ }

/*N*/ SfxDispatcher::SfxDispatcher( SfxDispatcher* pParent )
/*N*/ {
/*N*/ 	Construct_Impl( pParent );
/*N*/ 	pImp->pFrame = 0;
/*N*/ }

/*N*/ 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.
*/

/*N*/ {
/*N*/ 	if ( pViewFrame )
/*N*/ 	{
/*N*/ 		SfxViewFrame *pFrame = pViewFrame->GetParentViewFrame();
/*N*/ 		if ( pFrame )
/*?*/ 			Construct_Impl(  pFrame->GetDispatcher() );
/*N*/         else
/*?*/             Construct_Impl( 0 );
/*N*/ 	}
/*N*/ 	else
/*N*/ 		Construct_Impl( 0 );
/*N*/ 	pImp->pFrame = pViewFrame;
/*N*/ }

//====================================================================
/*N*/ 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.
*/

/*N*/ {
/*N*/ #ifdef DBG_UTIL
/*N*/ 	ByteString sTemp( "Delete Dispatcher " );
/*N*/ 	sTemp += ByteString::CreateFromInt32( (sal_uInt32)this );
/*N*/ 	DBG_TRACE( sTemp.GetBuffer() );
/*N*/ 	DBG_ASSERT( !pImp->bActive, "deleting active Dispatcher" );
/*N*/ #endif

	// Damit in LeaveRegistrations kein Timer per Reschedule in PlugComm
	// zuschlaegt
/*N*/ 	pImp->aTimer.Stop();
/*N*/ 	pImp->xPoster->SetEventHdl( Link() );

	// die Stack-Varialblem in Call_Impl benachrichtigen
/*N*/ 	if ( pImp->pInCallAliveFlag )
/*N*/ 		*pImp->pInCallAliveFlag = sal_False;

	// Bindings und App besorgen
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/     SfxBindings* pBindings = GetBindings();

//	if (pImp->nEventId)
//		pSfxApp->RemoveEventHdl(pImp->nEventId);

	// wenn noch nicht flushed, die Bindings wiederbeleben
/*N*/     if ( pBindings && !pSfxApp->IsDowning() && !bFlushed )
/*N*/         pBindings->DLEAVEREGISTRATIONS();

	// ggf. bei den Bindings abmelden
/*N*/     while ( pBindings )
/*N*/ 	{
/*N*/         if ( pBindings->GetDispatcher_Impl() == this)
/*N*/             pBindings->SetDispatcher(0);
/*N*/         pBindings = pBindings->GetSubBindings_Impl();
/*N*/ 	}
/*N*/ 
/*N*/ 	delete pImp;
/*N*/ }

//====================================================================
/*N*/ void SfxDispatcher::Pop
/*N*/ (
/*N*/ 	SfxShell&   rShell,     /*  Die vom Stack zu nehmende SfxShell-Instanz. */

/*N*/ 	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. */
/*N*/ )
/*  [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.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	DBG_ASSERT( rShell.GetInterface(),
/*N*/ 				"pushing SfxShell without previous RegisterInterface()" );
/*N*/ 	DBG_ASSERT( pImp->nActionLevel == 0, "Push or Pop within Action" );
//	DBG_ASSERT( SFX_APP()->IsInAsynchronCall_Impl(),
//				  "Dispatcher Push/Pop in synchron-call-stack" );

/*N*/ 	FASTBOOL bDelete = (nMode & SFX_SHELL_POP_DELETE) == SFX_SHELL_POP_DELETE;
/*N*/ 	FASTBOOL bUntil = (nMode & SFX_SHELL_POP_UNTIL) == SFX_SHELL_POP_UNTIL;
/*N*/ 	FASTBOOL bPush = (nMode & SFX_SHELL_PUSH) == SFX_SHELL_PUSH;

/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 
/*N*/ #ifdef DBG_UTIL
/*N*/ 	ByteString aMsg( "SfxDispatcher(" );
/*N*/ 	aMsg += ByteString::CreateFromInt32( (long) this );
/*N*/ 	aMsg += bPush ? ")::Push(" : ")::Pop(";
/*N*/ 	if ( rShell.GetInterface() )
/*N*/ 		aMsg += rShell.GetInterface()->GetClassName();
/*N*/ 	else
/*N*/ 		aMsg += ByteString::CreateFromInt32( (long) &rShell );
/*N*/ 	aMsg += bDelete ? ") with delete" : ")";
/*N*/ 	DbgTrace( aMsg.GetBuffer() );
/*N*/ #endif
/*N*/ 
/*N*/ 	// gleiche Shell wie on-Top des ToDo-Stacks?
/*N*/ 	if ( pImp->aToDoStack.Count() && pImp->aToDoStack.Top().pCluster == &rShell )
/*N*/ 	{
/*?*/ 		// 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" );
/*?*/ 		}
/*N*/ 	}
/*N*/ 	else
/*N*/ 	{
/*N*/ 		// ::com::sun::star::chaos::Action merken
/*N*/ 		pImp->aToDoStack.Push( SfxToDo_Impl(bPush, bDelete, bUntil, rShell) );
/*N*/ 		if ( bFlushed )
/*N*/ 		{
/*N*/ 			bFlushed = sal_False;
/*N*/ 			pImp->bUpdated = sal_False;
/*N*/ 
/*N*/ 			// Bindings schlafen legen
/*N*/             SfxBindings* pBindings = GetBindings();
/*N*/             if ( pBindings )
/*N*/                 pBindings->DENTERREGISTRATIONS();
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( !pSfxApp->IsDowning() && pImp->aToDoStack.Count() )
/*N*/ 	{
/*N*/ 		//! if (SFX_APP()->AnyInput(INPUT_KEYBOARD | INPUT_MOUSE) )
/*N*/ 		//! AnyInput haut nicht hin; hier muss noch ein Kriterium gefunden
/*N*/ 		//! werden. Solange wieder immer mit Timer.
/*N*/ 
/*N*/ 		if (sal_True)
/*N*/ 		{
/*N*/ 			// Kein sofortiges Update gewuenscht
/*N*/ 			pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
/*N*/ 			pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
/*N*/ 			pImp->aTimer.Start();
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*?*/ 			// Schnellstmoegliches Update (sollte Normalfall sein)
/*?*/ 			pImp->aTimer.Stop();
/*?*/ 			GetpApp()->PostUserEvent(pImp->nEventId, (void*)0);
/*N*/ 		}
/*N*/ 	}
/*N*/ 	else
/*N*/ 	{
/*?*/ 		// doch nichts zu tun
/*?*/ 		pImp->aTimer.Stop();
/*?*/ 
/*?*/ 		// ggf. Bindings wieder aufwecken
/*?*/ 		if ( !pImp->aToDoStack.Count() )
/*?*/ 		{
/*?*/             SfxBindings* pBindings = GetBindings();
/*?*/             if ( pBindings )
/*?*/                 pBindings->DLEAVEREGISTRATIONS();
/*?*/ 		}
/*N*/ 	}
/*N*/ }

//--------------------------------------------------------------------

/*?*/ 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.
*/

/*?*/ {
/*?*/ 	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 )

//--------------------------------------------------------------------
/*N*/ 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.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	SFX_STACK(SfxDispatcher::CheckVirtualStack);
/*N*/ 
/*N*/ 	SfxShellStack_Impl aStack( pImp->aStack );
/*N*/ 	for ( short nToDo = pImp->aToDoStack.Count()-1; nToDo >= 0; --nToDo )
/*N*/ 	{
/*?*/ 		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" );
/*?*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	sal_Bool bReturn;
/*N*/ 	if ( bDeep )
/*N*/ 		bReturn = aStack.Contains(&rShell);
/*N*/ 	else
/*?*/ 		bReturn = aStack.Top() == &rShell;
/*N*/ 	return bReturn;
/*N*/ }

//--------------------------------------------------------------------
/*N*/ sal_uInt16 SfxDispatcher::GetShellLevel( const SfxShell& rShell )

/*	[Beschreibung]

	Ermittelt die Position einer SfxShell im Stack des Dispatchers.
	Dazu wird dieser ggf. zuvor geflusht.


	[Rckgabewert]

	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.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	SFX_STACK(SfxDispatcher::GetShellLevel);
/*N*/ 	Flush();
/*N*/ 
/*N*/ 	for ( sal_uInt16 n = 0; n < pImp->aStack.Count(); ++n )
/*N*/ 		if ( pImp->aStack.Top( n ) == &rShell )
/*N*/ 			return n;
/*N*/ 	if ( pImp->pParent )
/*N*/     {
/*?*/         sal_uInt16 nRet = pImp->pParent->GetShellLevel(rShell);
/*?*/         if ( nRet == USHRT_MAX )
/*?*/             return nRet;
/*?*/         return  nRet + pImp->aStack.Count();
/*N*/     }
/*N*/ 
/*N*/ 	return USHRT_MAX;
/*N*/ }

//--------------------------------------------------------------------
/*N*/ SfxShell *SfxDispatcher::GetShell(sal_uInt16 nIdx) const
/*N*/ 
/*	[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.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 
/*N*/ 	sal_uInt16 nShellCount = pImp->aStack.Count();
/*N*/ 	if ( nIdx < nShellCount )
/*N*/ 		return pImp->aStack.Top(nIdx);
/*N*/ 	else if ( pImp->pParent )
/*?*/ 		return pImp->pParent->GetShell(	nIdx - nShellCount );
/*N*/ 	return 0;
/*N*/ }

//--------------------------------------------------------------------
/*N*/ 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.
*/

/*N*/ {
/*N*/ 	if ( pImp->pFrame )
/*N*/ 		return &pImp->pFrame->GetBindings();
/*N*/     else
/*N*/         return NULL;
/*N*/ }

//--------------------------------------------------------------------
/*N*/ 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.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	return pImp->pFrame;
/*N*/ }

//--------------------------------------------------------------------
/*N*/ void SfxDispatcher::DoActivate_Impl( sal_Bool bMDI )

/*	[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.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	SFX_STACK(SfxDispatcher::DoActivate);
/*N*/ 	if ( bMDI )
/*N*/ 	{
/*N*/ 		#ifdef DBG_UTIL
/*N*/ 		ByteString sTemp("Activate Dispatcher ");
/*N*/ 		sTemp += ByteString::CreateFromInt32( (sal_uInt32) this );
/*N*/ 		DBG_TRACE(sTemp.GetBuffer());
/*N*/ 		DBG_ASSERT( !pImp->bActive, "Activate-Fehler" );
/*N*/ 		#endif
/*N*/ 		pImp->bActive = sal_True;
/*N*/ 		pImp->bUpdated = sal_False;
/*N*/         SfxBindings* pBindings = GetBindings();
/*N*/         if ( pBindings )
/*N*/         {
/*N*/             pBindings->SetDispatcher(this);
/*N*/             pBindings->SetActiveFrame( pImp->pFrame->GetFrame()->GetFrameInterface() );
/*N*/         }
/*N*/ 	}
/*N*/ 	else
/*N*/ 	{
/*?*/ 		#ifdef DBG_UTIL
/*?*/ 		ByteString sTemp("Non-MDI-Activate Dispatcher");
/*?*/ 		sTemp += ByteString::CreateFromInt32( (sal_uInt32) this );
/*?*/ 		DBG_TRACE( sTemp.GetBuffer() );
/*?*/ 		#endif
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( IsAppDispatcher() )
/*N*/ 		return;
/*N*/ 
/*N*/ 	for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
/*N*/ 		pImp->aStack.Top( (sal_uInt16) i )->DoActivate(pImp->pFrame, bMDI);
/*N*/ 
/*N*/ 	if ( pImp->aToDoStack.Count() )
/*N*/ 	{
/*?*/ 		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);
/*?*/ 		}
/*N*/ 	}
/*N*/ }

/*?*/ void SfxDispatcher::DoParentActivate_Impl()
/*?*/ {
/*?*/ 	for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
/*?*/ 		pImp->aStack.Top( (sal_uInt16) i )->ParentActivate();
/*?*/ }

//--------------------------------------------------------------------
/*N*/ void SfxDispatcher::DoDeactivate_Impl( sal_Bool bMDI )

/*  [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.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	SFX_STACK(SfxDispatcher::DoDeactivate);
/*N*/ 
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 
/*N*/ 	if ( bMDI )
/*N*/ 	{
/*N*/ 		DBG_TRACE(ByteString("Deactivate Dispatcher ").Append(ByteString::CreateFromInt32( (sal_uInt32) this )).GetBuffer());
/*N*/ 		DBG_ASSERT( pImp->bActive, "Deactivate-Fehler" );
/*N*/ 		pImp->bActive = sal_False;
/*N*/ 
/*N*/ 		if ( pImp->pFrame && !pImp->pFrame->IsA(TYPE(SfxInPlaceFrame)) )
/*N*/ 		{
/*N*/             SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame()->GetWorkWindow_Impl();
/*N*/             if ( pWorkWin )
/*N*/             {
/*N*/                 for (sal_uInt16 n=0; n<pImp->aChildWins.Count();)
/*N*/                 {
/*N*/                     SfxChildWindow *pWin = pWorkWin->GetChildWindow_Impl( (sal_uInt16) ( pImp->aChildWins[n] & 0xFFFF ) );
/*N*/                     if (!pWin || pWin && pWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT)
/*N*/                         pImp->aChildWins.Remove(n);
/*N*/                     else
/*N*/                         n++;
/*N*/                 }
/*N*/             }
/*N*/ 		}
/*N*/ 	}
/*N*/ 	else
/*N*/ 		DBG_TRACE( ByteString ("Non-MDI-DeActivate Dispatcher").Append(ByteString::CreateFromInt32( (sal_uInt32) this )).GetBuffer() );
/*N*/ 
/*N*/ 	if ( IsAppDispatcher() && !pSfxApp->IsDowning() )
/*N*/ 		return;
/*N*/ 
/*N*/ 	for ( sal_uInt16 i = 0; i < pImp->aStack.Count(); ++i )
/*N*/ 		pImp->aStack.Top(i)->DoDeactivate(pImp->pFrame, bMDI);
/*N*/ 
/*N*/ 	Flush();
/*N*/ }

/*?*/ void SfxDispatcher::DoParentDeactivate_Impl()
/*?*/ {
/*?*/ 	for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
/*?*/ 		pImp->aStack.Top( (sal_uInt16) i )->ParentDeactivate();
/*?*/ }

//--------------------------------------------------------------------
/*N*/ int SfxDispatcher::GetShellAndSlot_Impl
/*N*/ (
/*N*/ 	sal_uInt16			nSlot,		// die zu suchende Slot-Id
/*N*/ 	SfxShell**		ppShell,	// die SfxShell, welche nSlot z.Zt. bedient
/*N*/ 	const SfxSlot** ppSlot, 	// der SfxSlot, welcher nSlot z.Zt. bedient
/*N*/ 	sal_Bool			bOwnShellsOnly,
/*N*/ 	sal_Bool			bModal,		// trotz ModalMode
/*N*/ 	sal_Bool		bRealSlot
/*N*/ )

/*	[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.
*/

/*N*/ {
/*N*/ 	SFX_STACK(SfxDispatcher::GetShellAndSlot_Impl);
/*N*/ 
/*N*/ 	Flush();
/*N*/ 	SfxSlotServer aSvr;
/*N*/ 	if ( _FindServer(nSlot, aSvr, bModal) )
/*N*/ 	{
/*N*/ 		if ( bOwnShellsOnly && aSvr.GetShellLevel() >= pImp->aStack.Count() )
/*N*/ 			return sal_False;
/*N*/ 
/*N*/ 		*ppShell = GetShell(aSvr.GetShellLevel());
/*N*/ 		*ppSlot = aSvr.GetSlot();
/*N*/ 		if ( 0 == (*ppSlot)->GetExecFnc() && bRealSlot )
/*?*/ 			*ppSlot = (*ppShell)->GetInterface()->GetRealSlot(*ppSlot);
/*N*/ 
/*N*/ #ifdef DBG_UTILx
/*N*/ 		ByteString aMsg( nSlot );
/*N*/ 		aMsg += " found in ";
/*N*/ 		aMsg += (*ppShell)->GetInterface()->GetClassName();
/*N*/ 		DbgTrace( aMsg.GetBuffer() );
/*N*/ #endif
/*N*/ 
/*N*/ 		return sal_True;
/*N*/ 	}
/*N*/ 
/*N*/ #ifdef DBG_UTILx
/*N*/ 	ByteString aMsg( nSlot );
/*N*/ 	aMsg += " not found";
/*N*/ 	DbgTrace( aMsg.GetBuffer() );
/*N*/ #endif
/*N*/ 
/*N*/ 	return sal_False;
/*N*/ }

/*
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;}
};
*/

//--------------------------------------------------------------------
/*N*/ void SfxDispatcher::_Execute
/*N*/ (
/*N*/ 	SfxShell&		rShell,		// zu rufende <SfxShell>
/*N*/ 	const SfxSlot&	rSlot,		// zu rufender <SfxSlot>
/*N*/ 	SfxRequest&		rReq,		// auszuf"uhrende Funktion (Id und optional Parameter)
/*N*/ 	SfxCallMode 	eCallMode	// synchron, asynchron oder wie beim Slot angegeben
/*N*/ )

/*	[Beschreibung]

	Diese Methode f"uhrt einen Request "uber einen gecachten <Slot-Server>
	aus.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
/*N*/ 	DBG_ASSERT( !pImp->aToDoStack.Count(), "unprepared InPlace _Execute" );
/*N*/ 
/*N*/ 	if ( IsLocked( rSlot.GetSlotId() ) )
/*N*/ 		return;
/*N*/ 
/*N*/ 	sal_uInt16 nSlot = rSlot.GetSlotId();
/*N*/ 	if ( SfxMacroConfig::IsMacroSlot( nSlot ) )
/*?*/ 		{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 SFX_APP()->GetMacroConfig()->RegisterSlotId( nSlot );
/*N*/ 
/*N*/ 	if ( (eCallMode & SFX_CALLMODE_ASYNCHRON) ||
/*N*/ 		 ( !(eCallMode & SFX_CALLMODE_SYNCHRON) &&
/*N*/ 		   rSlot.IsMode(SFX_SLOT_ASYNCHRON) ) )
/*N*/ 	{
/*N*/ 		SfxDispatcher *pDispat = this;
/*N*/ 		while ( pDispat )
/*N*/ 		{
/*N*/ 			sal_uInt16 nShellCount = pDispat->pImp->aStack.Count();
/*N*/ 			for ( sal_uInt16 n=0; n<nShellCount; n++ )
/*N*/ 			{
/*N*/ 				if ( &rShell == pDispat->pImp->aStack.Top(n) )
/*N*/ 				{
/*N*/                     if ( eCallMode & SFX_CALLMODE_RECORD )
/*N*/                         rReq.AllowRecording( TRUE );
/*N*/                     pDispat->pImp->xPoster->Post(new SfxRequest(rReq));
/*N*/ //                    pDispat->pImp->xPoster->Post(new Executer(new SfxRequest(rReq), &rSlot, n ));
/*N*/ 					return;
/*N*/ 				}
/*N*/ 			}
/*N*/ 
/*?*/ 			pDispat = pDispat->pImp->pParent;
/*N*/ 		}
/*N*/ 	}
/*N*/ 	else
/*N*/ 		Call_Impl( rShell, rSlot, rReq, SFX_CALLMODE_RECORD==(eCallMode&SFX_CALLMODE_RECORD) );
/*N*/ }

//--------------------------------------------------------------------
/*?*/ 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 )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return 0;//STRIP001 
/*?*/ }

/*?*/ sal_uInt16 SfxDispatcher::ExecuteFunction( sal_uInt16 nSlot, const SfxItemSet& rArgs,
/*?*/ 									   sal_uInt16 nMode )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return 0;//STRIP001 

/*
    // 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
/*?*/ }

/*N*/ sal_uInt16 SfxDispatcher::GetSlotId( const String& rCommand )
/*N*/ {
/*N*/ 	// Anzahl der Shells auf den verkettenten Dispatchern z"ahlen
/*N*/ 	Flush();
/*N*/ 	sal_uInt16 nTotCount = pImp->aStack.Count();
/*N*/ 	if ( pImp->pParent )
/*N*/ 	{
/*?*/ 		SfxDispatcher *pParent = pImp->pParent;
/*?*/ 		while ( pParent )
/*?*/ 		{
/*?*/ 			nTotCount += pParent->pImp->aStack.Count();
/*?*/ 			pParent = pParent->pImp->pParent;
/*?*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	const SfxSlot *pSlot=NULL;
/*N*/ 	sal_uInt16 nFirstShell = 0;
/*N*/ 	for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
/*N*/ 	{
/*N*/ 		SfxShell *pObjShell = GetShell(i);
/*N*/ 		SfxInterface *pIFace = pObjShell->GetInterface();
/*N*/ 		pSlot = pIFace->GetSlot( rCommand );
/*N*/ 		if ( pSlot )
/*?*/ 			return pSlot->GetSlotId();
/*N*/ 	}
/*N*/ 
/*N*/ 	return 0;
/*N*/ }

//--------------------------------------------------------------------

//--------------------------------------------------------------------

//--------------------------------------------------------------------
/*N*/ SfxExecuteItem::SfxExecuteItem( const SfxExecuteItem& rArg )
/*N*/ 	: SfxPoolItem( rArg ), nModifier( 0 )
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ }

//--------------------------------------------------------------------
/*N*/ SfxExecuteItem::SfxExecuteItem(
/*N*/ 	sal_uInt16 nWhich, sal_uInt16 nSlotP, SfxCallMode eModeP,
/*N*/ 	const SfxPoolItem*	pArg1, ... ) :
/*N*/ 	SfxPoolItem( nWhich ), eCall( eModeP ), nSlot( nSlotP ), nModifier( 0 )
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ }

//--------------------------------------------------------------------
/*N*/ SfxExecuteItem::SfxExecuteItem(
/*N*/ 	sal_uInt16 nWhich, sal_uInt16 nSlotP, SfxCallMode eModeP )
/*N*/ 	: SfxPoolItem( nWhich ), nSlot( nSlotP ), eCall( eModeP ), nModifier( 0 )
/*N*/ {
/*N*/ }

//--------------------------------------------------------------------
/*N*/ const SfxPoolItem* SfxDispatcher::Execute( const SfxExecuteItem& rItem )
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return 0;//STRIP001 
/*N*/ }

//--------------------------------------------------------------------
/*N*/ const SfxPoolItem* SfxDispatcher::Execute
/*N*/ (
/*N*/ 	sal_uInt16 nSlot,				// die Id der auszufuehrenden Funktion
/*N*/ 	SfxCallMode eCall,			// SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
/*N*/ 	const SfxPoolItem **pArgs,	// 0-terminiertes C-Array von Parametern
/*N*/ 	sal_uInt16 nModi,
/*N*/ 	const SfxPoolItem **pInternalArgs // 0-terminiertes C-Array von Parametern
/*N*/ )

/*  [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).
*/

/*N*/ {
/*N*/ 	if ( IsLocked(nSlot) )
/*N*/ 		return 0;
/*N*/ 
/*N*/ 	SfxShell *pShell = 0;
/*N*/ 	const SfxSlot *pSlot = 0;
/*N*/ 	if ( GetShellAndSlot_Impl( nSlot,  &pShell, &pSlot, sal_False,
/*N*/ 							   SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
/*N*/ 	{
/*N*/ 		SfxRequest* pReq;
/*N*/ 		if ( pArgs && *pArgs )
/*N*/ 		{
/*?*/ 			SfxAllItemSet aSet( pShell->GetPool() );
/*?*/ 			for ( const SfxPoolItem **pArg = pArgs; *pArg; ++pArg )
/*?*/ 				MappedPut_Impl( aSet, **pArg );
/*?*/ 			pReq = new SfxRequest( nSlot, eCall, aSet );
/*N*/ 		}
/*N*/ 		else
/*N*/ 			pReq =  new SfxRequest( nSlot, eCall, pShell->GetPool() );
/*N*/ 		pReq->SetModifier( nModi );
/*N*/ 		if( pInternalArgs && *pInternalArgs)
/*N*/ 		{
/*?*/ 			SfxAllItemSet aSet( SFX_APP()->GetPool() );
/*?*/ 			for ( const SfxPoolItem **pArg = pInternalArgs; *pArg; ++pArg )
/*?*/ 				aSet.Put( **pArg );
/*?*/ 			pReq->SetInternalArgs_Impl( aSet );
/*N*/ 		}
/*N*/ 		_Execute( *pShell, *pSlot, *pReq, eCall );
/*N*/ 		const SfxPoolItem* pRet = pReq->GetReturnValue();
/*N*/ 		delete pReq; return pRet;
/*N*/ 	}
/*N*/ 	return 0;
/*N*/ }

//--------------------------------------------------------------------
/*?*/ 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).
*/

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ 	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).
*/

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ 	return 0;
/*?*/ }

//--------------------------------------------------------------------
/*N*/ const SfxPoolItem* SfxDispatcher::Execute
/*N*/ (
/*N*/ 	sal_uInt16				nSlot,		// die Id der auszufuehrenden Funktion
/*N*/ 	SfxCallMode 		eCall,		// SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
/*N*/ 	const SfxPoolItem*	pArg1,		// erster Parameter
/*N*/ 	... 							// 0-terminiertes Liste Parametern
/*N*/ )

/*  [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 );
*/

/*N*/ {
/*N*/ 	if ( IsLocked(nSlot) )
/*N*/ 		return 0;
/*N*/ 
/*N*/ 	SfxShell *pShell = 0;
/*N*/ 	const SfxSlot *pSlot = 0;
/*N*/ 	if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
/*N*/ 							   SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
/*N*/ 	{
/*N*/ 	   SfxAllItemSet aSet( pShell->GetPool() );
/*N*/ 
/*N*/ 	   va_list pVarArgs;
/*N*/ 	   va_start( pVarArgs, pArg1 );
/*N*/ 	   for ( const SfxPoolItem *pArg = pArg1;
/*N*/ 			 pArg;
/*N*/ 			 pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
/*N*/ 		   MappedPut_Impl( aSet, *pArg );
/*N*/ 	   va_end(pVarArgs);
/*N*/ 
/*N*/ 	   SfxRequest aReq( nSlot, eCall, aSet );
/*N*/ 	   _Execute( *pShell, *pSlot, aReq, eCall );
/*N*/ 	   return aReq.GetReturnValue();
/*N*/ 	}
/*N*/ 	return 0;
/*N*/ }

//--------------------------------------------------------------------

/*N*/ IMPL_LINK( SfxDispatcher, PostMsgHandler, SfxRequest*, pReq )

/*	[Beschreibung]

	Hilfsmethode zum Empfangen der asynchron auszuf"uhrenden <SfxRequest>s.
*/

/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
/*N*/ 	SFX_STACK(SfxDispatcher::PostMsgHandler);
/*N*/ 
/*N*/ 	// ist auch der Pool noch nicht gestorben?
/*N*/ //    SfxRequest* pReq = pExec->pRequest;
/*N*/ 	if ( !pReq->IsCancelled() )
/*N*/ 	{
/*N*/ 		if ( !IsLocked(pReq->GetSlot()) )
/*N*/ 		{
/*N*/ 			Flush();
/*N*/             SfxSlotServer aSvr;
/*N*/             if ( _FindServer(pReq->GetSlot(), aSvr, HACK(x) sal_True ) )
/*N*/ //            SfxShell *pShell = GetShell(pExec->nLevel);
/*N*/ //            if ( pShell && pShell->GetInterface()->GetSlot( pExec->pSlot->GetSlotId() ) )
/*N*/ 			{
/*N*/                 const SfxSlot *pSlot = aSvr.GetSlot();
/*N*/                 SfxShell *pSh = GetShell(aSvr.GetShellLevel());
/*N*/ 
/*N*/ 				DBG( SfxApplication *pSfxApp = SFX_APP() );
/*N*/ 				DBG( pSfxApp->EnterAsynchronCall_Impl() );
/*N*/ 
/*N*/ 				// Wenn pSlot ein "Pseudoslot" f"ur Macros oder Verben ist, kann
/*N*/ 				// er im Call_Impl zerst"ort werden, also nicht mehr benutzen!
/*N*/ 				pReq->SetSynchronCall( sal_False );
/*N*/                 Call_Impl( *pSh, *pSlot, *pReq, pReq->AllowsRecording() ); //! woher bRecord?
/*N*/ //                Call_Impl( *pShell, *pExec->pSlot, *pReq, sal_True ); //! woher bRecord?
/*N*/ 				DBG( pSfxApp->LeaveAsynchronCall_Impl() );
/*N*/ 			}
/*N*/ 
/*N*/ //            delete pExec;
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/ //            pImp->xPoster->Post(pExec);
/*?*/             pImp->xPoster->Post(new SfxRequest(*pReq));
/*N*/ 		}
/*N*/ 	}
/*N*/ //    else
/*N*/ //        delete pExec;
/*N*/ 
/*N*/     delete pReq;
/*N*/ 	return 0;
/*N*/ }
//--------------------------------------------------------------------
/*?*/ void SfxDispatcher::EnterAction( const String& rName )

// marks the beginning of a block of actions

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }
//--------------------------------------------------------------------
/*?*/ void SfxDispatcher::LeaveAction()

// marks the end of a block of actions

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }
//--------------------------------------------------------------------
/*N*/ void SfxDispatcher::SetMenu_Impl()
/*N*/ {
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 	if ( pImp->pFrame )
/*N*/ 	{
/*N*/ 		if ( !pImp->pFrame->GetViewShell() )
/*N*/ 			return;
/*N*/ 
/*N*/         SfxTopViewFrame* pTop= PTR_CAST( SfxTopViewFrame, pImp->pFrame->GetTopViewFrame() );
/*N*/         if ( pTop && pTop->GetBindings().GetDispatcher() == this )
/*N*/         {
/*N*/ 			SfxTopFrame* pFrm = pTop->GetTopFrame_Impl();
/*N*/ 			SfxMenuBarManager* pMenuBar = pImp->pFrame->GetViewShell()->GetMenuBar_Impl();
/*N*/             if ( pMenuBar )
/*N*/             {
/*N*/                 MenuBar* pMenu = (MenuBar*) pMenuBar->GetMenu()->GetSVMenu();
/*N*/                 pFrm->LockResize_Impl( TRUE );
/*N*/                 pFrm->SetMenuBar_Impl( pMenu );
/*N*/                 pFrm->LockResize_Impl( FALSE );
/*N*/             }
/*N*/             else if ( pImp->pParent )
/*N*/             {
/*?*/                 pImp->pParent->SetMenu_Impl();
/*N*/             }
/*N*/         }
/*N*/ 	}
/*N*/ }

/*N*/ long SfxDispatcher::Update_Impl( sal_Bool bForce )

/*	[Beschreibung]

	Hilfsmethode zum Updaten der <Object-Bars> und <Object-Menus>,
	nach Bewegungen auf dem Stack.
*/

/*N*/ {
/*N*/ 	SFX_STACK(SfxDispatcher::Update_Impl);
/*N*/ 
/*N*/ 	Flush();
/*N*/ 
/*N*/     if ( !pImp->pFrame )
/*N*/ 		return 0;
/*N*/ 
/*N*/ 	if ( pImp->bUILocked )
/*N*/ 		return 0;
/*N*/ 
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 	SfxDispatcher *pDisp = this;
/*N*/ 	sal_Bool bUpdate = bForce;
/*N*/     while ( pDisp && pDisp->pImp->pFrame )
/*N*/ 	{
/*N*/         SfxWorkWindow *pWork = pDisp->pImp->pFrame->GetFrame()->GetWorkWindow_Impl();
/*N*/ 		SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
/*N*/ 		if ( pAct == pDisp || pAct == this )
/*N*/ 		{
/*N*/ 			if ( !bUpdate )
/*N*/ 				bUpdate = !pDisp->pImp->bUpdated;
/*N*/ 			pDisp->pImp->bUpdated = sal_True;
/*N*/ 		}
/*N*/ 		else
/*N*/ 			break;
/*N*/ 
/*N*/ 		pDisp = pDisp->pImp->pParent;
/*N*/ 	}
/*N*/ 
/*N*/     if ( !bUpdate || pImp->pFrame->GetFrame()->IsClosing_Impl() )
/*N*/ 		return 0;
/*N*/ 
/*N*/     SfxTopViewFrame* pTop = pImp->pFrame ? PTR_CAST( SfxTopViewFrame, pImp->pFrame->GetTopViewFrame() ) : NULL;
/*N*/     sal_Bool bUIActive = pTop && pTop->GetBindings().GetDispatcher() == this;
/*N*/     SfxMenuBarManager* pAppMenu = NULL;
/*N*/ 
/*N*/     if ( !bUIActive && pTop && GetBindings() == &pTop->GetBindings() )
/*N*/ 		// Eigene Tools nur intern festhalten und da"fur sorgen, da\s der
/*N*/ 		// aktive Dispatcher sie abholt
/*?*/         GetBindings()->GetDispatcher()->pImp->bUpdated = sal_False;
/*N*/ 
/*N*/ 	// Bindings schlafen legen
/*N*/     SfxBindings* pBindings = GetBindings();
/*N*/     if ( pBindings )
/*N*/         pBindings->DENTERREGISTRATIONS();
/*N*/ 
/*N*/ 	// Test auf InPlaceFrame und speziell internes InPlace
/*N*/ 	SfxInPlaceFrame *pIPFrame = PTR_CAST ( SfxInPlaceFrame, pImp->pFrame);
/*N*/     sal_Bool bIsIPOwner = (pIPFrame && pIPFrame->GetObjectShell()->GetInPlaceObject()->GetIPClient()->Owner());
/*N*/     SvInPlaceClient *pClient = pImp->pFrame ? pImp->pFrame->GetViewShell()->GetIPClient() : NULL;
/*N*/     if ( bUIActive && !pIPFrame && ( !pClient || !pClient->GetProtocol().IsUIActive() ) )
/*N*/     {
/*N*/ 		SetMenu_Impl();
/*N*/         pAppMenu = pImp->pFrame->GetViewShell()->GetMenuBar_Impl();
/*N*/         pAppMenu->ResetObjectMenus();
/*N*/     }
/*N*/ 
/*N*/ 	// Environment
/*N*/     SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame()->GetWorkWindow_Impl();
/*N*/ 
/*N*/ 	// der SfxInternalFrame oder SfxTopViewFrame, zu dem ich geh"ore
/*N*/ 	SfxViewFrame *pAct =
/*N*/ 		bIsIPOwner ?
/*N*/ 		pImp->pFrame->GetParentViewFrame_Impl() :
/*N*/ 		pImp->pFrame;
/*N*/ 
/*N*/ 	// Ich kontrolliere die StatusBar einer Task auch wenn ich nicht aktiv bin, aber
/*N*/ 	// zu einem internem InPlaceFrame oder einem anderen ViewFrame innerhalb der Task geh"ore
/*N*/     SfxFrame *pTask = pAct ? pAct->GetFrame()->GetTopFrame() : NULL;
/*N*/ 
/*N*/ 	SfxWorkWindow *pTaskWin = NULL;
/*N*/ 	sal_Bool bSet = sal_True;
/*N*/ 	if ( pImp->pFrame && pImp->pFrame->GetViewShell() )
/*N*/ 	{
/*N*/ 		SvInPlaceClient *pClient = pImp->pFrame->GetViewShell()->GetIPClient();
/*N*/ 		if ( pClient && pClient->GetProtocol().IsUIActive() )
/*N*/ 			bSet = sal_False;
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( pTask && bSet )
/*N*/ 	{
/*N*/ 		pTaskWin = pTask->GetWorkWindow_Impl();
/*N*/ 		pTaskWin->ResetStatusBar_Impl();
/*N*/ 	}
/*N*/ 
/*N*/ 	SfxDispatcher *pDispat = this;
/*N*/ 	while ( pDispat )
/*N*/ 	{
/*N*/         SfxWorkWindow *pWork = pDispat->pImp->pFrame->GetFrame()->GetWorkWindow_Impl();
/*N*/ 		SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
/*N*/ 		if ( pAct == pDispat || pAct == this )
/*N*/ 		{
/*N*/ 			pWork->ResetObjectBars_Impl();
/*N*/ 			pWork->ResetChildWindows_Impl();
/*N*/ 		}
/*N*/ 
/*N*/ 		pDispat = pDispat->pImp->pParent;
/*N*/ 	}
/*N*/ 
/*N*/ 	sal_Bool bIsActive = sal_False;
/*N*/ 	SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
/*N*/ 	pDispat = this;
/*N*/ 	while ( pActDispat && !bIsActive )
/*N*/ 	{
/*N*/ 		if ( pDispat == pActDispat )
/*N*/ 			bIsActive = sal_True;
/*N*/ 		pActDispat = pActDispat->pImp->pParent;
/*N*/ 	}
/*N*/ 
/*N*/     if ( !pIPFrame && !IsAppDispatcher() && bIsActive )
/*N*/ 		CollectTools_Impl( pWorkWin );
/*N*/ 
/*N*/ 	// Jetzt rekursiv die Dispatcher abklappern
/*N*/     sal_uInt32 nHelpId = _Update_Impl( bUIActive, !pIPFrame, bIsIPOwner, pAppMenu, bSet ? pTaskWin : NULL );
/*N*/ 	if ( bUIActive || bIsActive )
/*N*/ 	{
/*N*/ 		pWorkWin->UpdateObjectBars_Impl();
/*N*/ 
/*N*/         if ( pAppMenu )
/*N*/             pAppMenu->UpdateObjectMenus();
/*N*/ 
/*N*/ 		if ( bUIActive )
/*N*/ 		{
/*N*/ 			// ggf. Hilfe-PI antriggern
/*N*/ //            SfxHelpPI* pHelpPI = pSfxApp->GetHelpPI();
/*N*/ //            if (pHelpPI && nHelpId)
/*N*/ //                pHelpPI->LoadTopic( nHelpId );
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( pTaskWin )
/*N*/ 		pTaskWin->UpdateStatusBar_Impl();
/*N*/ 
/*N*/     if ( pBindings )
/*N*/         pBindings->DLEAVEREGISTRATIONS();
/*N*/ 	return 1;
/*N*/ }


/*N*/ void SfxDispatcher::CollectTools_Impl( SfxWorkWindow* pWorkWin )
/*N*/ {
/*N*/ 	// Innerhalb eines ToolSpace werden auch die Tools von nicht aktiven Frames
/*N*/ 	// angezeigt, damit es beim Wechsel der Frames nicht zappelt
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/     SfxToolBoxConfig *pTbxCfg = pWorkWin->GetBindings().GetToolBoxConfig();
/*N*/ 
/*N*/ 	// Die Objectbars aller ViewFrames der aktuellen Task einsammeln
/*N*/ 	for ( SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst();
/*N*/ 			pViewFrame;
/*N*/ 			pViewFrame = SfxViewFrame::GetNext(*pViewFrame) )
/*N*/ 	{
/*N*/ 		// Frames mit anderem WorkWindow interessieren hier nicht
/*N*/ 		if ( pViewFrame->GetFrame()->GetWorkWindow_Impl() != pWorkWin )
/*N*/ 			continue;
/*N*/ 
/*N*/ 		// Nur weitermachen, wenn es nicht sowieso einer meiner parents ist
/*N*/ 		SfxDispatcher *pDispat = pViewFrame->GetDispatcher();
/*N*/ 		SfxDispatcher *pParent = this;
/*N*/ 		while ( pParent )
/*N*/ 		{
/*N*/ 			if ( pParent == pDispat )
/*N*/ 				break;
/*?*/ 			pParent = pParent->pImp->pParent;
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( pParent )
/*N*/ 			continue;
/*N*/ 
/*N*/ 		// Alle objectbars des ViewFrames vormerken
/*N*/ 		sal_uInt16 n;
/*?*/ 		for (n=0; n<SFX_OBJECTBAR_MAX; n++)
/*?*/ 		{
/*?*/ 			SfxObjectBars_Impl& rBar = pDispat->pImp->aObjBars[n];
/*?*/ 			sal_uInt16 nId = rBar.aResId.GetId();
/*?*/ 			if ( nId && pTbxCfg->GetAlignment(n) != SFX_ALIGN_NOALIGNMENT )
/*?*/ 				pWorkWin->SetObjectBar_Impl( rBar.nMode,
/*?*/ 					rBar.aResId, rBar.pIFace, &rBar.aName );
/*?*/ 		}
/*?*/ 
/*?*/ 		SfxShell *pShell = pDispat->GetShell(0);
/*?*/ 		SfxModule *pMod = pShell->GetInterface()->GetModule();
/*?*/ 		SfxSlotPool& rSlotPool = pMod ? *pMod->GetSlotPool() : pShell->GetSlotPool_Impl();
/*?*/ 
/*?*/ 		// ChildWindows auch "bunkern"
/*?*/ 		for (n=0; n<pDispat->pImp->aChildWins.Count(); n++)
/*?*/ 		{
/*?*/ 			sal_uInt32 nId = pDispat->pImp->aChildWins[n];
/*?*/ 			const SfxSlot *pSlot = rSlotPool.GetSlot( (sal_uInt16) nId );
/*?*/ 			sal_uInt16 nMode = SFX_VISIBILITY_STANDARD;
/*?*/ 			if( pSlot )
/*?*/ 			{
/*?*/ 				if ( pSlot->IsMode(SFX_SLOT_CONTAINER) )
/*?*/ 				{
/*?*/ 					if ( !pWorkWin->IsVisible_Impl( SFX_VISIBILITY_CLIENT ) )
/*?*/ 						continue;
/*?*/ 					nMode |= SFX_VISIBILITY_CLIENT;
/*?*/ 				}
/*?*/ 				else
/*?*/ 				{
/*?*/ 					if ( !pWorkWin->IsVisible_Impl( SFX_VISIBILITY_SERVER ) )
/*?*/ 						continue;
/*?*/ 					nMode |= SFX_VISIBILITY_SERVER;
/*?*/ 				}
/*?*/ 			}
/*?*/ 
/*?*/ 			pWorkWin->SetChildWindowVisible_Impl( nId, sal_False, nMode );
/*?*/ 		}
/*?*/ 	}
/*N*/ }


/*N*/ sal_uInt32 SfxDispatcher::_Update_Impl( sal_Bool bUIActive, sal_Bool bIsMDIApp,
/*N*/ 			sal_Bool bIsIPOwner, SfxMenuBarManager *pAppMenu, SfxWorkWindow *pTaskWin )
/*N*/ {
/*N*/ 	sal_uInt32 nHelpId = 0L;
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/     SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame()->GetWorkWindow_Impl();
/*N*/ 	sal_Bool bIsActive = sal_False;
/*N*/ 	sal_Bool bIsTaskActive = sal_False;
/*N*/ 	SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
/*N*/ 	SfxDispatcher *pDispat = this;
/*N*/ 	while ( pActDispat && !bIsActive )
/*N*/ 	{
/*N*/ 		if ( pDispat == pActDispat )
/*N*/ 			bIsActive = sal_True;
/*N*/ 		pActDispat = pActDispat->pImp->pParent;
/*N*/ 	}
/*N*/ 
/*N*/     if ( pImp->pParent && !pImp->bQuiet /* && bUIActive */ )
/*N*/ 		// Das Men"u kommt immer vom obersten Dispatcher, also pAppMenu nicht weiterreichen
/*?*/ 		nHelpId = pImp->pParent->_Update_Impl( bUIActive, bIsMDIApp, bIsIPOwner, NULL, pTaskWin );
/*N*/ 
/*N*/ 	// Internen Zwischenspeicher ObjectBars und ChildWindows zur"ucksetzen
/*N*/ 	for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
/*N*/ 		pImp->aObjBars[n].aResId = ResId( 0,0 );
/*N*/ 	pImp->aChildWins.Remove(0, pImp->aChildWins.Count());
/*N*/ 
/*N*/ 	// bQuiet : eigene Shells weder f"ur UI noch f"ur SlotServer ber"ucksichtigen
/*N*/ 	// bNoUI: eigene Shells f"ur das UI nicht ber"ucksichtigen
/*N*/     if ( pImp->bQuiet || pImp->bNoUI || pImp->pFrame && pImp->pFrame->GetObjectShell()->IsPreview() )
/*N*/ 		return nHelpId;
/*N*/ 
/*N*/ 	sal_uInt16 nStatBarId=0;
/*N*/ 	SfxShell *pStatusBarShell = NULL;
/*N*/ 
/*N*/ 	sal_uInt16 nTotCount = pImp->aStack.Count();
/*N*/ 	for ( sal_uInt16 nShell = nTotCount; nShell > 0; --nShell )
/*N*/ 	{
/*N*/ 		SfxShell *pShell = GetShell( nShell-1 );
/*N*/ 		SfxInterface *pIFace = pShell->GetInterface();
/*N*/ 		if (pShell->GetHelpId())
/*N*/ 			nHelpId = pShell->GetHelpId();
/*N*/ 
/*N*/ 		// Shells von Dispatcher mit Attribut "Hidden" oder "Quiet" auslassen
/*N*/ 		sal_Bool bReadOnlyShell = IsReadOnlyShell_Impl( nShell-1 );
/*N*/ 		SfxSlotPool& rSlotPool = pIFace->GetModule() ?
/*N*/ 			*pIFace->GetModule()->GetSlotPool() : pShell->GetSlotPool_Impl();
/*N*/ 
/*N*/ 		sal_uInt16 nNo;
/*N*/ 		for ( nNo = 0; pIFace && nNo<pIFace->GetObjectBarCount(); ++nNo )
/*N*/ 		{
/*N*/ 			sal_uInt16 nPos = pIFace->GetObjectBarPos(nNo);
/*N*/             if ( ( nPos & SFX_POSITION_MASK ) == 0 )
/*N*/             {
/*N*/                 ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame >
/*N*/                     xTask( pImp->pFrame->GetFrame()->GetFrameInterface(), ::com::sun::star::uno::UNO_QUERY );
/*N*/                 if ( !xTask->isTop() )
/*N*/                     continue;
/*N*/             }
/*N*/ 
/*N*/ 			if ( bReadOnlyShell && !( nPos & SFX_VISIBILITY_READONLYDOC ) )
/*N*/ 				continue;
/*N*/ 
/*N*/ 			// Soll die ObjectBar nur angezeigt werden, wenn die Shell
/*N*/ 			// einen bestimmten UI-Modus hat?
/*N*/ 			sal_uInt32 nFeature = pIFace->GetObjectBarFeature(nNo);
/*N*/ 			if ( nFeature && !pShell->HasUIFeature( nFeature ) )
/*N*/ 				continue;
/*N*/ 
/*N*/ 			// check for toolboxes that are exclusively for a viewer
/*N*/ 			if ( pImp->pFrame)
/*N*/ 			{
/*N*/ 				BOOL bViewerTbx = SFX_VISIBILITY_VIEWER == ( nPos & SFX_VISIBILITY_VIEWER );
/*N*/ 				SfxObjectShell* pSh = pImp->pFrame->GetObjectShell();
/*N*/ 				SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, sal_False );
/*N*/ 				BOOL bIsViewer = pItem && pItem->GetValue();
/*N*/ 				if ( bIsViewer != bViewerTbx )
/*N*/ 					continue;
/*N*/ 			}
/*N*/ 
/*N*/ 			// Auf jeden Fall eintragen, auch wenn unsichtbar. Dann kann
/*N*/ 			// WorkWindow anbieten, wieder anzuschalten
/*N*/ 			sal_Bool bVisible = pIFace->IsObjectBarVisible(nNo);
/*N*/ 			if ( !bVisible )
/*N*/ 				nPos &= SFX_POSITION_MASK;
/*N*/ 
/*N*/ 			SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos & SFX_POSITION_MASK];
/*N*/ 			rBar.nMode = nPos;
/*N*/ 			rBar.aResId = pIFace->GetObjectBarResId(nNo);
/*N*/ 			const String *pName = pIFace->GetObjectBarName(nNo);
/*N*/ 			if ( pName )
/*N*/ 				rBar.aName = *pName;
/*N*/ 			else
/*N*/ 				rBar.aName.Erase();
/*N*/ 			rBar.pIFace = pIFace;
/*N*/ 
/*N*/ 			if ( bUIActive || bIsActive )
/*N*/ 			{
/*N*/ 				pWorkWin->SetObjectBar_Impl(
/*N*/ 					nPos, rBar.aResId, rBar.pIFace, &rBar.aName );
/*N*/ 			}
/*N*/ 
/*N*/ 			if ( !bVisible )
/*N*/ 				rBar.aResId = ResId( 0,0 );
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( bUIActive || bIsActive )
/*N*/ 		{
/*N*/ 			SfxConfigManager* pMgr = pImp->pFrame->GetObjectShell()->GetConfigManager();
/*N*/ 			SfxInterface* pIFace = pImp->pFrame->GetObjectShell()->GetInterface();
/*N*/ 			USHORT nMask = SFX_VISIBILITY_CLIENT | SFX_VISIBILITY_STANDARD;
/*N*/ 			if ( !pMgr )
/*N*/ 			{
/*N*/ 				pMgr = SFX_APP()->GetConfigManager_Impl();
/*N*/ 				pIFace = SFX_APP()->GetInterface();
/*N*/ 				nMask = SFX_VISIBILITY_SERVER | SFX_VISIBILITY_STANDARD;
/*N*/ 
/*N*/ 			}
/*N*/ 
/*N*/ 			for ( USHORT n=0; n<4; n++ )
/*N*/ 			{
/*N*/ 				USHORT nType = n + RID_SFX_TOOLBOX_START + 10;
/*N*/ 				if ( pMgr->HasConfigItem( nType ) )
/*?*/ 					pWorkWin->SetObjectBar_Impl( (SFX_OBJECTBAR_USERDEF1 + n) | nMask, nType, pIFace, (const String*) NULL );
/*N*/ 			}
/*N*/ 		}
/*N*/ 
/*N*/ 		for ( nNo=0; pIFace && nNo<pIFace->GetChildWindowCount(); nNo++ )
/*N*/ 		{
/*N*/ 			sal_uInt32 nId = pIFace->GetChildWindowId(nNo);
/*N*/ 			const SfxSlot *pSlot = rSlotPool.GetSlot( (sal_uInt16) nId );
/*N*/ 			DBG_ASSERT( pSlot, "Da fehlt ein Childwindow-Slot!");
/*N*/ 			if ( bReadOnlyShell )
/*N*/ 			{
/*N*/ 				// Bei read only documents nur solche ChildWindows anzeigen,
/*N*/ 				// die daf"ur freigegeben sind
/*N*/ 				if ( pSlot && !pSlot->IsMode( SFX_SLOT_READONLYDOC ) )
/*N*/ 					continue;
/*N*/ 			}
/*N*/ 
/*N*/ 			sal_uInt32 nFeature = pIFace->GetChildWindowFeature(nNo);
/*N*/ 			if ( nFeature && !pShell->HasUIFeature( nFeature ) )
/*N*/ 				continue;
/*N*/ 
/*N*/ 			// Bei den anderen auf CONTAINER/SERVER-Slots abfragen
/*N*/ 			sal_uInt16 nMode = SFX_VISIBILITY_STANDARD;
/*N*/ 			if( pSlot )
/*N*/ 			{
/*N*/ 				if ( pSlot->IsMode(SFX_SLOT_CONTAINER) )
/*N*/ 				{
/*N*/ 					if ( !pWorkWin->IsVisible_Impl( SFX_VISIBILITY_CLIENT ) )
/*N*/ 						continue;
/*N*/ 					nMode |= SFX_VISIBILITY_CLIENT;
/*N*/ 				}
/*N*/ 				else
/*N*/ 				{
/*N*/ 					if ( !pWorkWin->IsVisible_Impl( SFX_VISIBILITY_SERVER ) )
/*N*/ 						continue;
/*N*/ 					nMode |= SFX_VISIBILITY_SERVER;
/*N*/ 				}
/*N*/ 			}
/*N*/ 
/*N*/ 			if ( bUIActive || bIsActive )
/*N*/ 				pWorkWin->SetChildWindowVisible_Impl( nId, sal_True, nMode );
/*N*/ 			if ( bUIActive || bIsActive || !pWorkWin->IsFloating( (sal_uInt16) ( nId & 0xFFFF ) ) )
/*N*/ 				pImp->aChildWins.Insert( nId, pImp->aChildWins.Count());
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( pAppMenu )
/*N*/ 		{
/*N*/ 			// update Object-Menus
/*N*/ 			for ( nNo = 0; pIFace && nNo<pIFace->GetObjectMenuCount(); ++nNo )
/*N*/ 				pAppMenu->SetObjectMenu( pIFace->GetObjectMenuPos(nNo),
/*N*/ 											pIFace->GetObjectMenuResId(nNo));
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( bIsMDIApp || bIsIPOwner )
/*N*/ 		{
/*N*/ 			// Bei MDIEnvironment oder internem InPlace Statuszeile setzen
/*N*/ 			sal_uInt16 nId = pIFace->GetStatusBarResId().GetId();
/*N*/ 			if ( nId )
/*N*/ 			{
/*N*/ 				nStatBarId = nId;
/*N*/ 				pStatusBarShell =  pShell;
/*N*/ 			}
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	for ( sal_uInt16 nPos=0; nPos<SFX_OBJECTBAR_MAX; nPos++ )
/*N*/ 	{
/*N*/ 		SfxObjectBars_Impl& rFixed = pImp->aFixedObjBars[nPos];
/*N*/ 		if ( rFixed.aResId.GetId() )
/*N*/ 		{
/*?*/ 			SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos];
/*?*/ 			rBar = rFixed;
/*?*/ 			pWorkWin->SetObjectBar_Impl( rFixed.nMode,
/*?*/ 				rFixed.aResId, rFixed.pIFace, &rFixed.aName );
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( pTaskWin && ( bIsMDIApp || bIsIPOwner ) )
/*N*/ 	{
/*N*/ 		SfxDispatcher *pActDispat = pTaskWin->GetBindings().GetDispatcher_Impl();
/*N*/ 		SfxDispatcher *pDispat = this;
/*N*/ 		if ( bIsIPOwner && pImp->pFrame )
/*?*/ 			pDispat = pImp->pFrame->GetParentViewFrame_Impl()->GetDispatcher();
/*N*/ 
/*N*/ 		while ( pActDispat && !bIsTaskActive )
/*N*/ 		{
/*N*/ 			if ( pDispat == pActDispat )
/*N*/ 				bIsTaskActive = sal_True;
/*N*/ 			pActDispat = pActDispat->pImp->pParent;
/*N*/ 		}
/*N*/ 
/*N*/         if ( bIsTaskActive && nStatBarId && pImp->pFrame )
/*N*/ 		{
/*N*/ 			// Ich kontrolliere die StatusBar einer Task auch wenn ich nicht aktiv bin, aber
/*N*/ 			// zu einem internem InPlaceFrame oder einem anderen ViewFrame innerhalb der Task geh"ore
/*N*/             SfxBindings& rBindings = pImp->pFrame->GetBindings();
/*N*/ 			pTaskWin->SetStatusBar_Impl( nStatBarId, pStatusBarShell, rBindings );
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	return nHelpId;
/*N*/ }

//--------------------------------------------------------------------
/*N*/ long SfxDispatcher::UpdateObjectMenus_Impl( SfxMenuBarManager *pMenuMgr )

/*	[Beschreibung]

	Hilfsmethode zum Updaten der <Object-Menus>.
*/

/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return 0;//STRIP001 
/*N*/ }

//--------------------------------------------------------------------
/*N*/ void SfxDispatcher::FlushImpl()

/*	[Beschreibung]

	Hilfsmethode zum Ausf"uhren der ausstehenden Push- und Pop-Befehle.
*/

/*N*/ {
/*N*/ 	DBG_PROFSTART(SfxDispatcherFlush);
/*N*/ 	DBG_MEMTEST();
/*N*/ 	SFX_STACK(SfxDispatcher::FlushImpl);
/*N*/ 
/*N*/ 
/*N*/ #ifdef DBG_UTIL
/*N*/ 	ByteString aMsg( "SfxDispatcher(" );
/*N*/ 	aMsg += ByteString::CreateFromInt32( (long) this );
/*N*/ 	aMsg += ")::Flush()";
/*N*/ #endif
/*N*/ 
/*N*/ 	pImp->aTimer.Stop();
/*N*/ 
/*N*/ 	if ( pImp->pParent )
/*?*/ 		pImp->pParent->Flush();
/*N*/ 
//	if ( pImp->bQuiet )
//		return;

/*N*/ 	pImp->bFlushing = !pImp->bFlushing;
/*N*/ 	if ( !pImp->bFlushing )
/*N*/ 	{
/*?*/ 		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;
/*N*/ 	}
/*N*/ 
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 
/*N*/ 	// in der 1. Runde den echten Stack 'um'bauen
/*N*/ 	SfxToDoStack_Impl aToDoCopy;
/*N*/ 	sal_Bool bModify = sal_False;
/*N*/ 	short nToDo;
/*N*/ 	for ( nToDo = pImp->aToDoStack.Count()-1; nToDo >= 0; --nToDo )
/*N*/ 	{
/*N*/ 		bModify = sal_True;
/*N*/ 
/*N*/ 		SfxToDo_Impl aToDo( pImp->aToDoStack.Top(nToDo) );
/*N*/ 		if ( aToDo.bPush )
/*N*/ 		{
/*N*/ 			// tats"aechlich pushen
/*N*/ 			DBG_ASSERT( !pImp->aStack.Contains( aToDo.pCluster ),
/*N*/ 						"pushed SfxShell already on stack" );
/*N*/ 			pImp->aStack.Push( aToDo.pCluster );
/*N*/ 			aToDo.pCluster->SetDisableFlags( pImp->nDisableFlags );
/*N*/ 
/*N*/ 			// die bewegte Shell merken
/*N*/ 			aToDoCopy.Push( aToDo );
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/ 			// tats"aechlich poppen
/*N*/ 			SfxShell* pPopped = 0;
/*N*/ 			FASTBOOL bFound = sal_False;
/*N*/ 			do
/*N*/ 			{
/*N*/ 				DBG_ASSERT( pImp->aStack.Count(), "popping from empty stack" );
/*N*/ 				pPopped = pImp->aStack.Pop();
/*N*/ 				pPopped->SetDisableFlags( 0 );
/*N*/ 				bFound = pPopped == aToDo.pCluster;
/*N*/ 
/*N*/ 				// die bewegte Shell merken
/*N*/ 				aToDoCopy.Push( SfxToDo_Impl( sal_False, aToDo.bDelete, sal_False, *pPopped) );
/*N*/ 			}
/*N*/ 			while ( aToDo.bUntil && !bFound );
/*N*/ 			DBG_ASSERT( bFound, "wrong SfxShell popped" );
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( nToDo == 0 )
/*N*/ 			pImp->aToDoStack.Clear();
/*N*/ 	}
/*N*/ 
/*N*/ 	// ggf. Bindings invalidieren
/*N*/ 	if ( !pSfxApp->IsDowning() )
/*N*/ 	{
/*N*/ 		if ( bModify )
/*N*/ 		{
/*N*/ 			pImp->pCachedServ1 = 0;
/*N*/ 			pImp->pCachedServ2 = 0;
/*N*/ 		}
/*N*/ 
/*N*/ 		InvalidateBindings_Impl( bModify );
/*N*/ 	}
/*N*/ 
/*N*/ 	pImp->bFlushing = sal_False;
/*N*/ 	pImp->bUpdated = sal_False; // nicht nur bei bModify, falls Doc/Template-Config
/*N*/ 	bFlushed = sal_True;
/*N*/ 
/*N*/ 	// in der 2. Runde die Shells aktivieren und ggf. l"oschen
/*N*/ 	for ( nToDo = aToDoCopy.Count()-1; nToDo >= 0; --nToDo )
/*N*/ 	{
/*N*/ 		SfxToDo_Impl aToDo( aToDoCopy.Top(nToDo) );
/*N*/ 		if ( aToDo.bPush )
/*N*/ 		{
/*N*/ 			if ( pImp->bActive )
/*N*/ 				aToDo.pCluster->DoActivate(pImp->pFrame, sal_True);
/*N*/ 		}
/*N*/ 		else
/*N*/ 			if ( pImp->bActive )
/*N*/ 				aToDo.pCluster->DoDeactivate(pImp->pFrame, sal_True);
/*N*/ 	}
/*N*/ 	for ( nToDo = aToDoCopy.Count()-1; nToDo >= 0; --nToDo )
/*N*/ 	{
/*N*/ 		SfxToDo_Impl aToDo( aToDoCopy.Top(nToDo) );
/*N*/ 		if ( aToDo.bDelete ) delete aToDo.pCluster;
/*N*/ 	}
/*N*/ 	sal_Bool bAwakeBindings = aToDoCopy.Count() != 0;
/*N*/ 	if( bAwakeBindings )
/*N*/ 		aToDoCopy.Clear();
/*N*/ 
/*N*/ 	// Wenn bei Activate/Deactivate/Delete weitere Stackbewegungen erfolgt sind :
/*N*/ 	if (!bFlushed)
/*N*/ 		// falls jemand Push/Pop gerufen hat, wurde auch EnterReg gerufen!
/*?*/ 		FlushImpl();
/*N*/ 
/*N*/     if( bAwakeBindings && GetBindings() )
/*N*/ 		GetBindings()->DLEAVEREGISTRATIONS();
/*N*/ 	DBG_PROFSTOP(SfxDispatcherFlush);
/*N*/ 
/*N*/ 	for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
/*N*/ 		pImp->aFixedObjBars[n].aResId = ResId( 0,0 );
/*N*/ 
/*N*/ #ifdef DBG_UTIL
/*N*/ 	aMsg += " done";
/*N*/ 	DbgTrace( aMsg.GetBuffer() );
/*N*/ #endif
/*N*/ }

//--------------------------------------------------------------------

/*	[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();
*/


//--------------------------------------------------------------------
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) );
/*?*/ }

//--------------------------------------------------------------------
/*N*/ 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
*/

/*N*/ {
/*N*/ 	// kein Filter?
/*N*/ 	if ( 0 == pImp->nFilterCount )
/*N*/ 		// => alle SIDs erlaubt
/*N*/ 		return sal_True;
/*N*/ 
/*N*/ 	// suchen
/*N*/ 	sal_Bool bFound = 0 != bsearch( &nSID, pImp->pFilterSIDs, pImp->nFilterCount,
/*N*/ 								sizeof(sal_uInt16), SfxCompareSIDs_Impl );
/*N*/ 
/*N*/ 	// even if ReadOnlyDoc
/*?*/ 	if ( 2 == pImp->bFilterEnabling )
/*?*/ 		return bFound ? 2 : 1;
/*?*/ 	// sonst je nach Negativ/Positiv Filter
/*?*/ 	return pImp->bFilterEnabling ? bFound : !bFound;
/*N*/ }

//--------------------------------------------------------------------

/*N*/ sal_Bool SfxDispatcher::_FindServer
/*N*/ (
/*N*/ 	sal_uInt16				nSlot,		// zu suchende Slot-Id
/*N*/ 	SfxSlotServer&	 rServer,	 // zu f"uellnde <SfxSlotServer>-Instanz
/*N*/ 	sal_Bool				bModal		// trotz ModalMode
/*N*/ )

/*	[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.
*/

/*N*/ {
/*N*/ 	SFX_STACK(SfxDispatcher::_FindServer);
/*N*/ 
/*N*/ 	// Dispatcher gelockt? (SID_BROWSE_STOP und SID_HELP_PI trotzdem durchlassen)
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 	sal_Bool bAllLocked = pSfxApp->IsDispatcherLocked();
/*N*/ 	if ( IsLocked(nSlot) )
/*N*/ 	{
/*N*/ 		if ( bAllLocked )
/*?*/ 			pSfxApp->Get_Impl()->bInvalidateOnUnlock = sal_True;
/*N*/ 		pImp->bInvalidateOnUnlock = sal_True;
/*N*/ 		return sal_False;
/*N*/ 	}
/*N*/ 
/*N*/ 	// Anzahl der Shells auf den verkettenten Dispatchern z"ahlen
/*N*/ 	Flush();
/*N*/ 	sal_uInt16 nTotCount = pImp->aStack.Count();
/*N*/ 	if ( pImp->pParent )
/*N*/ 	{
/*?*/ 		SfxDispatcher *pParent = pImp->pParent;
/*?*/ 		while ( pParent )
/*?*/ 		{
/*?*/ 			nTotCount += pParent->pImp->aStack.Count();
/*?*/ 			pParent = pParent->pImp->pParent;
/*?*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	// Makro-Slot?
/*N*/ 	if ( SfxMacroConfig::IsMacroSlot( nSlot ) )
/*N*/ 	{
/*?*/ 		DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SfxMacroInfo* pInfo = pSfxApp->GetMacroConfig()->GetMacroInfo(nSlot);
/*N*/ 	}
/*N*/ 	// Verb-Slot?
/*N*/ 	else if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
/*N*/ 	{
/*?*/ 		SfxShell *pSh = 0;
/*?*/ 		for ( sal_uInt16 nShell = 0; pSh = GetShell(nShell); ++nShell )
/*?*/ 		{
/*?*/ 			if ( pSh->ISA(SfxViewShell) )
/*?*/ 			{
/*?*/                 const SfxSlot* pSlot = pSh->GetVerbSlot_Impl(nSlot);
/*?*/                 if ( pSlot )
/*?*/                 {
/*?*/                     rServer.SetShellLevel(nShell);
/*?*/                     rServer.SetSlot( pSlot );
/*?*/                     return sal_True;
/*?*/                 }
/*?*/ 			}
/*?*/ 		}
/*?*/ 
/*?*/ 		return sal_False;
/*N*/ 	}

/*N*/ 	// SID gegen gesetzten Filter pr"ufen
/*N*/ 	sal_uInt16 nSlotEnableMode=0;
/*N*/ 	if ( pImp->pFrame )
/*N*/ 	{
/*N*/ 		nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
/*N*/ 		if ( 0 == nSlotEnableMode )
/*?*/ 			return sal_False;
/*N*/ 	}
/*N*/ 
/*N*/ 	// im Quiet-Mode nur Parent-Dispatcher
/*N*/ 	if ( pImp->bQuiet )
/*N*/ 	{
/*?*/ 		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;
/*N*/ 	}
/*N*/ 
/*N*/ 	sal_Bool bReadOnly = ( 2 != nSlotEnableMode && pImp->bReadOnly ) ||
/*N*/ 				( pImp->pFrame && pImp->pFrame->GetObjectShell() &&
/*N*/ 				  pImp->pFrame->GetObjectShell()->IsLoading() );

	// durch alle Shells der verketteten Dispatchern von oben nach unten suchen
/*N*/ #ifdef DBG_UTILx
/*N*/ 	String aStack( "Stack:" );
/*N*/ #endif
/*N*/ 	sal_uInt16 nFirstShell = pImp->bModal && !bModal ? pImp->aStack.Count() : 0;
/*N*/ 	for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
/*N*/ 	{
/*N*/ 		SfxShell *pObjShell = GetShell(i);
/*N*/ 		SfxInterface *pIFace = pObjShell->GetInterface();
/*N*/ 		const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
/*N*/ 
/*N*/ 		if ( pSlot && pSlot->nDisableFlags && ( pSlot->nDisableFlags & pObjShell->GetDisableFlags() ) != 0 )
/*N*/ 			return sal_False;
/*N*/ 
/*N*/ 		if ( pSlot && !( pSlot->nFlags & SFX_SLOT_READONLYDOC ) && bReadOnly )
/*N*/ 			return sal_False;
/*N*/ 
/*N*/ 		if ( pSlot )
/*N*/ 		{
/*N*/ 			// Slot geh"ort zum Container?
/*N*/ 			FASTBOOL bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
/*N*/ 			FASTBOOL bIsInPlace = pImp->pFrame && pImp->pFrame->ISA( SfxInPlaceFrame );
/*N*/ 
/*N*/ 			// Shell geh"ort zum Server?
/*N*/ 			// AppDispatcher oder IPFrame-Dispatcher
/*N*/ 			FASTBOOL bIsServerShell = !pImp->pFrame || bIsInPlace;
/*N*/ 
/*N*/ 			// Nat"urlich sind ServerShell-Slots auch ausf"uhrbar, wenn sie auf
/*N*/ 			// einem Container-Dispatcher ohne IPClient ausgef"uhrt werden sollen.
/*N*/ 			if ( !bIsServerShell )
/*N*/ 			{
/*N*/ 				SfxViewShell *pViewSh = pImp->pFrame->GetViewShell();
/*N*/ 				bIsServerShell = !pViewSh || !pViewSh->GetIPClient();
/*N*/ 			}
/*N*/ 
/*N*/ 			// Shell geh"ort zum Container?
/*N*/ 			// AppDispatcher oder kein IPFrameDispatcher
/*N*/ 			FASTBOOL bIsContainerShell = !pImp->pFrame || !bIsInPlace;
/*N*/ #ifdef MBA
/*N*/ 			if ( !bIsContainerShell )
/*N*/ 			{
/*N*/ 				// Bei internem InPlace auch den AppDispatcher zug"angig machen
/*N*/ 				if ( pImp->pFrame && pImp->pFrame->GetParentViewFrame_Impl() )
/*N*/ 				{
/*N*/ 					if ( i == nTotCount - 1 )
/*N*/ 						bIsContainerShell = sal_True;
/*N*/ 				}
/*N*/ 			}
/*N*/ #endif
/*N*/ 			// Shell und Slot passen zusammen
/*N*/ 			if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
/*N*/ 					( !bIsContainerSlot && bIsServerShell ) ) )
/*N*/ 				pSlot = 0;
/*N*/ 		}
/*N*/ 
/*N*/ #ifdef DBG_UTILx
/*N*/ 		if ( pSlot )
/*N*/ 		{
/*N*/ 			String aMsg( nSlot );
/*N*/ 			aMsg += " found in ";
/*N*/ 			aMsg += pObjShell->GetInterface()->GetClassName();
/*N*/ 			DbgTrace( aMsg.GetBuffer() );
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/ 			aStack += " ";
/*N*/ 			aStack += pObjShell->GetInterface()->GetClassName();
/*N*/ 		}
/*N*/ #endif
/*N*/ 		if ( pSlot && !IsAllowed( nSlot ) )
/*N*/ 		{
/*N*/ 			pSlot = NULL;
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( pSlot )
/*N*/ 		{
/*N*/ 			rServer.SetSlot(pSlot);
/*N*/ 			rServer.SetShellLevel(i);
/*N*/ 			return sal_True;
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ #ifdef DBG_UTILx
/*N*/ 	String aMsg( nSlot );
/*N*/ 	aMsg += " not found in ";
/*N*/ 	aMsg += aStack;
/*N*/ 	DbgTrace( aMsg.GetBuffer() );
/*N*/ #endif
/*N*/ 	return sal_False;
/*N*/ }
//--------------------------------------------------------------------
/*N*/ sal_Bool SfxDispatcher::_FillState
/*N*/ (
/*N*/ 	const SfxSlotServer& rSvr,		 // abzufragende <Slot-Server>
/*N*/ 	SfxItemSet& 			rState, 	// zu f"ullendes <SfxItemSet>
/*N*/ 	const SfxSlot*			pRealSlot	// ggf. der tats"achliche Slot
/*N*/ )

/*	[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.
*/

/*N*/ {
/*N*/ 	SFX_STACK(SfxDispatcher::_FillState);
/*N*/ 
/*N*/ 	DBG_PROFSTART(SfxDispatcherFillState);
/*N*/ 
/*N*/ 	const SfxSlot *pSlot = rSvr.GetSlot();
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 	sal_Bool bAllLocked = pSfxApp->IsDispatcherLocked();
/*N*/ 	if ( pSlot && IsLocked( pSlot->GetSlotId() ) )
/*N*/ 	{
/*N*/ 		if ( bAllLocked )
/*?*/ 			pSfxApp->Get_Impl()->bInvalidateOnUnlock = sal_True;
/*N*/ 		pImp->bInvalidateOnUnlock = sal_True;
/*N*/ 		DBG_PROFSTOP(SfxDispatcherFillState);
/*N*/ 		return sal_False;
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( pSlot )
/*N*/ 	{
/*N*/ 		Flush();
/*N*/ 
/*N*/ 		// Objekt ermitteln und Message an diesem Objekt aufrufen
/*N*/ 		SfxShell *pSh = GetShell(rSvr.GetShellLevel());
/*N*/ 		DBG_ASSERT(pSh, "ObjektShell nicht gefunden");
/*N*/ 
/*N*/ 		SfxStateFunc pFunc;
/*N*/ 
/*N*/ 		if (pRealSlot)
/*N*/ 			pFunc = pRealSlot->GetStateFnc();
/*N*/ 		else
/*N*/ 			pFunc = pSlot->GetStateFnc();
/*N*/ 
/*N*/ 		pSh->CallState( pFunc, rState );
/*N*/ #ifdef DBG_UTIL
/*N*/ 		// pr"ufen, ob IDL (SlotMap) und aktuelle Items "ubereinstimmen
/*N*/ 		if ( DbgIsAssertWarning() && rState.Count() )
/*N*/ 		{
/*?*/ 			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__);
/*?*/ 					}
/*?*/ 				}
/*N*/ 		}
/*N*/ #endif
/*N*/ 
/*N*/ 		DBG_PROFSTOP(SfxDispatcherFillState);
/*N*/ 		return sal_True;
/*N*/ 	}
/*N*/ 
/*N*/ 	DBG_PROFSTOP(SfxDispatcherFillState);
/*N*/ 	return sal_False;
/*N*/ }

//--------------------------------------------------------------------
/*?*/ const SfxPoolItem* SfxDispatcher::_Execute( const SfxSlotServer &rSvr )

/*  [Beschreibung]

	Diese Methode f"uhrt einen Request "uber einen gecachten <Slot-Server>
	aus.
*/

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ 	return 0;
/*?*/ }

//----------------------------------------------------------------------
/*?*/ void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId,
/*?*/ 								  Window *pWin, const Point *pPos,
/*?*/ 								  const SfxPoolItem *pArg1, ... )
/*?*/ {
DBG_BF_ASSERT(0, "STRIP"); //STRIP001     ExecutePopup( nConfigId, pWin, pPos );
/*?*/ }

//----------------------------------------------------------------------
/*?*/ void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId, Window *pWin, const Point *pPos )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*
	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;
		}
    }
*/
/*?*/ }

//----------------------------------------------------------------------
/*?*/ void SfxDispatcher::ExecutePopup( const ResId &rId, Window *pWin, const Point *pPos )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*
	SfxPopupMenuManager aPop( rId, *GetBindings() );
	aPop.AddClipboardFunctions();
	aPop.Initialize();
	aPop.RemoveDisabledEntries();
    aPop.Execute( pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
*/
/*?*/ }

//--------------------------------------------------------------------
/*N*/ 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.
*/

/*N*/ {
/*N*/     SfxBindings* pBindings = GetBindings();
/*N*/ 	if ( !bLock && pImp->bLocked && pImp->bInvalidateOnUnlock )
/*N*/ 	{
/*N*/         if ( pBindings )
/*N*/             pBindings->InvalidateAll(sal_True);
/*N*/ 		pImp->bInvalidateOnUnlock = sal_False;
/*N*/ 	}
/*N*/     else if ( pBindings )
/*N*/         pBindings->InvalidateAll(sal_False);
/*N*/ 	pImp->bLocked = bLock;
/*N*/ }

//--------------------------------------------------------------------
/*?*/ void SfxDispatcher::ShowObjectBar(sal_uInt16 nId, SfxShell *pShell) const

/*  [Beschreibung]

	Mit dieser Methode kann auf einer Objektleistenposition gezielt eine
	bestimmte Objektleiste eingeblendet werden.
*/

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

/*N*/ sal_uInt16 SfxDispatcher::GetObjectBarId( sal_uInt16 nPos ) const
/*N*/ {
/*N*/ 	return pImp->aObjBars[nPos].aResId.GetId();
/*N*/ }

//--------------------------------------------------------------------
/*?*/ void SfxDispatcher::ResetObjectBars_Impl()

/*  [Beschreibung]

	Mit dieser Methode werden alle Objectbar-Anforderungen, die dieser
	Dispatcher an das AppWindow hat, beseitigt.
*/
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }


//--------------------------------------------------------------------
/*?*/ void SfxDispatcher::DebugOutput_Impl() const
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

/*?*/ void SfxDispatcher::LockUI_Impl( sal_Bool bLock )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

//-------------------------------------------------------------------------
/*N*/ void SfxDispatcher::HideUI( sal_Bool bHide )
/*N*/ {
//	if ( !bHide && pImp->bReadOnly )
//		bHide = sal_True;
/*N*/ 	sal_Bool bWasHidden = pImp->bNoUI;
/*N*/ 	pImp->bNoUI = bHide;
/*N*/ 	if ( bHide != bWasHidden )
/*?*/ 		Update_Impl( sal_True );
/*N*/ }

/*N*/ void SfxDispatcher::SetReadOnly_Impl( sal_Bool bOn )
/*N*/ {
/*N*/ 	pImp->bReadOnly = bOn;
/*N*/ //	pImp->bNoUI = bOn;
/*N*/ }

/*N*/ sal_Bool SfxDispatcher::GetReadOnly_Impl() const
/*N*/ {
/*N*/ 	return pImp->bReadOnly;
/*N*/ }

//-------------------------------------------------------------------------
/*?*/ void SfxDispatcher::SetQuietMode_Impl( sal_Bool bOn )

/*	[Beschreibung]

	Bei 'bOn' stellt sich dieser Dispatcher quasi tot und leitet alles
	an den Parent-Dispatcher weiter.
*/

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

//-------------------------------------------------------------------------
/*?*/ void SfxDispatcher::SetModalMode_Impl( sal_Bool bOn )

/*	[Beschreibung]

	Bei 'bOn' werden nur noch Slots des Parent-Dispatchers gefunden.
*/

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

/*N*/ void SfxDispatcher::SetExecuteMode( sal_uInt16 nMode )
/*N*/ {
/*N*/ 	pImp->nStandardMode = nMode;
/*N*/ }

/*N*/ SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSlot, const SfxPoolItem* &rpState )
/*N*/ {
/*N*/ 	SfxShell *pShell = 0;
/*N*/ 	const SfxSlot *pSlot = 0;
/*N*/ 	if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False, sal_False ) )
/*N*/ 	{
/*N*/ 		rpState = pShell->GetSlotState(nSlot);
/*N*/ 		if ( !rpState )
/*N*/ 			return SFX_ITEM_DISABLED;
/*N*/ 		else
/*N*/ 			return SFX_ITEM_AVAILABLE;
/*N*/ 	}
/*N*/ 
/*N*/ 	return SFX_ITEM_DISABLED;
/*N*/ }

/*N*/ sal_Bool SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell ) const
/*N*/ {
/*N*/ 	sal_uInt16 nShellCount = pImp->aStack.Count();
/*N*/ 	if ( nShell < nShellCount )
/*N*/ 	{
/*N*/         SfxShell* pShell = pImp->aStack.Top( nShell );
/*N*/         if( pShell->ISA( SfxModule ) || pShell->ISA( SfxApplication ) || pShell->ISA( SfxViewFrame ) )
/*N*/             return sal_False;
/*N*/         else
/*N*/             return pImp->bReadOnly;
/*N*/ 	}
/*?*/ 	else if ( pImp->pParent )
/*?*/ 		return pImp->pParent->IsReadOnlyShell_Impl( nShell - nShellCount );
/*?*/ 	return sal_True;
/*N*/ }

// 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 )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

/*N*/ void SfxDispatcher::RemoveShell_Impl( SfxShell& rShell )
/*N*/ {
/*N*/ 	Flush();
/*N*/ 
/*N*/ 	// Der cast geht, weil SfxShellStack_Impl keine eigenen member hat
/*N*/ 	StackAccess_Impl& rStack = *((StackAccess_Impl*) (&pImp->aStack));
/*N*/ 	sal_uInt16 nCount = rStack.Count();
/*N*/ 	for ( sal_uInt16 n=0; n<nCount; ++n )
/*N*/ 	{
/*N*/ 		if ( rStack[n] == &rShell )
/*N*/ 		{
/*N*/ 			rStack.Remove( n );
/*N*/ 			rShell.SetDisableFlags( 0 );
/*N*/ 			rShell.DoDeactivate(pImp->pFrame, sal_True);
/*N*/ 			break;
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( !SFX_APP()->IsDowning() )
/*N*/ 	{
/*N*/ 		pImp->bUpdated = sal_False;
/*N*/ 		pImp->pCachedServ1 = 0;
/*N*/ 		pImp->pCachedServ2 = 0;
/*N*/ 		InvalidateBindings_Impl(sal_True);
/*N*/ 	}
/*N*/ }

/*N*/ sal_Bool SfxDispatcher::IsAllowed
/*N*/ (
/*N*/ 	sal_uInt16 nSlot
/*N*/ ) const
/*
	[Beschreibung]
	Die Methode prueft, ob der Zugriff auf diese Schnittstelle erlaubt ist.
	*/
/*N*/ {
/*N*/ 	if ( !pImp->pDisableList )
/*N*/ 	{
/*N*/ 		return sal_True;
/*N*/ 	}

	// BinSearch in der DisableListe
/*?*/ 	SvUShorts& rList = *pImp->pDisableList;
/*?*/ 	sal_uInt16 nCount = rList.Count();
/*?*/ 	sal_uInt16 nLow = 0, nMid, 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;
/*?*/ 	}
/*?*/ 
/*?*/ 	// 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], "" );
/*?*/ 
/*?*/ 	return !bFound;
/*N*/ }

/*N*/ void SfxDispatcher::InvalidateBindings_Impl( sal_Bool bModify )
/*N*/ {
/*N*/ 	// App-Dispatcher?
/*N*/ 	if ( IsAppDispatcher() )
/*N*/ 	{
/*N*/ 		for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst();
/*N*/ 				pFrame;
/*N*/ 				pFrame = SfxViewFrame::GetNext( *pFrame ) )
/*?*/ 			pFrame->GetBindings().InvalidateAll(bModify);
/*
		// alle Bindings sind betroffen
		for ( SfxInPlaceFrame *pIPFrame = (SfxInPlaceFrame*)
					SfxViewFrame::GetFirst(0, TYPE(SfxInPlaceFrame));
				pIPFrame;
				pIPFrame = (SfxInPlaceFrame*)
					SfxViewFrame::GetNext(*pIPFrame, 0, TYPE(SfxInPlaceFrame)) )
			pIPFrame->GetBindings().InvalidateAll(bModify);

		for ( SfxPlugInFrame *pPIFrame = (SfxPlugInFrame*)
					SfxViewFrame::GetFirst(0, TYPE(SfxPlugInFrame));
				pPIFrame;
				pPIFrame = (SfxPlugInFrame*)
					SfxViewFrame::GetNext(*pPIFrame, 0, TYPE(SfxPlugInFrame)) )
			pPIFrame->GetBindings().InvalidateAll(bModify);

		for ( SfxTask* pTask = SfxTask::GetFirst(); pTask;
				pTask = SfxTask::GetNext( *pTask ) )
			if ( !pTask->IsExternal() )
				pTask->GetBindings()->InvalidateAll(bModify);
*/
/*N*/ 	}
/*N*/ 	else
/*N*/ 	{
/*N*/ 		SfxDispatcher *pDisp = GetBindings()->GetDispatcher_Impl();
/*N*/ 		while ( pDisp )
/*N*/ 		{
/*N*/ 			if ( pDisp == this )
/*N*/ 			{
/*N*/ 				GetBindings()->InvalidateAll( bModify );
/*N*/ 				break;
/*N*/ 			}
/*N*/ 
/*?*/ 			pDisp = pDisp->pImp->pParent;
/*N*/ 		}
/*N*/ 	}
/*N*/ }

/*N*/ sal_uInt16 SfxDispatcher::GetNextToolBox_Impl( sal_uInt16 nPos, sal_uInt16 nType, String *pStr )
/*N*/ {
/*N*/ 	SfxShell *pShell;
/*N*/ 	sal_Bool bReadOnly = sal_False;
/*N*/ 	SfxViewFrame *pFrame = pImp->pFrame;
/*N*/ 	if ( pFrame )
/*N*/ 	{
/*N*/ 		SfxObjectShell *pObj = pFrame->GetObjectShell();
/*N*/ 		bReadOnly =  !pObj || pObj->IsReadOnly();
/*N*/ 	}
/*N*/ 
/*N*/ 	sal_Bool bFound = sal_False;
/*N*/ 	SfxWorkWindow *pWorkWin = GetBindings()->GetWorkWindow_Impl();
/*N*/ 
/*N*/ 	// Wenn die aktuelle Toolbox die letzte ist, mu\s die erste zur"uckgegeben
/*N*/ 	// werden
/*N*/ 	sal_uInt16 nNext = 0;
/*N*/ 
/*N*/ 	if ( nPos != 0xFFFF )
/*N*/ 	{
/*N*/ 		SfxDispatcher *pDispat = this;
/*N*/ 		while ( pDispat )
/*N*/ 		{
/*N*/             SfxBindings* pBindings = pDispat->GetBindings();
/*N*/             if ( !pBindings || pBindings->GetWorkWindow_Impl() != pWorkWin )
/*N*/ 				break;
/*N*/ 
/*N*/ 			sal_uInt16 nCount = pDispat->pImp->aStack.Count();
/*N*/ 			// Alle interfaces auf dem Dispatcher-Stack durchsuchen
/*N*/ 			for ( sal_uInt16 nIdx=0; nIdx<nCount; nIdx++ )
/*N*/ 			{
/*N*/ 				pShell = pDispat->pImp->aStack.Top(nIdx);
/*N*/ 				const SfxInterface *pInterFace = pShell->GetInterface();
/*N*/ 				for ( sal_uInt16 nNo = 0; pInterFace && nNo<pInterFace->GetObjectBarCount(); ++nNo )
/*N*/ 				{
/*N*/ 					// Ist die Objectbar an der richtigen Position und sichtbar ?
/*N*/ 					sal_uInt16 nP = pInterFace->GetObjectBarPos(nNo);
/*N*/ 
/*N*/ 					if ( (nP & SFX_POSITION_MASK) == (nPos & SFX_POSITION_MASK) &&
/*N*/ 							pInterFace->IsObjectBarVisible(nNo) &&
/*N*/ 						( !bReadOnly || ( nP & SFX_VISIBILITY_READONLYDOC ) ) )
/*N*/ 					{
/*N*/ 						sal_uInt16 nId = pInterFace->GetObjectBarResId(nNo).GetId();
/*N*/ 						if ( nId != nType )
/*N*/ 						{
/*N*/ 							// Es ist eine andere Toolbox
/*N*/ 							// Ist sie aktivierbar ?
/*N*/ 							sal_uInt32 nFeature = pInterFace->GetObjectBarFeature( nNo );
/*N*/ 							if ( nFeature && !pShell->HasUIFeature( nFeature ) )
/*N*/ 								continue;
/*N*/ 
/*N*/ 							// check for toolboxes that are exclusively for a viewer
/*N*/ 							if ( pImp->pFrame)
/*N*/ 							{
/*N*/ 								BOOL bViewerTbx = SFX_VISIBILITY_VIEWER == ( nP & SFX_VISIBILITY_VIEWER );
/*N*/ 								SfxObjectShell* pSh = pImp->pFrame->GetObjectShell();
/*N*/ 								SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, sal_False );
/*N*/ 								BOOL bIsViewer = pItem && pItem->GetValue();
/*N*/ 								if ( bIsViewer != bViewerTbx )
/*N*/ 									continue;
/*N*/ 							}
/*N*/ 
/*N*/ 							// Kommt sie nach der aktuellen ?
/*N*/ 							if ( bFound )
/*N*/ 							{
/*N*/ 								// Ja, also ist sie die n"achste
/*N*/ 								if ( pStr )
/*N*/ 									*pStr = *pInterFace->GetObjectBarName( nNo );
/*N*/ 								return nId;
/*N*/ 							}
/*N*/ 							else if ( !nNext )
/*N*/ 							{
/*?*/ 								// Nein, aber vielleicht ist es die erste ?
/*?*/ 								nNext = nId;
/*?*/ 								if ( pStr )
/*?*/ 									*pStr = *pInterFace->GetObjectBarName( nNo );
/*N*/ 							}
/*N*/ 						}
/*N*/ 						else
/*N*/ 							// das ist die aktuelle!
/*N*/ 							bFound = sal_True;
/*N*/ 					}
/*N*/ 				}
/*N*/ 			}
/*N*/ 
/*N*/ 			pDispat = pDispat->pImp->pParent;
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	return nNext;
/*N*/ }

/*N*/ sal_Bool SfxDispatcher::IsUpdated_Impl() const
/*N*/ {
/*N*/ 	return pImp->bUpdated;
/*N*/ }

/*N*/ void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags )
/*N*/ {
/*N*/ 	pImp->nDisableFlags = nFlags;
/*N*/ 	for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
/*N*/ 		pImp->aStack.Top( (sal_uInt16) i )->SetDisableFlags( nFlags );
/*N*/ }

/*N*/ sal_uInt32 SfxDispatcher::GetDisableFlags() const
/*N*/ {
/*N*/ 	return pImp->nDisableFlags;
/*N*/ }

/*N*/ sal_Bool SfxDispatcher::HasSlot_Impl( sal_uInt16 nSlot )
/*N*/ {
/*N*/ 	Flush();
/*N*/ 	sal_uInt16 nTotCount = pImp->aStack.Count();
/*N*/ 
/*N*/     if ( pImp->pParent && !pImp->pParent->pImp->pFrame )
/*N*/     {
/*N*/         // the last frame also uses the AppDispatcher
/*N*/         nTotCount += pImp->aStack.Count();
/*N*/     }
/*N*/ 
/*N*/ 	if ( SfxMacroConfig::IsMacroSlot( nSlot ) )
/*N*/         // Makro-Slot?
/*N*/ 		return sal_True;
/*N*/ 	else if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
/*?*/ /*N*/ 	{
/*?*/         // Verb-Slot?
/*?*/ 		SfxShell *pSh = 0;
/*?*/ 		for ( sal_uInt16 nShell = 0; pSh = GetShell(nShell); ++nShell )
/*?*/ 		{
/*?*/ 			if ( pSh->ISA(SfxViewShell) )
/*?*/ 				return sal_True;
/*?*/ 		}
/*?*/ 
/*?*/ 		return sal_False;
/*N*/ 	}
/*N*/ 
/*N*/ 	// SID gegen gesetzten Filter pr"ufen
/*N*/ 	sal_uInt16 nSlotEnableMode=0;
/*N*/ 	if ( pImp->pFrame )
/*N*/ 	{
/*N*/ 		nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
/*N*/ 		if ( 0 == nSlotEnableMode )
/*N*/ 			return sal_False;
/*N*/ 	}
/*N*/ 
/*N*/ 	// im Quiet-Mode nur Parent-Dispatcher
/*N*/ 	if ( pImp->bQuiet )
/*N*/ 		return sal_False;
/*N*/ 
/*N*/ 	sal_Bool bReadOnly = ( 2 != nSlotEnableMode && pImp->bReadOnly ) ||
/*N*/ 				( pImp->pFrame && pImp->pFrame->GetObjectShell() &&
/*N*/ 				  pImp->pFrame->GetObjectShell()->IsLoading() );
/*N*/ 
/*N*/ 	for ( sal_uInt16 i=0 ; i < nTotCount; ++i )
/*N*/ 	{
/*N*/ 		SfxShell *pObjShell = GetShell(i);
/*N*/ 		SfxInterface *pIFace = pObjShell->GetInterface();
/*N*/ 		const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
/*N*/ 		if ( pSlot && pSlot->nDisableFlags && ( pSlot->nDisableFlags & pObjShell->GetDisableFlags() ) != 0 )
/*N*/ 			return sal_False;
/*N*/ 
/*N*/ 		if ( pSlot && !( pSlot->nFlags & SFX_SLOT_READONLYDOC ) && bReadOnly )
/*N*/ 			return sal_False;
/*N*/ 
/*N*/ 		if ( pSlot )
/*N*/ 		{
/*N*/ 			// Slot geh"ort zum Container?
/*N*/ 			FASTBOOL bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
/*N*/ 			FASTBOOL bIsInPlace = pImp->pFrame && pImp->pFrame->ISA( SfxInPlaceFrame );
/*N*/ 
/*N*/ 			// Shell geh"ort zum Server?
/*N*/ 			// AppDispatcher oder IPFrame-Dispatcher
/*N*/ 			FASTBOOL bIsServerShell = !pImp->pFrame || bIsInPlace;
/*N*/ 
/*N*/ 			// Nat"urlich sind ServerShell-Slots auch ausf"uhrbar, wenn sie auf
/*N*/ 			// einem Container-Dispatcher ohne IPClient ausgef"uhrt werden sollen.
/*N*/ 			if ( !bIsServerShell )
/*N*/ 			{
/*N*/ 				SfxViewShell *pViewSh = pImp->pFrame->GetViewShell();
/*N*/ 				bIsServerShell = !pViewSh || !pViewSh->GetIPClient();
/*N*/ 			}
/*N*/ 
/*N*/ 			// Shell geh"ort zum Container?
/*N*/ 			// AppDispatcher oder kein IPFrameDispatcher
/*N*/ 			FASTBOOL bIsContainerShell = !pImp->pFrame || !bIsInPlace;
/*N*/ 
/*N*/ 			// Shell und Slot passen zusammen
/*N*/ 			if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
/*N*/ 					( !bIsContainerSlot && bIsServerShell ) ) )
/*N*/ 				pSlot = 0;
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( pSlot && !IsAllowed( nSlot ) )
/*N*/ 			pSlot = NULL;
/*N*/ 
/*N*/ 		if ( pSlot )
/*N*/ 			return sal_True;
/*N*/ 	}
/*N*/ 
/*N*/ 	return sal_False;
/*N*/ }


}
