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



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"
#include <com/sun/star/embed/VerbDescriptor.hpp>
#include <com/sun/star/embed/VerbAttributes.hpp>
#include <basic/sbstar.hxx>
#include <svl/itempool.hxx>
#include <svl/undo.hxx>
#include <svtools/itemdel.hxx>
#include <svtools/asynclink.hxx>
#include <basic/sbx.hxx>

#include <unotools/undoopt.hxx>

#ifndef GCC
#endif

#include <sfx2/app.hxx>
#include <sfx2/shell.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/dispatch.hxx>
#include "sfxtypes.hxx"
#include <sfx2/request.hxx>
#include <sfx2/mnumgr.hxx>
#include "statcach.hxx"
#include <sfx2/msgpool.hxx>
#include <sfx2/sidebar/ContextChangeBroadcaster.hxx>

//====================================================================

DBG_NAME(SfxShell)

//====================================================================

TYPEINIT0(SfxShell);

//====================================================================
typedef SfxSlot* SfxSlotPtr;
SV_DECL_PTRARR_DEL( SfxVerbSlotArr_Impl, SfxSlotPtr, 4, 4)
SV_IMPL_PTRARR( SfxVerbSlotArr_Impl, SfxSlotPtr);

using namespace com::sun::star;

//=========================================================================
// SfxShell_Impl
//=========================================================================
struct SfxShell_Impl: public SfxBroadcaster
{
	String                      aObjectName;// Name des Sbx-Objects
	SfxItemArray_Impl           aItems;     // Datenaustausch auf Item-Basis
    SfxViewShell*               pViewSh;    // SfxViewShell falls Shell ViewFrame/ViewShell/SubShell ist
	SfxViewFrame*               pFrame;     // Frame, falls <UI-aktiv>
	SfxRepeatTarget*            pRepeatTarget;
//    SbxObjectRef                xParent;
	sal_Bool						bInAppBASIC;
	sal_Bool                        bActive;
	sal_uIntPtr						nDisableFlags;
	sal_uIntPtr                       nHelpId;
    svtools::AsynchronLink*     pExecuter;
    svtools::AsynchronLink*     pUpdater;
    SfxVerbSlotArr_Impl         aSlotArr;
    com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aVerbList;
    ::sfx2::sidebar::ContextChangeBroadcaster maContextChangeBroadcaster;

	SfxShell_Impl()  : pExecuter( 0 ), pUpdater( 0 ) {}
	~SfxShell_Impl() { delete pExecuter; delete pUpdater;}
};

//====================================================================
#ifdef DBG_UTIL

String SfxShellIdent_Impl( const SfxShell *pSh )

/*  [Beschreibung]

	Interne Hilfesfunktion. Liefert einen die SfxShell 'pSh' beschreibenden
	String zur"uck. Z.B.: SfxApplication[StarWriter]
*/

{
	String aIdent( pSh->ISA(SfxApplication) ? DEFINE_CONST_UNICODE("SfxApplication") :
				   pSh->ISA(SfxViewFrame) ? DEFINE_CONST_UNICODE("SfxViewFrame") :
				   pSh->ISA(SfxViewShell) ? DEFINE_CONST_UNICODE("SfxViewShell") :
				   pSh->ISA(SfxObjectShell) ? DEFINE_CONST_UNICODE("SfxObjectShell") : DEFINE_CONST_UNICODE("SfxShell") );
	aIdent += '[';
	aIdent += pSh->GetName();
	aIdent += ']';
	return aIdent;
}

#endif
//====================================================================

//=========================================================================
// SfxShell
//=========================================================================

void __EXPORT SfxShell::EmptyExecStub(SfxShell *, SfxRequest &)
{
}

void __EXPORT SfxShell::EmptyStateStub(SfxShell *, SfxItemSet &)
{
}

SfxShell::SfxShell()

/*  [Beschreibung]

	Der Konstruktor der Klasse SfxShell initialisierung nur einfache
	Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
	Daher ist das Anlegen einer SfxShell Instanz sehr billig.
*/

:	pImp(0),
    pPool(0),
	pUndoMgr(0)
{
	DBG_CTOR(SfxShell, 0);
	pImp = new SfxShell_Impl;
	pImp->pViewSh = 0;
	pImp->pFrame = 0;
	pImp->pRepeatTarget = 0;
	pImp->bInAppBASIC = sal_False;
	pImp->nHelpId = 0L;
	pImp->bActive = sal_False;
	pImp->nDisableFlags = 0;
}

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

SfxShell::SfxShell( SfxViewShell *pViewSh )

/*  [Beschreibung]

	Der Konstruktor der Klasse SfxShell initialisierung nur einfache
	Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
	Daher ist das Anlegen einer SfxShell Instanz sehr billig.
*/

:	pImp(0),
    pPool(0),
	pUndoMgr(0)
{
	DBG_CTOR(SfxShell, 0);
	pImp = new SfxShell_Impl;
	pImp->pViewSh = pViewSh;
	pImp->pFrame = 0;
	pImp->pRepeatTarget = 0;
	pImp->bInAppBASIC = sal_False;
	pImp->nHelpId = 0L;
	pImp->bActive = sal_False;
}

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

SfxShell::~SfxShell()

/*  [Beschreibung]

	Die Verbindungs zu einem ggf. zugeh"origen SbxObject wird gel"ost.
	Das SbxObject existiert ggf. weiter, kann aber keine Funktionen
	mehr ausf"uhren und keine Properties mehr bereitstellen.
*/

{
	DBG_DTOR(SfxShell, 0);


	delete pImp;
}

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

void SfxShell::SetName( const String &rName )

/*  [Beschreibung]

	Setzt den Namen des Shell-Objekts. Mit diesem Namen kann die
	SfxShell-Instanz vom BASIC aus angesprochen werden.
*/

{
	pImp->aObjectName = rName;
}

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

const String& SfxShell::GetName() const

/*  [Beschreibung]

	Liefert den Namen des Shell-Objekts. Mit diesem Namen kann die
	SfxShell-Instanz vom BASIC aus angesprochen werden.
*/

{
	return pImp->aObjectName;
}

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

SvGlobalName SfxShell::GetGlobalName() const

/*  [Beschreibung]

	Liefert den Global Unique Identifier des Shell-Objekts. Mit diesem
	Namen kann die SfxShell-Instanz z.B. via OLE Automation angesprochen
	werden, bzw. in der Registration-Database gefunden werden.
*/

{
	return SvGlobalName();
}

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

SfxDispatcher* SfxShell::GetDispatcher() const

/*  [Beschreibung]

	Diese Methode liefert einen Pointer auf den <SfxDispatcher>, in
	dem die SfxShell gerade <UI-aktiv> ist bzw. einen 0-Pointer, wenn
	sie gerade nicht UI-aktiv ist.

	Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
	Methodenaufrufs g"ultig.
*/

{
	return pImp->pFrame ? pImp->pFrame->GetDispatcher() : 0;
}

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

SfxViewShell* SfxShell::GetViewShell() const

/*  [Beschreibung]

	Liefert bei SubShells die SfxViewShell, in der sie liegen. Sonst und
	falls nicht vom App-Entwickler angegeben liefert diese Methode 0.
*/

{
	return pImp->pViewSh;
}

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

SfxViewFrame* SfxShell::GetFrame() const

/*  [Beschreibung]

	Diese Methode liefert einen Pointer auf den <SfxViewFrame>, dem diese
	SfxShell-Instanz zugeordnet ist oder in dem sie zur Zeit <UI-aktiv> ist.
	Ein 0-Pointer wird geliefert, wenn diese SfxShell-OInstanz gerade nicht
	UI-aktiv ist und auch keinem SfxViewFrame fest zugeordnet ist.

	Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
	Methodenaufrufs g"ultig.


	[Anmerkung]

	Nur Instanzen von Subklasse von SfxApplication und SfxObjectShell sollten
	hier einen 0-Pointer liefern. Ansonsten liegt ein Fehler im Anwendungs-
	programm vor (falscher Ctor von SfxShell gerufen).


	[Querverweise]

	<SfxViewShell::GetViewFrame()const>
*/

{
	if ( pImp->pFrame )
		return pImp->pFrame;
	if ( pImp->pViewSh )
		return pImp->pViewSh->GetViewFrame();
	return 0;
}

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

const SfxPoolItem* SfxShell::GetItem
(
	sal_uInt16  nSlotId         // Slot-Id des zu erfragenden <SfxPoolItem>s
)   const

/*  [Beschreibung]

	Mit dieser Methode kann auf beliebige Objekte von Subklassen von
	<SfxPoolItem> zugegriffen werden. Diese Austauschtechnik wird ben"otigt,
	wenn z.B. spezielle <SfxToolBoxControl> Subklassen Zugriff auf
	bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.

	Die zur"uckgelieferte Instanz geh"ort der jeweilige SfxShell und
	darf nur im unmittelbaren Kontext des Methodenaufrufs verwendet werden.


	[Querverweise]

	<SfxShell::PutItem(const SfxPoolItem&)>
	<SfxShell::RemoveItem(sal_uInt16)>
*/

{
	for ( sal_uInt16 nPos = 0; nPos < pImp->aItems.Count(); ++nPos )
		if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId )
			return pImp->aItems.GetObject(nPos);
	return 0;
}

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

void SfxShell::RemoveItem
(
	sal_uInt16  nSlotId         // Slot-Id des zu l"oschenden <SfxPoolItem>s
)

/*  [Beschreibung]

	Mit dieser Methode k"onnen die allgemein zur Verf"ugung gestellten
	Instanzen von Subklassen von <SfxPoolItem> aus der SfxShell entfernt
	werden.

	Die gespeicherte Instanz wird gel"oscht.


	[Querverweise]

	<SfxShell::PutItem(const SfxPoolItem&)>
	<SfxShell::GetItem(sal_uInt16)>
*/

{
	for ( sal_uInt16 nPos = 0; nPos < pImp->aItems.Count(); ++nPos )
		if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId )
		{
			// Item entfernen und l"oschen
			SfxPoolItem *pItem = pImp->aItems.GetObject(nPos);
			delete pItem;
			pImp->aItems.Remove(nPos);

			// falls aktiv Bindings benachrichtigen
			SfxDispatcher *pDispat = GetDispatcher();
			if ( pDispat )
			{
				SfxVoidItem aVoid( nSlotId );
				pDispat->GetBindings()->Broadcast( SfxPoolItemHint( &aVoid ) );
			}
		}
}

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

void SfxShell::PutItem
(
	const SfxPoolItem&  rItem   /*  Instanz, von der eine Kopie erstellt wird,
									die in der SfxShell in einer Liste
									gespeichert wird. */
)

/*  [Beschreibung]

	Mit dieser Methode k"onnen beliebige Objekte von Subklassen von
	<SfxPoolItem> zur Verf"ugung gestellt werden. Diese Austauschtechnik
	wird ben"otigt, wenn z.B. spezielle <SfxToolBoxControl> Subklassen
	Zugriff auf bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.

	Falls ein SfxPoolItem mit derselben Slot-Id exisitert, wird dieses
	automatisch gel"oscht.


	[Querverweise]

	<SfxShell::RemoveItem(sal_uInt16)>
	<SfxShell::GetItem(sal_uInt16)>
*/

{
	DBG_ASSERT( !rItem.ISA(SfxSetItem), "SetItems aren't allowed here" );
	DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ),
				"items with Which-Ids aren't allowed here" );

	// MSC auf WNT/W95 machte hier Mist, Vorsicht bei Umstellungen
	const SfxPoolItem *pItem = rItem.Clone();
	SfxPoolItemHint aItemHint( (SfxPoolItem*) pItem );
	const sal_uInt16 nWhich = rItem.Which();
	SfxPoolItem **ppLoopItem = (SfxPoolItem**) pImp->aItems.GetData();
	sal_uInt16 nPos;
	for ( nPos = 0; nPos < pImp->aItems.Count(); ++nPos, ++ppLoopItem )
	{
		if ( (*ppLoopItem)->Which() == nWhich )
		{
			// Item austauschen
			delete *ppLoopItem;
			pImp->aItems.Remove(nPos);
			pImp->aItems.Insert( (SfxPoolItemPtr) pItem, nPos );

			// falls aktiv Bindings benachrichtigen
			SfxDispatcher *pDispat = GetDispatcher();
			if ( pDispat )
            {
                SfxBindings* pBindings = pDispat->GetBindings();
                pBindings->Broadcast( aItemHint );
                sal_uInt16 nSlotId = nWhich; //pItem->GetSlotId();
                SfxStateCache* pCache = pBindings->GetStateCache( nSlotId );
                if ( pCache )
                {
                    pCache->SetState( SFX_ITEM_AVAILABLE, pItem->Clone(), sal_True );
                    pCache->SetCachedState( sal_True );
                }
            }
            return;
		}
	}

	Broadcast( aItemHint );
	pImp->aItems.Insert((SfxPoolItemPtr)pItem, nPos );
}

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

SfxInterface* SfxShell::GetInterface() const

/*  [Beschreibung]

	Mit dieser virtuellen Methode, die durch das Makro <SFX_DECL_INTERFACE>
	von jeder Subclass mit eigenen Slots automatisch "uberladen wird, kann
	auf die zu der Subklasse geh"orende <SfxInterface>-Instanz zugegriffen
	werden.

	Die Klasse SfxShell selbst hat noch kein eigenes SfxInterface
	(keine Slots), daher wird ein 0-Pointer zur"uckgeliefert.
*/

{
    return GetStaticInterface();
}

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

SfxBroadcaster* SfxShell::GetBroadcaster()

/*	[Beschreibung]

	Liefert einen SfxBroadcaster f"ur diese SfxShell-Instanz bis die
	Klasse SfxShell von SfxBroadcaster abgeleitet ist.
*/

{
	return pImp;
}

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

::svl::IUndoManager* SfxShell::GetUndoManager()

/*  [Beschreibung]

	Jede Subclass von SfxShell kann "uber einen <SfxUndoManager> verf"ugen.
	Dieser kann in den abgeleiteten Klasse mit <SfxShell:SetUndoManager()>
	gesetzt werden.

	Die Klasse SfxShell selbst hat noch keinen SfxUndoManager, es wird
	daher ein 0-Pointer zur"uckgeliefert.
*/

{
	return pUndoMgr;
}

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

void SfxShell::SetUndoManager( ::svl::IUndoManager *pNewUndoMgr )

/*  [Beschreibung]

	Setzt einen <SfxUndoManager> f"ur diese <SfxShell> Instanz. F"ur das
	Undo wird immer nur der Undo-Manager an der jeweils oben auf dem
	Stack des <SfxDispatcher> liegenden SfxShell verwendet.

	Am "ubergebenen <SfxUndoManager> wird automatisch die aktuelle
	Max-Undo-Action-Count Einstellung aus den Optionen gesetzt.

	'pNewUndoMgr' mu\s bis zum Dtor dieser SfxShell-Instanz oder bis
	zum n"achsten 'SetUndoManager()' existieren.
*/

{
    OSL_ENSURE( ( pUndoMgr == NULL ) || ( pNewUndoMgr == NULL ) || ( pUndoMgr == pNewUndoMgr ),
        "SfxShell::SetUndoManager: exchanging one non-NULL manager with another non-NULL manager? Suspicious!" );
    // there's at least one client of our UndoManager - the DocumentUndoManager at the SfxBaseModel - which
    // caches the UndoManager, and registers itself as listener. If exchanging non-NULL UndoManagers is really
    // a supported scenario (/me thinks it is not), then we would need to notify all such clients instances.

	pUndoMgr = pNewUndoMgr;
	if ( pUndoMgr )
        pUndoMgr->SetMaxUndoActionCount( (sal_uInt16) SvtUndoOptions().GetUndoCount() );
}

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

SfxRepeatTarget* SfxShell::GetRepeatTarget() const

/*  [Beschreibung]

	Liefert einen Pointer auf die <SfxRepeatTarget>-Instanz, die
	als RepeatTarget bei SID_REPEAT verwendet wird, wenn der
	von dieser SfxShell gelieferte <SfxUndoManager> angesprochen wird.
	Der R"uckgabewert kann 0 sein.


	[Anmerkung]

	Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
	<SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
	provoziert werden (wegen Call-to-Pointer-to-Member-Function to
	subclass).
*/

{
	return pImp->pRepeatTarget;
}

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

void SfxShell::SetRepeatTarget( SfxRepeatTarget *pTarget )

/*  [Beschreibung]

	Setzt den die <SfxRepeatTarget>-Instanz, die bei SID_REPEAT als
	RepeatTarget verwendet wird, wenn der von dieser SfxShell gelieferte
	<SfxUndoManager> angesprochen wird. Durch 'pTarget==0' wird SID_REPEAT
	f"ur diese SfxShell disabled. Die Instanz '*pTarget' mu\s so lange
	leben, wie sie angemeldet ist.


	[Anmerkung]

	Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
	<SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
	provoziert werden (wegen Call-to-Pointer-to-Member-Function to
	subclass).
*/

{
	pImp->pRepeatTarget = pTarget;
}

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

void SfxShell::Invalidate
(
	sal_uInt16          nId     /* Zu invalidierende Slot-Id oder Which-Id.
							   Falls diese 0 ist (default), werden
							   alle z.Zt. von dieser Shell bedienten
							   Slot-Ids invalidiert. */
)

/*  [Beschreibung]

	Mit dieser Methode k"onnen Slots der Subclasses "uber die Slot-Id
	oder alternativ "uber die Which-Id invalidiert werden. Slot-Ids,
	die von der Subclass ererbt sind, werden ebenfalls invalidert.

	[Querverweise]
	<SfxBindings::Invalidate(sal_uInt16)>
	<SfxBindings::InvalidateAll(sal_Bool)>
*/

{
    if ( !GetViewShell() )
    {
        DBG_ERROR( "wrong Invalidate method called!" );
        return;
    }

    Invalidate_Impl( GetViewShell()->GetViewFrame()->GetBindings(), nId );
}

void SfxShell::Invalidate_Impl( SfxBindings& rBindings, sal_uInt16 nId )
{
	if ( nId == 0 )
    {
        rBindings.InvalidateShell( *this, sal_False );
    }
	else
	{
		const SfxInterface *pIF = GetInterface();
		do
		{
			const SfxSlot *pSlot = pIF->GetSlot(nId);
			if ( pSlot )
			{
				// bei Enum-Slots ist der Master-Slot zu invalidieren
				if ( SFX_KIND_ENUM == pSlot->GetKind() )
					pSlot = pSlot->GetLinkedSlot();

				// den Slot selbst und ggf. auch alle Slave-Slots invalidieren
				rBindings.Invalidate( pSlot->GetSlotId() );
				for ( const SfxSlot *pSlave = pSlot->GetLinkedSlot();
					  pSlave && pIF->ContainsSlot_Impl( pSlave ) &&
						pSlave->GetLinkedSlot() == pSlot;
					  ++pSlave )
					rBindings.Invalidate( pSlave->GetSlotId() );

				return;
			}

			pIF = pIF->GetGenoType();
		}

		while ( pIF );

		DBG_WARNING( "W3: invalidating slot-id unknown in shell" );
	}
}

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

void SfxShell::DoActivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI )

/*  [Beschreibung]

	Diese Methode steuert die Aktivierung der SfxShell-Instanz. Zun"achst
	wird durch Aufruf der virtuellen Methode <SfxShell::Activate(sal_Bool)>
	der Subclass die M"oglichkeit gegeben, auf das Event zu reagieren.

	Bei bMDI == TRUE wird das zugeh"orige SbxObject 'scharfgeschaltet',
	so da\s Methoden des Objekts unqualifiziert (ohne den Namen des Objekts)
	vom BASIC gefunden werden.
*/

{
#ifdef DBG_UTIL
	const SfxInterface *p_IF = GetInterface();
	if ( !p_IF )
		return;
#endif
#ifdef DBG_UTIL_VB
		String aMsg("SfxShell::DoActivate() ");
		aMsg += (long)this;
		aMsg += "  ";
		aMsg += GetInterface()->GetName();
		aMsg += " bMDI ";
		if ( bMDI ) aMsg += "MDI";
		DbgTrace( aMsg.GetBuffer() );
#endif

	if ( bMDI )
	{
		// Frame merken, in dem aktiviert wird
		pImp->pFrame = pFrame;
		pImp->bActive = sal_True;
	}

	// Subklasse benachrichtigen
	Activate(bMDI);
}

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

void SfxShell::DoDeactivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI )

/*  [Beschreibung]

	Diese Methode steuert die Deaktivierung der SfxShell-Instanz. Bei
	bMDI == TRUE wird zun"achst das SbxObject in einen Status versetzt,
	so da\s Methoden vom BASIC aus nur noch qualifiziert gerufen werden
	k"onnen.

	Dann erh"alt in jedem Fall die Subclass durch Aufruf der virtuellen
	Methode <SfxShell::Deactivate(sal_Bool)> die M"oglichkeit auf das Event
	zu reagieren.
*/

{
#ifdef DBG_UTIL
	const SfxInterface *p_IF = GetInterface();
	if ( !p_IF )
		return;
#endif
#ifdef DBG_UTIL_VB
		String aMsg("SfxShell::DoDeactivate()");
		aMsg += (long)this;
		aMsg += "  ";
		aMsg += GetInterface()->GetName();
		aMsg += " bMDI ";
		if ( bMDI ) aMsg += "MDI";
		DbgTrace( aMsg.GetBuffer() );
#endif

	// nur wenn er vom Frame kommt (nicht z.B. pop der BASIC-IDE vom AppDisp)
	if ( bMDI && pImp->pFrame == pFrame )
	{
		// austragen
		pImp->pFrame = 0;
		pImp->bActive = sal_False;
	}

	// Subklasse benachrichtigen
	Deactivate(bMDI);
}

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

sal_Bool SfxShell::IsActive() const
{
	return pImp->bActive;
}

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

void SfxShell::Activate
(
	sal_Bool    /*bMDI*/        /*  TRUE
							der <SfxDispatcher>, auf dem die SfxShell sich
							befindet, ist aktiv geworden oder die SfxShell
							Instanz wurde auf einen aktiven SfxDispatcher
							gepusht. (vergl. SystemWindow::IsMDIActivate())

							FALSE
							das zum <SfxViewFrame>, auf dessen SfxDispatcher
							sich die SfxShell Instanz befindet, wurde
							aktiviert.
							(z.B. durch einen geschlossenen Dialog) */
)

/*  [Beschreibung]

	Virtuelle Methode, die beim Aktivieren der SfxShell Instanz gerufen
	wird, um den Subclasses die Gelegenheit zu geben, auf das Aktivieren
	zu reagieren.

	[Querverweise]
	StarView SystemWindow::Activate(sal_Bool)
*/

{
    BroadcastContextForActivation(true);
}

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

void SfxShell::Deactivate
(
	sal_Bool    /*bMDI*/        /*  TRUE
							der <SfxDispatcher>, auf dem die SfxShell sich
							befindet, ist inaktiv geworden oder die SfxShell
							Instanz wurde auf einen aktiven SfxDispatcher
							gepoppt. (vergl. SystemWindow::IsMDIActivate())

							FALSE
							das zum <SfxViewFrame>, auf dessen SfxDispatcher
							sich die SfxShell Instanz befindet, wurde
							deaktiviert. (z.B. durch einen Dialog) */

)

/*  [Beschreibung]

	Virtuelle Methode, die beim Deaktivieren der SfxShell Instanz gerufen
	wird, um den Subclasses die Gelegenheit zu geben, auf das Deaktivieren
	zu reagieren.

	[Querverweise]
	StarView SystemWindow::Deactivate(sal_Bool)
*/

{
    BroadcastContextForActivation(false);
}


void SfxShell::ParentActivate
(
)

/*  [Beschreibung]

	Ein Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
	ist aktiv geworden, oder die SfxShell Instanz wurde auf einen
	<SfxDispatcher> gepusht, dessen parent aktiv ist.

	Die Basisimplementation ist leer und braucht nicht gerufen zu werden.

	[Querverweise]
	SfxShell::Activate()
*/
{
}

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

void SfxShell::ParentDeactivate
(
)

/*  [Beschreibung]

	Der aktive Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
	ist deaktiviert worden.

	Die Basisimplementation ist leer und braucht nicht gerufen zu werden.

	[Querverweise]
	SfxShell::Deactivate()
*/
{
}

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

ResMgr* SfxShell::GetResMgr() const

/*  [Beschreibung]

	Diese Methode liefert den ResMgr der <Resource-DLL>, die von der
	SfxShell-Instanz verwendet wird. Ist dies ein 0-Pointer, so
	ist der aktuelle Resource-Manager zu verwenden.
*/

{
	return GetInterface()->GetResMgr();
}

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

bool SfxShell::CanExecuteSlot_Impl( const SfxSlot &rSlot )

/*  [Beschreibung]

	Diese Methode stellt durch Aufruf der Statusfunktion fest,
	ob 'rSlot' aktuell ausgef"uhrt werden kann.
*/
{
	// Slot-Status holen
	SfxItemPool &rPool = GetPool();
	const sal_uInt16 nId = rSlot.GetWhich( rPool );
	SfxItemSet aSet(rPool, nId, nId);
	SfxStateFunc pFunc = rSlot.GetStateFnc();
	CallState( pFunc, aSet );
	return aSet.GetItemState(nId) != SFX_ITEM_DISABLED;
}

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

long ShellCall_Impl( void* pObj, void* pArg )
{
	((SfxShell* )pObj)->ExecuteSlot( *(SfxRequest*)pArg, (SfxInterface*)0L );
	return 0;
}

/*  [Beschreibung]
	Asynchrones ExecuteSlot fuer das RELOAD
 */

//--------------------------------------------------------------------
const SfxPoolItem* SfxShell::ExecuteSlot( SfxRequest& rReq, sal_Bool bAsync )
{
	if( !bAsync )
		return ExecuteSlot( rReq, (SfxInterface*)0L );
	else
	{
		if( !pImp->pExecuter )
            pImp->pExecuter = new svtools::AsynchronLink(
				Link( this, ShellCall_Impl ) );
		pImp->pExecuter->Call( new SfxRequest( rReq ) );
		return 0;
	}
}

const SfxPoolItem* SfxShell::ExecuteSlot
(
	SfxRequest &rReq,			// der weiterzuleitende <SfxRequest>
	const SfxInterface* pIF     // default = 0 bedeutet virtuell besorgen
)

/*  [Beschreibung]

	Diese Methode erm"oglicht das Weiterleiten eines <SfxRequest> an
	die angegebene Basis-<SfxShell>.


	[Beispiel]

	In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
	abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
	eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.

	Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
	Execute-Methode enth"alt dann skizziert:

	void SubViewShell::Exec( SfxRequest &rReq )
	{
		if ( rReq.GetSlot() == SID_PRINTDOCDIRECT )
		{
			'dialog'
			if ( 'condition' )
				ExecuteSlot( rReq, SfxViewShell::GetInterface() );
		}
	}

	Es braucht i.d.R. kein rReq.Done() gerufen zu werden, da das bereits
	die Implementierung der SfxViewShell erledigt bzw. abgebrochen wurde.


	[Querverweise]

	<SfxShell::GetSlotState(sal_uInt16,const SfxInterface*,SfxItemSet*)>
*/

{
	if ( !pIF )
		pIF = GetInterface();

    sal_uInt16 nSlot = rReq.GetSlot();
    const SfxSlot* pSlot = NULL;
    if ( nSlot >= SID_VERB_START && nSlot <= SID_VERB_END )
        pSlot = GetVerbSlot_Impl(nSlot);
    if ( !pSlot )
        pSlot = pIF->GetSlot(nSlot);
	DBG_ASSERT( pSlot, "slot not supported" );

	SfxExecFunc pFunc = pSlot->GetExecFnc();
    if ( pFunc )
        CallExec( pFunc, rReq );

	return rReq.GetReturnValue();
}

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

const SfxPoolItem* SfxShell::GetSlotState
(
	sal_uInt16              nSlotId,    // Slot-Id des zu befragenden Slots
	const SfxInterface* pIF,        // default = 0 bedeutet virtuell besorgen
	SfxItemSet*         pStateSet   // SfxItemSet der Slot-State-Methode
)

/*  [Beschreibung]

	Diese Methode liefert den Status des Slots mit der angegebenen Slot-Id
	"uber das angegebene Interface.

	Ist der Slot disabled oder in dieser SfxShell (und deren Parent-Shells)
	nicht bekannt, wird ein 0-Pointer zur"uckgeliefert.

	Hat der Slot keinen Status, wird ein SfxVoidItem zur"uckgeliefert.

	Der Status wird bei pStateSet != 0 gleich in diesem Set gesetzt, so
	da\s <SfxShell>-Subklassen Slots-"uberladen und auch bei der
	Status-Methode die Basis-Implementierung rufen k"onnen.


	[Beispiel]

	In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
	abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
	eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.

	Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
	Status-Methode enth"alt dann skizziert:

	void SubViewShell::PrintState( SfxItemSet &rState )
	{
		if ( rState.GetItemState( SID_PRINTDOCDIRECT ) != SFX_ITEM_UNKNOWN )
			GetSlotState( SID_PRINTDOCDIRECT, SfxViewShell::GetInterface(),
					&rState );
		...
	}


	[Querverweise]

	<SfxShell::ExecuteSlot(SfxRequest&)>
*/

{
	// Slot am angegebenen Interface besorgen
	if ( !pIF )
		pIF = GetInterface();
	SfxItemState eState;
	SfxItemPool &rPool = GetPool();

    const SfxSlot* pSlot = NULL;
    if ( nSlotId >= SID_VERB_START && nSlotId <= SID_VERB_END )
        pSlot = GetVerbSlot_Impl(nSlotId);
    if ( !pSlot )
        pSlot = pIF->GetSlot(nSlotId);
	if ( pSlot )
		// ggf. auf Which-Id mappen
		nSlotId = pSlot->GetWhich( rPool );

	// Item und Item-Status besorgen
	const SfxPoolItem *pItem = NULL;
	SfxItemSet aSet( rPool, nSlotId, nSlotId ); // pItem stirbt sonst zu fr"uh
	if ( pSlot )
	{
		// Status-Methode rufen
		SfxStateFunc pFunc = pSlot->GetStateFnc();
        if ( pFunc )
            CallState( pFunc, aSet );
		eState = aSet.GetItemState( nSlotId, sal_True, &pItem );

		// ggf. Default-Item besorgen
		if ( eState == SFX_ITEM_DEFAULT )
		{
			if ( SfxItemPool::IsWhich(nSlotId) )
				pItem = &rPool.GetDefaultItem(nSlotId);
			else
				eState = SFX_ITEM_DONTCARE;
		}
	}
	else
		eState = SFX_ITEM_UNKNOWN;

	// Item und Item-Status auswerten und ggf. in pStateSet mitpflegen
	SfxPoolItem *pRetItem = 0;
	if ( eState <= SFX_ITEM_DISABLED )
	{
		if ( pStateSet )
			pStateSet->DisableItem(nSlotId);
		return 0;
	}
	else if ( eState == SFX_ITEM_DONTCARE )
	{
		if ( pStateSet )
			pStateSet->ClearItem(nSlotId);
		pRetItem = new SfxVoidItem(0);
	}
	else
	{
		if ( pStateSet && pStateSet->Put( *pItem ) )
			return &pStateSet->Get( pItem->Which() );
		pRetItem = pItem->Clone();
	}
	DeleteItemOnIdle(pRetItem);

	return pRetItem;
}

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

SFX_EXEC_STUB(SfxShell, VerbExec)
SFX_STATE_STUB(SfxShell, VerbState)

void SfxShell::SetVerbs(const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& aVerbs)
{
	SfxViewShell *pViewSh = PTR_CAST ( SfxViewShell, this);

	DBG_ASSERT(pViewSh, "SetVerbs nur an der ViewShell aufrufen!");
    if ( !pViewSh )
        return;

    // Zun"achst alle Statecaches dirty machen, damit keiner mehr versucht,
    // die Slots zu benutzen
    {
        SfxBindings *pBindings =
            pViewSh->GetViewFrame()->GetDispatcher()->GetBindings();
        sal_uInt16 nCount = pImp->aSlotArr.Count();
        for (sal_uInt16 n1=0; n1<nCount ; n1++)
        {
            sal_uInt16 nId = SID_VERB_START + n1;
            pBindings->Invalidate(nId, sal_False, sal_True);
        }
    }

    sal_uInt16 nr=0;
    for (sal_Int32 n=0; n<aVerbs.getLength(); n++)
    {
        sal_uInt16 nSlotId = SID_VERB_START + nr++;
        DBG_ASSERT(nSlotId <= SID_VERB_END, "Zuviele Verben!");
        if (nSlotId > SID_VERB_END)
            break;

        SfxSlot *pNewSlot = new SfxSlot;
        pNewSlot->nSlotId = nSlotId;
        pNewSlot->nGroupId = 0;

        // Verb-Slots m"ussen asynchron ausgef"uhrt werden, da sie w"ahrend
        // des Ausf"uhrens zerst"ort werden k"onnten
        pNewSlot->nFlags = SFX_SLOT_ASYNCHRON | SFX_SLOT_CONTAINER;
        pNewSlot->nMasterSlotId = 0;
        pNewSlot->nValue = 0;
        pNewSlot->fnExec = SFX_STUB_PTR(SfxShell,VerbExec);
        pNewSlot->fnState = SFX_STUB_PTR(SfxShell,VerbState);
        pNewSlot->pType = 0; HACK(SFX_TYPE(SfxVoidItem))
        pNewSlot->pName = OUStringToOString( aVerbs[n].VerbName, RTL_TEXTENCODING_UTF8).getStr(); // TODO: life time of temp is suspicious!!!
        pNewSlot->pLinkedSlot = 0;
        pNewSlot->nArgDefCount = 0;
        pNewSlot->pFirstArgDef = 0;
        pNewSlot->pUnoName = 0;

        if (pImp->aSlotArr.Count())
        {
            SfxSlot *pSlot = (pImp->aSlotArr)[0];
            pNewSlot->pNextSlot = pSlot->pNextSlot;
            pSlot->pNextSlot = pNewSlot;
        }
        else
            pNewSlot->pNextSlot = pNewSlot;

        pImp->aSlotArr.Insert(pNewSlot, (sal_uInt16) n);
	}

    pImp->aVerbList = aVerbs;

    if (pViewSh)
	{
		// Der Status von SID_OBJECT wird im Controller direkt an der Shell
		// abgeholt, es reicht also, ein neues StatusUpdate anzuregen
		SfxBindings *pBindings = pViewSh->GetViewFrame()->GetDispatcher()->
				GetBindings();
		pBindings->Invalidate( SID_OBJECT, sal_True, sal_True );
	}
}

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

const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& SfxShell::GetVerbs() const
{
    return pImp->aVerbList;
}

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

void SfxShell::VerbExec(SfxRequest& rReq)
{
	sal_uInt16 nId = rReq.GetSlot();
	SfxViewShell *pViewShell = GetViewShell();
	if ( pViewShell )
	{
        sal_Bool bReadOnly = pViewShell->GetObjectShell()->IsReadOnly();
        com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aList = pViewShell->GetVerbs();
        for (sal_Int32 n=0, nVerb=0; n<aList.getLength(); n++)
		{
            // check for ReadOnly verbs
            if ( bReadOnly && !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES) )
                continue;

            // check for verbs that shouldn't appear in the menu
            if ( !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU) )
                continue;

            if (nId == SID_VERB_START + nVerb++)
			{
                pViewShell->DoVerb(aList[n].VerbID);
				rReq.Done();
				return;
			}
		}
	}
}

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

void SfxShell::VerbState(SfxItemSet& )
{
}

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

const SfxSlot* SfxShell::GetVerbSlot_Impl(sal_uInt16 nId) const
{
    com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > rList = pImp->aVerbList;

	DBG_ASSERT(nId >= SID_VERB_START && nId <= SID_VERB_END,"Falsche VerbId!");
	sal_uInt16 nIndex = nId - SID_VERB_START;
    DBG_ASSERT(nIndex < rList.getLength(),"Falsche VerbId!");

    if (nIndex < rList.getLength())
        return pImp->aSlotArr[nIndex];
	else
		return 0;
}

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

void SfxShell::SetHelpId(sal_uIntPtr nId)
{
	pImp->nHelpId = nId;
}

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

sal_uIntPtr SfxShell::GetHelpId() const
{
	return pImp->nHelpId;
}

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

SfxObjectShell* SfxShell::GetObjectShell()
{
	if ( GetViewShell() )
		return GetViewShell()->GetViewFrame()->GetObjectShell();
	else
		return NULL;
}

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

sal_Bool SfxShell::HasUIFeature( sal_uInt32 )
{
	return sal_False;
}

long DispatcherUpdate_Impl( void*, void* pArg )
{
	((SfxDispatcher*) pArg)->Update_Impl( sal_True );
    ((SfxDispatcher*) pArg)->GetBindings()->InvalidateAll(sal_False);
	return 0;
}

void SfxShell::UIFeatureChanged()
{
	SfxViewFrame *pFrame = GetFrame();
    if ( pFrame && pFrame->IsVisible() )
	{
		// Auch dann Update erzwingen, wenn Dispatcher schon geupdated ist,
		// sonst bleibt evtl. irgendwas in den gebunkerten Tools stecken.
		// Asynchron aufrufen, um Rekursionen zu vermeiden
		if ( !pImp->pUpdater )
            pImp->pUpdater = new svtools::AsynchronLink( Link( this, DispatcherUpdate_Impl ) );

		// Mehrfachaufrufe gestattet
		pImp->pUpdater->Call( pFrame->GetDispatcher(), sal_True );
	}
}

void SfxShell::SetDisableFlags( sal_uIntPtr nFlags )
{
	pImp->nDisableFlags = nFlags;
}

sal_uIntPtr SfxShell::GetDisableFlags() const
{
	return pImp->nDisableFlags;
}

SfxItemSet*	SfxShell::CreateItemSet( sal_uInt16 )
{
	return NULL;
}

void SfxShell::ApplyItemSet( sal_uInt16, const SfxItemSet& )
{
}

void SfxShell::SetContextName (const ::rtl::OUString& rsContextName)
{
    pImp->maContextChangeBroadcaster.Initialize(rsContextName);
}

void SfxShell::SetViewShell_Impl( SfxViewShell* pView )
{
    pImp->pViewSh = pView;
}




void SfxShell::BroadcastContextForActivation (const bool bIsActivated)
{
    SfxViewFrame* pViewFrame = GetFrame();
    if (pViewFrame != NULL)
        if (bIsActivated)
            pImp->maContextChangeBroadcaster.Activate(pViewFrame->GetFrame().GetFrameInterface());
        else
            pImp->maContextChangeBroadcaster.Deactivate(pViewFrame->GetFrame().GetFrameInterface());
}




bool SfxShell::SetContextBroadcasterEnabled (const bool bIsEnabled)
{
    return pImp->maContextChangeBroadcaster.SetBroadcasterEnabled(bIsEnabled);
}
