/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sfx2_mnumgr.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/27 19:43:07 $
 *
 *  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
 *
 ************************************************************************/

#ifdef SOLARIS
// HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
#include <ctime>
#endif

#include <string> 	// HACK: prevent conflict between STLPORT and Workshop headers
#include <cstdarg>	// std::va_list

#pragma hdrstop


#include "mnumgr.hxx"

#define _SVSTDARR_USHORTS
#include <svtools/menuoptions.hxx>

#include "virtmenu.hxx"
#include "minstack.hxx"
#include "sfxtypes.hxx"
#include "bindings.hxx"
#include "sfxresid.hxx"
#include "sfx.hrc"
#include "menu.hrc"
namespace binfilter {

static const USHORT nCompatVersion = 4;
static const USHORT nVersion = 5;

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

DECL_PTRSTACK(SfxMenuCfgItemArrStack, SfxMenuCfgItemArr*, 4, 4 );

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

/*N*/ void TryToHideDisabledEntries_Impl( Menu* pMenu )
/*N*/ {
/*N*/ 	DBG_ASSERT( pMenu, "invalid menu" );
/*N*/ 	if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False )
/*N*/ 	{
/*?*/ 		pMenu->SetMenuFlags( pMenu->GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES );
/*N*/ 	}
/*N*/ }

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


/*	[Beschreibung]

	Mit solchen Instanzen wird beim Auslesen des Men"us f"ur die
	Konfiguration ein Stack gebildet, um die Iterator-Position zu
	bestimmen.

	Die Instanzen l"oschen sich selbst, wenn der Stack abgebaut wird.
*/


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


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



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

/*N*/ SfxMenuManager::SfxMenuManager( const ResId& rResId, SfxBindings &rBindings, SfxConfigManager* pMgr, BOOL bBar )
/*N*/ :   SfxConfigItem( rResId.GetId(), pMgr ),
/*N*/ 	bMenuBar(bBar),
/*N*/ 	pMenu(0),
/*N*/ 	pOldMenu(0),
/*N*/ 	pResMgr(rResId.GetResMgr()),
/*N*/ 	pBindings(&rBindings)
/*N*/ {
/*N*/ 	bOLE = FALSE;
/*N*/ 	bAddClipboardFuncs = FALSE;
/*N*/ 	DBG_MEMTEST();
/*N*/ }

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

/*N*/ SfxMenuManager::~SfxMenuManager()
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	pBindings->ENTERREGISTRATIONS();
/*N*/ 	delete pMenu;
/*N*/ 	pBindings->LEAVEREGISTRATIONS();
/*N*/ }

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

/*N*/ void SfxMenuManager::Construct( SfxVirtualMenu& rMenu )
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	pMenu = &rMenu;
/*N*/ 
/*N*/ 	// set the handlers
/*N*/ 	Menu *pSvMenu = pMenu->GetSVMenu();
/*N*/ 	pSvMenu->SetSelectHdl( LINK(this, SfxMenuManager, Select) );
/*N*/ 	TryToHideDisabledEntries_Impl( pSvMenu );
/*N*/ }

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


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


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


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

/*N*/ void SfxMenuManager::SetForceCtrlCreateMode( BOOL bCreate )
/*N*/ {
/*N*/ 	bOLE = bCreate;
/*N*/ }

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


/*?*/ int SfxMenuManager::Load( SvStream& rStream )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return 0;//STRIP001 
/*?*/ }

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

/*N*/ void SfxMenuManager::UseDefault()
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 
/*N*/ 	SfxApplication *pSfxApp = SFX_APP();
/*N*/ 	SfxVirtualMenu *pOldVirtMenu=0;
/*N*/ 	if (pMenu)
/*N*/ 	{
/*?*/ 		pOldVirtMenu = pMenu;
/*?*/ 		pBindings->ENTERREGISTRATIONS();
/*N*/ 	}
/*N*/ 
/*N*/ 	SfxVirtualMenu *pVMenu = 0;
/*N*/ 	if ( bMenuBar )
/*N*/ 	{
/*N*/         ResId aId( GetType(), pResMgr );
/*N*/         aId.SetRT(RSC_MENU);
/*N*/         if ( Resource::GetResManager()->IsAvailable( aId ) )
/*N*/         {
/*N*/             MenuBar *pSvMenu = new MenuBar( ResId(GetType(), pResMgr) );
/*N*/ 			SfxMenuManager::EraseItemCmds( pSvMenu ); // Remove .uno cmds to be compatible with 6.0/src641
/*N*/             TryToHideDisabledEntries_Impl( pSvMenu );
/*N*/             pVMenu = new SfxVirtualMenu( pSvMenu, FALSE, *pBindings, bOLE, TRUE );
/*N*/         }
/*N*/         else
/*N*/         {
/*?*/             MenuBar *pSvMenu = new MenuBar;
/*?*/             pVMenu = new SfxVirtualMenu( pSvMenu, FALSE, *pBindings, bOLE, TRUE );
/*N*/         }
/*N*/ 	}
/*N*/ 	else
/*N*/ 	{
/*N*/ 		ResId aResId(GetType());
/*N*/ 		aResId.SetRT(RSC_MENU);
/*N*/ 		aResId.SetResMgr(pResMgr);
/*N*/ 		Menu *pSVMenu = new PopupMenu( aResId );
/*N*/ 		SfxMenuManager::EraseItemCmds( pSVMenu ); // Remove .uno cmds to be compatible with 6.0/src641
/*N*/ 
/*N*/ 		if ( bAddClipboardFuncs )
/*N*/ 		{
/*?*/ 			USHORT n, nCount = pSVMenu->GetItemCount();
/*?*/ 			for ( n=0; n<nCount; n++ )
/*?*/ 			{
/*?*/ 				USHORT nId = pSVMenu->GetItemId( n );
/*?*/ 				if ( nId == SID_COPY || nId == SID_CUT || nId == SID_PASTE )
/*?*/ 					break;
/*?*/ 			}
/*?*/ 
/*?*/ 			if ( n == nCount )
/*?*/ 			{
/*?*/ 				PopupMenu aPop( SfxResId( MN_CLIPBOARDFUNCS ) );
/*?*/ 				nCount = aPop.GetItemCount();
/*?*/ 				pSVMenu->InsertSeparator();
/*?*/ 				for ( n=0; n<nCount; n++ )
/*?*/ 				{
/*?*/ 					USHORT nId = aPop.GetItemId( n );
/*?*/ 					pSVMenu->InsertItem( nId, aPop.GetItemText( nId ), aPop.GetItemBits( nId ) );
/*?*/ 				}
/*N*/ 			}
/*N*/ 		}
/*N*/ 
/*N*/ 		pVMenu = new SfxVirtualMenu( pSVMenu, FALSE, *pBindings, TRUE, TRUE );
/*N*/ 	}
/*N*/ 
/*N*/ 	Construct(*pVMenu);
/*N*/ 
/*N*/     if ( bMenuBar && pOldVirtMenu )
/*N*/ 	{
/*?*/         SfxMenuBarManager *pBar = (SfxMenuBarManager*) this;
/*?*/         MenuBar* pOldBar = (MenuBar*) pOldVirtMenu->GetSVMenu();
/*?*/         MenuBar* pSvBar = (MenuBar*) GetMenu()->GetSVMenu();
/*?*/         if ( pBar->GetWindow()->GetMenuBar() == pOldBar )
/*?*/             pBar->GetWindow()->SetMenuBar( pSvBar );
/*N*/ 	}
/*N*/ 
/*N*/ 	if (pOldVirtMenu)
/*N*/ 	{
/*?*/ 		delete pOldVirtMenu;
/*?*/ 		pBindings->LEAVEREGISTRATIONS();
/*N*/ 	}
/*N*/ 
/*N*/     SetDefault( TRUE );
/*N*/ }

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

/*?*/ String SfxMenuManager::GetStreamName() const
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); String aString;return aString;//STRIP001 
/*?*/ }

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

// Baut aus einem ConfigItemArray rekursiv das StarView-Menu auf


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

// Baut aus einem ConfigStream rekursiv das StarView-Menu auf


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

// append a binding by function-id


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

// append a separator


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

// append a popup (sub)-menu


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

// end a sub-menu


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

// executes the function for the selected item
extern int Select_Impl( void*, void* ) ;

/*N*/ IMPL_LINK( SfxMenuManager, Select, Menu *, pMenu )
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 	return TRUE;
/*N*/ }

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

// resets the item iterator, FALSE if none


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

// skips to the next item, FALSE if no more


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

// TRUE if current item is a binding



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

// TRUE if current item is a separator


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

// TRUE if current item is a popup; may be also a binding


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

// returns sub-menu-level


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

// id of binding if IsBinding()


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

// title of popup if IsPopup()


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


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

// call this before reconfiguring


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

// call this after reconfiguring



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

// reload all KeyCodes


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

/*N*/ BOOL SfxMenuManager::IsPopupFunction( USHORT nId )
/*N*/ {
/*N*/ 	return nId == SID_PICKLIST ||
/*N*/ 		   nId == SID_MDIWINDOWLIST ||
/*N*/ 		   nId == SID_HELPMENU ||
/*N*/ 		   nId == SID_ADDONLIST;
/*N*/ }

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

// creates a menu-manager and loads it from resource RID_DEFAULTMENU or RID_DEFAULTPLUGINMENU
/*
SfxMenuBarManager::SfxMenuBarManager( SfxBindings& rBindings, BOOL bPlugin ) :

	SfxMenuManager( bPlugin ? RID_DEFAULTPLUGINMENU : RID_DEFAULTMENU, rBindings, TRUE ),

	pWindow( rBindings.GetSystemWindow() )

{
	DBG_MEMTEST();

	// initialize ObjectMenus
	for ( int n = 0; n < 4; ++n )
	{
		aObjMenus[n].nId = 0;
		aObjMenus[n].pPMMgr = NULL;
		aObjMenus[n].pResMgr = NULL;
	}
}
*/
//--------------------------------------------------------------------

// creates a menu-manager and loads it from a resource

/*N*/ SfxMenuBarManager::SfxMenuBarManager( const ResId& rResId, SfxBindings &rBindings, SfxConfigManager* pMgr, BOOL bOLE )
/*N*/     : SfxMenuManager( rResId, rBindings, pMgr, TRUE )
/*N*/     , pWindow( rBindings.GetSystemWindow() )
/*N*/     , bDowning( FALSE )
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 
/*N*/ 	// initialize ObjectMenus
/*N*/ 	for ( int n = 0; n < 4; ++n )
/*N*/ 	{
/*N*/ 		aObjMenus[n].nId = 0;
/*N*/ 		aObjMenus[n].pPMMgr = NULL;
/*N*/ 		aObjMenus[n].pResMgr = NULL;
/*N*/ 	}
/*N*/ 
/*N*/ 	// #107258# full menu bar hierarchy is needed, if accessibility is enabled
/*N*/ 	BOOL bAccessibilityEnabled = Application::GetSettings().GetMiscSettings().GetEnableATToolSupport();
/*N*/     SetForceCtrlCreateMode( bOLE || bAccessibilityEnabled );
/*N*/ 
/*N*/ 	Initialize();
/*N*/ }


/*N*/ SfxMenuBarManager::~SfxMenuBarManager()
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 
/*N*/ 	DBG_ASSERT(!aObjMenus[0].pPMMgr || !aObjMenus[1].pPMMgr ||
/*N*/ 			   !aObjMenus[2].pPMMgr || !aObjMenus[3].pPMMgr,
/*N*/ 			   "da sind noch ObjectMenus" );
/*N*/ 
/*N*/     bDowning = TRUE;
/*N*/     ResetObjectMenus();
/*N*/ 	UpdateObjectMenus();
/*N*/ 
/*N*/     MenuBar* pSvBar = (MenuBar*) GetMenu()->GetSVMenu();
/*N*/     if ( pWindow && pWindow->GetMenuBar() == pSvBar )
/*?*/         pWindow->SetMenuBar( 0 );
/*N*/ }


/*
SvStream* SfxMenuBarManager::GetDefaultStream( StreamMode nMode )
{
	String aUserConfig = SvtPathOptions().GetUserConfigPath();
    INetURLObject aObj( aUserConfig );
    aObj.insertName( GetStreamName() );
    return ::utl::UcbStreamHelper::CreateStream( aObj.GetMainURL( INetURLObject::NO_DECODE ), nMode );
}

BOOL SfxMenuBarManager::Load( SvStream& rStream, BOOL bOLEServer )
{
	SetForceCtrlCreateMode( bOLEServer );
	Menu *pSVMenu = LoadMenuBar( rStream );
	if ( pSVMenu )
		Construct_Impl( pSVMenu, FALSE );
	return ( pSVMenu != NULL );
}
*/

//------------------------------------------------------------------------
// To be compatible to 6.0/src641 we have to erase .uno commands we got
// from resource file. Otherwise these commands get saved to our XML configurations
// files and 6.0/src641 is not able to map these to slot ids again!!!
/*N*/ void SfxMenuManager::EraseItemCmds( Menu* pMenu )
/*N*/ {
/*N*/ 	USHORT nCount = pMenu->GetItemCount();
/*N*/ 	for ( USHORT nSVPos = 0; nSVPos < nCount; nSVPos++ )
/*N*/ 	{
/*N*/ 		USHORT nId = pMenu->GetItemId( nSVPos );
/*N*/ 		PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nId );
/*N*/ 		if ( pPopupMenu )
/*N*/ 			EraseItemCmds( pPopupMenu );
/*N*/ 		else if ( nId > 0 )
/*N*/ 		{
/*N*/ 			// Remove .uno commands to be compatible with 6.0/src641
/*N*/ 			String aCommand = pMenu->GetItemCommand( nId );
/*N*/ 			if ( aCommand.CompareToAscii(".uno:", 5 ) == COMPARE_EQUAL )
/*N*/ 				pMenu->SetItemCommand( nId, String() );
/*N*/ 		}
/*N*/ 	}
/*N*/ }

//------------------------------------------------------------------------
// Restore the correct macro ID so that menu items with an associated accelerator
// are correctly identified. This ensures that the accelerator info is displayed in
// the menu.

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


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


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

/*N*/ void SfxMenuBarManager::ResetObjectMenus()
/*N*/ {
/*N*/ 	for ( int n = 0; n <= 3; ++n )
/*N*/ 		aObjMenus[n].nId = 0;
/*N*/ }

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

/*N*/ void SfxMenuBarManager::SetObjectMenu( USHORT nPos, const ResId& rResId )
/*N*/ {
/*N*/ 	nPos -= SID_OBJECTMENU0;
/*N*/ 	DBG_ASSERT( nPos < 4, "only 4 object Menu positions defined" );
/*N*/ 
/*N*/ 	aObjMenus[nPos].nId = rResId.GetId();
/*N*/ 	aObjMenus[nPos].pResMgr = rResId.GetResMgr();
/*N*/ }


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


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


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

/*N*/ void SfxMenuBarManager::UpdateObjectMenus()
/*N*/ {
/*N*/ 	Menu *pMenu = GetMenu()->GetSVMenu();
/*N*/ 	for ( int n = 0; n < 4; ++n )
/*N*/ 	{
/*N*/ 		SfxPopupMenuManager *pOldPopup = aObjMenus[n].pPMMgr;
/*N*/ 
/*N*/         // check if this object menue is in the menubar at all
/*N*/         USHORT nId = n + SID_OBJECTMENU0;
/*N*/         BOOL bInMenu = ( pMenu->GetItemPos( nId ) != MENU_ITEM_NOTFOUND );
/*N*/         PopupMenu* pOldSVPopup = pMenu->GetPopupMenu( nId );
/*N*/ 
/*N*/ 		if ( aObjMenus[n].nId )
/*N*/ 		{
/*N*/             if ( bInMenu )
/*N*/ 			{
/*N*/                 if ( !pOldPopup && pOldSVPopup )
/*N*/                 {
/*N*/                     // remove dummy popup
/*N*/                     pMenu->SetPopupMenu( nId, 0 );
/*N*/                     delete pOldSVPopup;
/*N*/                 }
/*N*/ 
/*N*/                 if ( !pOldPopup || ( pOldPopup && pOldPopup->GetType() != aObjMenus[n].nId ) )
/*N*/ 				{
/*N*/ 					ResId aResId( aObjMenus[n].nId, aObjMenus[n].pResMgr );
/*N*/ 					aObjMenus[n].pPMMgr =
/*N*/ 						new SfxPopupMenuManager( aResId , GetBindings() );
/*N*/ 					aObjMenus[n].pPMMgr->Initialize();
/*N*/ 				}
/*N*/ 				else
/*N*/                     // popups remains the same, prevent deletion
/*N*/ 					pOldPopup = NULL;
/*N*/ 
/*N*/                 pMenu->SetPopupMenu( nId, (PopupMenu*) aObjMenus[n].pPMMgr->GetMenu()->GetSVMenu() );
/*N*/                 pMenu->EnableItem( nId, TRUE );
/*N*/ 			}
/*N*/ 		}
/*N*/ 		else if ( pOldPopup )
/*N*/ 		{
/*N*/             if ( pMenu->GetItemPos( nId ) != MENU_ITEM_NOTFOUND )
/*N*/ 			{
/*N*/ //                pMenu->EnableItem( nId, FALSE );
/*N*/                 pMenu->SetPopupMenu( nId, 0 );
/*N*/ 			}
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( pOldPopup )
/*N*/ 		{
/*N*/             // no new popup menu created, so reset pointer before deleting menu
/*N*/ 			if ( pOldPopup == aObjMenus[n].pPMMgr )
/*N*/ 				aObjMenus[n].pPMMgr = NULL;
/*N*/ 			pOldPopup->StoreConfig();
/*N*/ 			delete pOldPopup;
/*N*/ 		}
/*N*/ 
/*N*/         if ( bDowning )
/*N*/         {
/*N*/             // delete possible empty popup menues
/*N*/             PopupMenu *pPop = pMenu->GetPopupMenu( nId );
/*N*/             if ( pPop )
/*N*/             {
/*N*/                 pMenu->SetPopupMenu( nId, 0 );
/*N*/                 delete pPop;
/*N*/             }
/*N*/         }
/*N*/         else if ( bInMenu )
/*N*/         {
/*N*/             // insert an empty popup window
/*N*/             if ( !aObjMenus[n].pPMMgr && !pMenu->GetPopupMenu( nId ) )
/*N*/                 pMenu->SetPopupMenu( nId, new PopupMenu );
/*N*/         }
/*N*/ 	}
/*N*/ }

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

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

// don't insert Popups into ConfigManager, they are not configurable at the moment !
/*N*/ SfxPopupMenuManager::SfxPopupMenuManager(const ResId& rResId, SfxBindings &rBindings )
/*N*/     : SfxMenuManager( rResId, rBindings, NULL/*rBindings.GetConfigManager( rResId.GetId() )*/, FALSE )
/*N*/ 	, pSVMenu( NULL )
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ }

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


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


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



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


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


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


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


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


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


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


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



/*?*/ int SfxMenuManager::Load( SotStorage& rStorage )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return 0;//STRIP001 
/*?*/ }

/*?*/ BOOL SfxMenuManager::Store( SotStorage& rStorage )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return 0;//STRIP001 
/*?*/ }

/*N*/ int SfxMenuBarManager::Load( SotStorage& rStorage )
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return 0;//STRIP001 
/*N*/ }

/*N*/ BOOL SfxMenuBarManager::Store( SotStorage& rStorage )
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE; //STRIP001 
/*N*/ }




/*?*/ BOOL SfxMenuBarManager::ReInitialize()
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return false;//STRIP001 
/*?*/ }
}
