/*************************************************************************
 *
 *  $RCSfile: dispatch.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: mba $ $Date: 2001/06/18 09:49:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SFXDISPATCH_HXX
#define _SFXDISPATCH_HXX

#include <stdarg.h>

#define _SVSTDARR_USHORTS
#include <svtools/svstdarr.hxx>		// SvUShorts

#include <sfx2/bindings.hxx>
#include <sfx2/app.hxx>

class SfxSlotServer;
class SfxShell;
class SfxRequest;
class SfxShellStack_Impl;
class SfxHintPoster;
class SfxViewFrame;
class SfxBindings;
class SfxItemSet;

struct SfxDispatcher_Impl;
struct SfxPlugInInfo_Impl;

namespace com
{
    namespace sun
    {
        namespace star
        {
            namespace frame
            {
                class XDispatch;
            }
        }
    }
}

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

#define SFX_SHELL_POP_UNTIL 	4
#define SFX_SHELL_POP_DELETE    2
#define SFX_SHELL_PUSH			1

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

typedef SfxPoolItem* SfxPoolItemPtr;
SV_DECL_PTRARR_DEL( SfxItemPtrArray, SfxPoolItemPtr, 4, 4 );

// fuer  shell.cxx
typedef SfxItemPtrArray SfxItemArray_Impl;

class SfxExecuteItem : public SfxItemPtrArray, public SfxPoolItem
{
	USHORT nSlot;
	SfxCallMode eCall;
	USHORT nModifier;
public:
	USHORT                   GetSlot() const { return nSlot; }
	USHORT                   GetModifier() const { return nModifier; }
	void                     SetModifier( USHORT nModifierP ) { nModifier = nModifierP; }
	SfxCallMode              GetCallMode() const { return eCall; }
	void                     SetCallMode( SfxCallMode eMode ) { eCall = eMode; }
	virtual int 			 operator==( const SfxPoolItem& ) const;

	virtual SfxPoolItem*	 Clone( SfxItemPool *pPool = 0 ) const;
							 SfxExecuteItem(
								 USHORT nWhich, USHORT nSlot, SfxCallMode eMode,
								 const SfxPoolItem *pArg1, ... );
							 SfxExecuteItem(
								 USHORT nWhich, USHORT nSlot, SfxCallMode eMode );
							 SfxExecuteItem( const SfxExecuteItem& );
};

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

class SfxDispatcher
{
	SfxDispatcher_Impl* 			pImp;
	BOOL							bFlushed;

private:
						// auf temporaer ausgewerteten Todos suchen
	BOOL				CheckVirtualStack( const SfxShell& rShell, BOOL bDeep );

#ifndef _SFX_HXX

friend class SfxApplication;
friend class SfxViewFrame;

	DECL_LINK( EventHdl_Impl, void * );
	DECL_LINK( PostMsgHandler, SfxRequest * );

	int 				Call_Impl( SfxShell& rShell, const SfxSlot &rSlot, SfxRequest &rReq, BOOL bRecord );
	ULONG               _Update_Impl( BOOL,BOOL,BOOL,SfxMenuBarManager*,SfxWorkWindow*);
	void				CollectTools_Impl(SfxWorkWindow*);

protected:
friend class SfxBindings;
friend class SfxStateCache;
friend class SfxPopupMenuManager;
friend class SfxHelp;
						// Fuer die Bindings: Finden einer Message; Level fuer
						// erneuten Zugriff
	BOOL				_TryIntercept_Impl( USHORT nId, SfxSlotServer &rServer, BOOL bModal );
	BOOL				_FindServer( USHORT nId, SfxSlotServer &rServer, BOOL bModal );
	BOOL				_FillState( const SfxSlotServer &rServer,
									SfxItemSet &rState, const SfxSlot *pRealSlot );
	const SfxPoolItem*	_Execute( const SfxSlotServer &rServer );
	void				_Execute( SfxShell &rShell, const SfxSlot &rSlot,
								  SfxRequest &rReq,
								  SfxCallMode eCall = SFX_CALLMODE_STANDARD);
	const SfxPoolItem*	_Execute( USHORT nSlot, SfxCallMode eCall,
								  va_list pArgs, const SfxPoolItem *pArg1 );

#endif
protected:
	void				FlushImpl();

public:
						SfxDispatcher( SfxDispatcher* pParent );
						SfxDispatcher( SfxViewFrame *pFrame = 0 );

	void                Construct_Impl( SfxDispatcher* pParent );

						~SfxDispatcher();

	long                UpdateObjectMenus_Impl(SfxMenuBarManager*);

	const SfxPoolItem*  Execute( const SfxExecuteItem& rItem );
	virtual	USHORT		ExecuteFunction( USHORT nSID, SfxPoolItem** ppArgs=0, USHORT nMode=0 );
    USHORT              ExecuteFunction( USHORT nSID, const SfxItemSet& rArgs , USHORT nMode=0 );

	virtual void		SetExecuteMode( USHORT );

	const SfxPoolItem*	Execute( USHORT nSlot,
								 SfxCallMode nCall = SFX_CALLMODE_SLOT,
								 const SfxPoolItem **pArgs = 0,
								 USHORT nModi = 0,
								 const SfxPoolItem **pInternalArgs = 0);

	const SfxPoolItem*	Execute( USHORT nSlot,
								 SfxCallMode nCall,
								 const SfxPoolItem *pArg1, ... );

	const SfxPoolItem*	Execute( USHORT nSlot,
								 SfxCallMode nCall,
								 const SfxItemSet &rArgs );

	USHORT				GetSlotId( const String& rCommand );

	BOOL				IsActive( const SfxShell& rShell );
	BOOL				IsOnTop( const SfxShell& rShell );
	USHORT				GetShellLevel( const SfxShell &rShell );
	SfxBindings*		GetBindings() const;

	void				Push( SfxShell& rShell );
	void				Pop( SfxShell& rShell, USHORT nMode = 0 );

	SfxShell*			GetShell(USHORT nIdx) const;
	SfxViewFrame*       GetFrame() const;

	void				ExecutePopup( const ResId &rId,
							  Window *pWin = 0, const Point *pPosPixel = 0 );
	static void 		ExecutePopup( USHORT nConfigId = 0,
							  Window *pWin = 0, const Point *pPosPixel = 0 );
	static void 		ExecutePopup( USHORT nConfigId,
									  Window *pWin, const Point *pPosPixel,
									  const SfxPoolItem *pArg1, ...  );

	void				EnterAction( const String& rName );
	void				LeaveAction();

	BOOL				IsAppDispatcher() const;
	BOOL				IsFlushed() const;
	void				Flush();
	void				Lock( BOOL bLock );
	BOOL				IsLocked( USHORT nSID = 0 ) const;
	void				SetSlotFilter( BOOL bEnable = FALSE,
									   USHORT nCount = 0, const USHORT *pSIDs = 0 );

	void				HideUI( BOOL bHide = TRUE );
	void				ShowObjectBar(USHORT nId, SfxShell *pShell=0) const;
	USHORT				GetObjectBarId( USHORT nPos ) const;

	SfxItemState		QueryState( USHORT nSID, const SfxPoolItem* &rpState );

	BOOL                IsAllowed( USHORT nSlot ) const;
    ::com::sun::star::frame::XDispatch*          GetDispatchInterface( const String& );
	void				SetDisableFlags( ULONG nFlags );
	ULONG				GetDisableFlags() const;

#if 0 // _SOLAR__PRIVATE
	BOOL				HasSlot_Impl( USHORT );
	void 				SetMenu_Impl();
	long                Update_Impl( BOOL bForce = FALSE ); // ObjectBars etc.
	BOOL                IsUpdated_Impl() const;
	void				DebugOutput_Impl() const;
	void				ResetObjectBars_Impl();
	int 				GetShellAndSlot_Impl( USHORT nSlot, SfxShell **ppShell, const SfxSlot **ppSlot,
											  BOOL bOwnShellsOnly, BOOL bModal );
	void				LockUI_Impl( BOOL bLock = TRUE );
	void				SetReadOnly_Impl( BOOL  bOn );
	BOOL				GetReadOnly_Impl() const;
	BOOL				IsSlotEnabledByFilter_Impl( USHORT nSID ) const;
	void				SetQuietMode_Impl( BOOL bOn );
	void				SetModalMode_Impl( BOOL bOn );
	BOOL				IsReadOnlyShell_Impl( USHORT nShell ) const;
	void				RemoveShell_Impl( SfxShell& rShell );
	void				InsertShell_Impl( SfxShell& rShell, USHORT nPos );
	void				DoParentActivate_Impl();
	void				DoParentDeactivate_Impl();
	void				DoActivate_Impl( BOOL bMDI );
	void				DoDeactivate_Impl( BOOL bMDI );
	void				InvalidateBindings_Impl(BOOL);
	USHORT				GetNextToolBox_Impl( USHORT nPos, USHORT nType, String *pStr );
#endif
};

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

inline BOOL SfxDispatcher::IsFlushed() const

/*	[Beschreibung]

	Mit dieser Methode l"a"st sich erfragen, ob der Stack des
	SfxDispatchers geflusht ist, oder noch Push- oder Pop-Befehle
	ausstehen.
*/

{
	 return bFlushed;
}

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

inline void SfxDispatcher::Flush()

/*  [Beschreibung]

	Diese Methode f"uhrt ausstehenden Push- und Pop-Befehle aus.
	F"ur <SfxShell>s, die dabei neu auf den Stack kommen, wird
	<SfxShell::Activate(BOOL)> mit bMDI == TRUE aufgerufen, f"ur
	SfxShells, die vom Stack entfernt werden, wird <SfxShell::Deactivate(BOOL)>
	mit bMDI == TRUE aufgerufen.
*/

{
	if ( !bFlushed ) FlushImpl();
}

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

inline void SfxDispatcher::Push( SfxShell& rShell )

/*	[Beschreibung]

	Mit dieser Methode wird eine <SfxShell> auf den SfxDispatcher
	gepusht. Die SfxShell wird zun"achst zum pushen vermerkt und
	es wird ein Timer aufgesetzt. Erst bei Ablauf des Timers wird
	tats"achlich gepusht (<SfxDispatcher::Flush()>) und die <SfxBindings>
	werden invalidiert. W"ahrend der Timer l"auft gleichen sich
	entgegengesetzte Push und Pop Befehle mit derselben SfxShell aus.
*/

{
	Pop( rShell, SFX_SHELL_PUSH );
}

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

inline BOOL SfxDispatcher::IsActive( const SfxShell& rShell )

/*	[Beschreibung]

	Mit dieser Methode kann abgefragt werden, ob sich eine bestimmte
	<SfxShell>-Instanz auf dem SfxDispatcher befindet.

	[R"uckgabewert]

	BOOL				TRUE
						Die SfxShell-Instanz befindet sich auf dem
						SfxDispatcher.

						FALSE
						Die SfxShell-Instanz befindet sich nicht auf dem
						SfxDispatcher.

*/

{
	return CheckVirtualStack( rShell, TRUE );
}
//--------------------------------------------------------------------

inline BOOL SfxDispatcher::IsOnTop( const SfxShell& rShell )

/*  [Beschreibung]

	Mit dieser Methode kann abgefragt werden, ob sich eine bestimmte
	<SfxShell>-Instanz zuoberst auf dem SfxDispatcher befindet.

	[R"uckgabewert]

	BOOL				TRUE
						Die SfxShell-Instanz befindet sich als oberste
						SfxShell auf dem SfxDispatcher.

						FALSE
						Die SfxShell-Instanz befindet sich nicht als
						oberste SfxShell auf dem SfxDispatcher.

*/

{
	return CheckVirtualStack( rShell, FALSE );
}

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

#if SUPD<606
#define SFX_DISPATCHER() SfxGetpApp()->GetDispatcher()
#endif

#endif

