/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sfx2_tbxcfg.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2006/01/05 17:51:37 $
 *
 *  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
 *
 ************************************************************************/

// #pragma ******************************************************************

#ifdef MSC
#pragma warning (disable:4355)
#endif

// #include *****************************************************************

#pragma hdrstop

#include "app.hxx"
#include "msg.hxx"
#include "msgdescr.hxx"
#include "msgpool.hxx"
#include "resmgr.hxx"
#include "tbxmgr.hxx"
#include "tbxcfg.hxx"
#include "sfxresid.hxx"
#include "toolbox.hrc"
namespace binfilter {

// static-Variablen *********************************************************

static const char *pSeparatorStr = "--------------------";

// SfxToolBoxConfigDialog::Ctor() **********************************************

SfxToolBoxConfigDialog::SfxToolBoxConfigDialog( Window *pParent ) :

	ModalDialog( pParent, SfxResId( DLG_TOOLBOXCONFIG ) ),

	aOKButton           ( this, ResId( BTN_OK              ) ),
	aCancelButton       ( this, ResId( BTN_CANCEL          ) ),
	aOptionsButton      ( this, ResId( BTN_OPTIONS         ) ),
	aUpButton           ( this, ResId( BTN_UP              ) ),
	aDownButton         ( this, ResId( BTN_DOWN            ) ),
	aNewButton          ( this, ResId( BTN_NEW             ) ),
	aChangeButton       ( this, ResId( BTN_CHANGE          ) ),
	aRemoveButton       ( this, ResId( BTN_REMOVE          ) ),
	aEntriesBox         ( this, ResId( BOX_ENTRIES         ) ),
	aBitmapBitmap       ( this, ResId( BMP_BITMAP          ) ),
	aFunctionTextText   ( this, ResId( TXT_FUNCTIONTEXT    ) ),
	aFunctionInfoText   ( this, ResId( TXT_FUNCTIONINFO    ) ),
	aDescriptionTextText( this, ResId( TXT_DESCRIPTIONTEXT ) ),
	aDescriptionInfoText( this, ResId( TXT_DESCRIPTIONINFO ) ),
	aToolBoxGroup       ( this, ResId( GRP_TOOLBOX         ) ),
	aGroupText          ( this, ResId( TXT_GROUP           ) ),
	aGroupBox           ( this, ResId( BOX_GROUP           ) ),
	aFunctionText       ( this, ResId( TXT_FUNCTION        ) ),
	aFunctionBox        ( this, ResId( BOX_FUNCTION        ) ),
	aFunctionsGroup     ( this, ResId( GRP_FUNCTIONS       ) ),

	pMgr( SFX_APP()->GetToolBoxManager() ),

	eAlign     ( pMgr->GetAlign     () ),
	eButtonType( pMgr->GetButtonType() ),
	eSymbolsSize ( pMgr->GetSymbolsSize () )

{
	FreeResource();

	// nicht fetten Font einstellen
	Font aFont( pApp->GetAppFont() );
	aFont.ChangeWeight( WEIGHT_NORMAL );
	aFont.ChangeTransparent( TRUE );
	aFunctionInfoText.SetFont(aFont);
	aDescriptionInfoText.SetFont(aFont);

	// Handler installieren
	aOKButton	  .ChangeClickHdl ( LINK( this, SfxToolBoxConfigDialog, OKHdl	   ) );
	aOptionsButton.ChangeClickHdl ( LINK( this, SfxToolBoxConfigDialog, OptionsHdl ) );
	aUpButton	  .ChangeClickHdl ( LINK( this, SfxToolBoxConfigDialog, UpHdl	   ) );
	aDownButton   .ChangeClickHdl ( LINK( this, SfxToolBoxConfigDialog, DownHdl    ) );
	aNewButton	  .ChangeClickHdl ( LINK( this, SfxToolBoxConfigDialog, NewHdl	   ) );
	aChangeButton .ChangeClickHdl ( LINK( this, SfxToolBoxConfigDialog, ChangeHdl  ) );
	aRemoveButton .ChangeClickHdl ( LINK( this, SfxToolBoxConfigDialog, RemoveHdl  ) );
	aEntriesBox   .ChangeSelectHdl( LINK( this, SfxToolBoxConfigDialog, SelectHdl  ) );
	aGroupBox	  .ChangeSelectHdl( LINK( this, SfxToolBoxConfigDialog, SelectHdl  ) );
	aFunctionBox  .ChangeSelectHdl( LINK( this, SfxToolBoxConfigDialog, SelectHdl  ) );

	// aToolArr initialisieren

	pApp->Wait();

	BOOL bItem = pMgr->FirstItem();
	while ( bItem )
	{
		if ( pMgr->IsBinding() )
			aToolArr.Append( pMgr->GetId() );
		else
			aToolArr.Append( 0 );

		bItem = pMgr->NextItem();
	}

	// aEntriesBox initialisieren

	for ( USHORT i = 0; i < aToolArr.Count(); i++ )
		aEntriesBox.InsertEntry( MakeEntry( aToolArr[ i ] ) );
	aEntriesBox.InsertEntry( String() );

	aEntriesBox.SelectEntryPos( 0 );
	aEntriesBox.GrabFocus();

	// aGroupBox initialisieren

	for ( i = 0; i < SFX_MESSAGEPOOL().GetGroupCount(); i++ )
		aGroupBox.InsertEntry( SFX_MESSAGEPOOL().SeekGroup( i ) );

	aGroupBox.SelectEntryPos( 0 );
	aGroupBox.GetSelectHdl().Call( &aGroupBox );

	aEntriesBox.GetSelectHdl().Call( &aEntriesBox );

	pApp->Wait( FALSE );
}

/* SfxToolBoxConfigDialog::OKHdl() *********************************************

Konfiguriert den ToolBox-Manager neu.

****************************************************************************/

IMPL_LINK( SfxToolBoxConfigDialog, OKHdl, Button *, pButton )
{
	pApp->Wait();
	pMgr->Clear();
	for ( USHORT i = 0; i < aToolArr.Count(); i++ )
		if ( aToolArr[ i ] )
			pMgr->AppendItem( aToolArr[ i ] );
		else
			pMgr->AppendSeparator();
	pMgr->Reconfigure();

	pMgr->ChangeAlign     ( eAlign      );
	pMgr->ChangeButtonType( eButtonType );
	pMgr->ChangeSymbolsSize ( eSymbolsSize  );

	pApp->Wait( FALSE );

	EndDialog( RET_OK );
	return 0;
}


/* SfxToolBoxConfigDialog::OptionsHdl() ****************************************

Fuehrt SfxToolBoxOptionsDialog aus.

****************************************************************************/

IMPL_LINK( SfxToolBoxConfigDialog, OptionsHdl, Button *, pButton )
{
	SfxToolBoxOptionsDialog *pDlg = new SfxToolBoxOptionsDialog( this );

	if ( pDlg->Execute() == RET_OK )
	{
		eAlign      = pDlg->GetAlign();
		eButtonType = pDlg->GetButtonType();
		eSymbolsSize= pDlg->GetSymbolsSize();
	}

	delete pDlg;
	return 0;
}


/* SfxToolBoxConfigDialog::UpHdl() *********************************************

Verschiebt einen ToolBox-Eintrag nach oben.

****************************************************************************/

IMPL_LINK( SfxToolBoxConfigDialog, UpHdl, Button *, pButton )
{
	USHORT nPos = aEntriesBox.GetSelectEntryPos(),
		   nId1 = aToolArr[ nPos - 1 ],
		   nId2 = aToolArr[ nPos     ];

	aEntriesBox.ChangeUpdateMode( FALSE );
	aEntriesBox.RemoveEntry( nPos - 1 );
	aEntriesBox.RemoveEntry( nPos - 1 );
	aEntriesBox.InsertEntry( MakeEntry( nId1 ), nPos - 1 );
	aEntriesBox.InsertEntry( MakeEntry( nId2 ), nPos - 1 );
	aEntriesBox.ChangeUpdateMode( TRUE );

	aToolArr[ nPos - 1 ] = nId2;
	aToolArr[ nPos     ] = nId1;

	aEntriesBox.SelectEntryPos( nPos - 1);
	aEntriesBox.GetSelectHdl().Call( &aEntriesBox );
	return 0;
}

/* SfxToolBoxConfigDialog::DownHdl() *******************************************

Verschiebt einen ToolBox-Eintrag nach unten.

****************************************************************************/

IMPL_LINK( SfxToolBoxConfigDialog, DownHdl, Button *, pButton )
{
	USHORT nPos = aEntriesBox.GetSelectEntryPos(),
		   nId1 = aToolArr[ nPos     ],
		   nId2 = aToolArr[ nPos + 1 ];

	aEntriesBox.ChangeUpdateMode( FALSE );
	aEntriesBox.RemoveEntry( nPos );
	aEntriesBox.RemoveEntry( nPos );
	aEntriesBox.InsertEntry( MakeEntry( nId1 ), nPos );
	aEntriesBox.InsertEntry( MakeEntry( nId2 ), nPos );
	aEntriesBox.ChangeUpdateMode( TRUE );

	aToolArr[ nPos     ] = nId2;
	aToolArr[ nPos + 1 ] = nId1;

	aEntriesBox.SelectEntryPos( nPos + 1);
	aEntriesBox.GetSelectHdl().Call( &aEntriesBox );
	return 0;
}


/* SfxToolBoxConfigDialog::NewHdl() ********************************************

Fuegt einen neuen ToolBox-Eintrag ein.

****************************************************************************/

IMPL_LINK( SfxToolBoxConfigDialog, NewHdl, Button *, pButton )
{
	USHORT nPos = aEntriesBox.GetSelectEntryPos();

	aEntriesBox.InsertEntry( MakeEntry( nCurId ), nPos );
	aToolArr   .Insert     ( nPos, nCurId );

	aEntriesBox.SelectEntryPos( nPos );
	aEntriesBox.GetSelectHdl().Call( &aEntriesBox );
	return 0;
}

/* SfxToolBoxConfigDialog::ChangeHdl() *****************************************

Aendert einen ToolBox-Eintrag.

****************************************************************************/

IMPL_LINK( SfxToolBoxConfigDialog, ChangeHdl, Button *, pButton )
{
	USHORT nPos = aEntriesBox.GetSelectEntryPos();

	aEntriesBox.ChangeUpdateMode( FALSE );
	aEntriesBox.RemoveEntry( nPos );
	aEntriesBox.InsertEntry( MakeEntry( nCurId ), nPos );
	aEntriesBox.ChangeUpdateMode( TRUE );

	aToolArr[ nPos ] = nCurId;

	aEntriesBox.SelectEntryPos( nPos );
	aEntriesBox.GetSelectHdl().Call( &aEntriesBox );
	return 0;
}

/* SfxToolBoxConfigDialog::RemoveHdl() *****************************************

Loescht einen ToolBox-Eintrag.

****************************************************************************/

IMPL_LINK( SfxToolBoxConfigDialog, RemoveHdl, Button *, pButton )
{
	USHORT nPos = aEntriesBox.GetSelectEntryPos();

	aEntriesBox.RemoveEntry( nPos );
	aToolArr   .Remove     ( nPos, 1 );

	aEntriesBox.SelectEntryPos( nPos );
	aEntriesBox.GetSelectHdl().Call( &aEntriesBox );
	return 0;
}

/* SfxToolBoxConfigDialog::SelectHdl() *****************************************

Select-Handler fuer alle ListBoxen.

****************************************************************************/

IMPL_LINK( SfxToolBoxConfigDialog, SelectHdl, ListBox *, pListBox )
{
	if ( pListBox == &aEntriesBox )
	{
		// Eintrag ausgewaehlt: Buttons enablen/disablen,
		//                      aktuelle Id wechseln

		USHORT nPos   = aEntriesBox.GetSelectEntryPos(),
			   nCount = aEntriesBox.GetEntryCount();

		aUpButton.Enable( nPos && nPos < nCount - 1 );
		aDownButton.Enable( nPos < nCount - 2 );
		aRemoveButton.Enable( nPos < nCount - 1 );

		if ( nPos < nCount - 1 )
			SetCurId( aToolArr[ nPos ] );
		else
			SetCurId( 0 );
	}
	else if ( pListBox == &aGroupBox )
	{
		// Gruppe ausgewaehlt: aFunctionBox initialisieren

		aFunctionBox.Clear();
		aFunctionArr.Clear();

		aFunctionBox.InsertEntry( String ( pSeparatorStr ) );
		aFunctionArr.Append     ( 0 );

		SFX_MESSAGEPOOL().SeekGroup( aGroupBox.GetSelectEntryPos() );

		const SfxSlot *pSfxSlot = SFX_MESSAGEPOOL().FirstMessage();
		while ( pSfxSlot )
		{
			if ( !aFunctionArr.Contains( pSfxSlot->GetSlotId() ) )
			{
//!                aFunctionBox.InsertEntry( SfxMessageDescription( pSfxSlot->GetId() ).GetFunctionName() );
				aFunctionArr.Append 	( pSfxSlot->GetSlotId() );
			}

			pSfxSlot = SFX_MESSAGEPOOL().NextMessage();
		}

		aFunctionBox.SelectEntryPos( 0 );
		aFunctionBox.GetSelectHdl().Call( &aFunctionBox );
	}
	else
	{
		// Funktion ausgewaehlt: aktuelle Id wechseln

		SetCurId( aFunctionArr[ aFunctionBox.GetSelectEntryPos() ] );
	}
	return 0;
}

/* SfxToolBoxConfigDialog::MakeEntry() *****************************************

Berechnet ListBox-Eintrag aus Funktions-Id.

****************************************************************************/

String SfxToolBoxConfigDialog::MakeEntry( USHORT nId ) const
{
	if ( nId )
	{
		String aStr = /*! SfxMessageDescription( nId ).GetFunctionName() + */ String( "  " );
		while ( aStr.Len() < 24 )
			aStr += " ";
		aStr += String( "[" ) + /*! SfxMessageDescription( nId ).GetFunctionName() + */ String( "]" );
		return aStr;
	}
	else
		return String( pSeparatorStr );
}

/* SfxToolBoxConfigDialog::SetCurId() ******************************************

Macht nId zur aktuellen Id.

****************************************************************************/

void SfxToolBoxConfigDialog::SetCurId( USHORT nId )
{
	nCurId = nId;

	// aNewButton enablen/disablen

	if ( nCurId )
	{
		// Id schon in Konfiguration enthalten?

		USHORT i      = 0;
		BOOL   bFound = FALSE;

		while ( i < aToolArr.Count() && !bFound )
			if ( aToolArr[ i ] == nCurId )
				bFound = TRUE;
			else
				i++;

		aNewButton.Enable( !bFound );
	}
	else
		aNewButton.Enable();

	// aChangeButton enablen/disablen

	USHORT nPos   = aEntriesBox.GetSelectEntryPos(),
		   nCount = aEntriesBox.GetEntryCount();

	aChangeButton.Enable( nPos < nCount - 1 &&
						  aToolArr[ nPos ] != nCurId );

	// Bitmap, Funktion und Beschreibung anzeigen

	if ( nCurId )
	{
		SFX_RESMANAGER().Enter();
		SfxMessageDescription *pDesc =
			SFX_RESMANAGER().CreateDescription(nCurId);

		aBitmapBitmap.ChangeBitmap( pDesc->GetSmallBitmap() );
		aFunctionTextText.Show();
		aFunctionInfoText.SetText( pDesc->GetFunctionName() );
		aDescriptionTextText.Show();
		aDescriptionInfoText.SetText( pDesc->GetHelpText() );
		delete pDesc;
		SFX_RESMANAGER().Leave();
	}
	else
	{
		aBitmapBitmap       .ChangeBitmap( Bitmap() );
		aFunctionTextText   .Hide();
		aFunctionInfoText   .SetText     ( String() );
		aDescriptionTextText.Hide();
		aDescriptionInfoText.SetText     ( String() );
	}
}

// SfxToolBoxOptionsDialog::Ctor() *********************************************

SfxToolBoxOptionsDialog::SfxToolBoxOptionsDialog( Window *pParent ) :

	ModalDialog( pParent, SfxResId( DLG_TOOLBOXOPTIONS ) ),

	aOKButton    ( this, ResId( BTN_OK       ) ),
	aCancelButton( this, ResId( BTN_CANCEL   ) ),
	aPositionText( this, ResId( TXT_POSITION ) ),
	aPositionBox ( this, ResId( BOX_POSITION ) ),
	aContentsText( this, ResId( TXT_CONTENTS ) ),
	aContentsBox ( this, ResId( BOX_CONTENTS ) ),
	aSymbolsText ( this, ResId( TXT_SYMBOLS  ) ),
	aSymbolsBox  ( this, ResId( BOX_SYMBOLS  ) ),
	aOptionsGroup( this, ResId( GRP_OPTIONS  ) ),

	pMgr( SFX_APP()->GetToolBoxManager() )

{
	FreeResource();

	// Bestehende Konfiguration auslesen

	switch ( pMgr->GetAlign() )
	{
		case BOXALIGN_TOP   : aPositionBox.SelectEntryPos( 0 ); break;
		case BOXALIGN_BOTTOM: aPositionBox.SelectEntryPos( 1 ); break;
		case BOXALIGN_LEFT  : aPositionBox.SelectEntryPos( 2 ); break;
		case BOXALIGN_RIGHT : aPositionBox.SelectEntryPos( 3 ); break;
	}

	switch ( pMgr->GetButtonType() )
	{
		case BUTTON_SYMBOL    : aContentsBox.SelectEntryPos( 0 ); break;
		case BUTTON_TEXT      : aContentsBox.SelectEntryPos( 1 ); break;
		case BUTTON_SYMBOLTEXT: aContentsBox.SelectEntryPos( 2 ); break;
	}

	switch ( pMgr->GetSymbolsSize() )
	{
		case SFX_SYMBOLS_SIZE_SMALL: aSymbolsBox.SelectEntryPos( 0 ); break;
		case SFX_SYMBOLS_SIZE_LARGE: aSymbolsBox.SelectEntryPos( 1 ); break;
	}

	aPositionBox.GrabFocus();
}

// SfxToolBoxOptionsDialog::GetAlign() *****************************************

ToolBoxAlign SfxToolBoxOptionsDialog::GetAlign() const
{
	switch ( aPositionBox.GetSelectEntryPos() )
	{
		case 0 : return BOXALIGN_TOP   ;
		case 1 : return BOXALIGN_BOTTOM;
		case 2 : return BOXALIGN_LEFT  ;
		default: return BOXALIGN_RIGHT ;
	}
}

// SfxToolBoxOptionsDialog::GetButtonType() ************************************

ButtonType SfxToolBoxOptionsDialog::GetButtonType() const
{
	switch ( aContentsBox.GetSelectEntryPos() )
	{
		case 0 : return BUTTON_SYMBOL    ;
		case 1 : return BUTTON_TEXT      ;
		default: return BUTTON_SYMBOLTEXT;
	}
}

// SfxToolBoxOptionsDialog::GetSymbolsSize() *************************************

SfxSymbolsSize SfxToolBoxOptionsDialog::GetSymbolsSize() const
{
	switch ( aSymbolsBox.GetSelectEntryPos() )
	{
		case 0 : return SFX_SYMBOLS_SIZE_SMALL;
		default: return SFX_SYMBOLS_SIZE_LARGE;
	}
}

}
