/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sfx2_stbmgr.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/27 19:45:11 $
 *
 *  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 hdrstop

#include "stbitem.hxx"
#include "msgpool.hxx"
#include "objsh.hxx"
#include "progress.hxx"
#include "workwin.hxx"
#include "objface.hxx"
#include "sfx.hrc"
#include "statbar.hrc"
#include "helpid.hrc"
#include "dispatch.hxx"
namespace binfilter {

using namespace ::framework;

static const USHORT nVersion = 5;

struct SfxStatusItemInf_Impl
{
	USHORT				nId;
	StatusBarItemBits	aBits;
	long				nWidth;
	long				nOffset;

	SfxStatusItemInf_Impl (USHORT n, long nW, StatusBarItemBits aSBits, long nOffs) :
		nId(n),
		aBits(aSBits),
		nWidth(nW),
		nOffset(nOffs)
	{}
};

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

DECL_PTRARRAY(SfxStatusItemArr_Impl, SfxStatusBarControl*, 2, 2 )//STRIP008 ;
DECL_PTRARRAY(SfxStatusItemInfArr_Impl, SfxStatusItemInf_Impl*, 4, 4 )//STRIP008 ;

SfxStatusItemInf_Impl* FindItem(SfxStatusItemInfArr_Impl, USHORT);

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



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

class SfxStatusBar_Impl: public StatusBar
{
	SfxStatusBarManager*	pMgr;
	Rectangle				aLastItemRect;
	Rectangle				aTrackingRect;
	SfxStatusBarControl*	pLastControl;
	USHORT                  nLastItemId;
	BOOL					bCaptured;
	USHORT					nMoveId;
	USHORT					nLastItemPos;
	long					nMovePos;
	Pointer 				aOldPointer;
	BOOL					bMoving;
	BOOL					bCapt;
	BOOL					bShow;
	BOOL					bLock;
	Window*					pLastFocusWin;

friend class SfxStatusBarManager;

private:

protected:
	virtual void    Click(){DBG_BF_ASSERT(0, "STRIP");} //STRIP001 virtual void    Click();
	virtual void    DoubleClick(){DBG_BF_ASSERT(0, "STRIP");} //STRIP001 virtual void    DoubleClick();
	virtual void	Command( const CommandEvent &rEvt ){DBG_BF_ASSERT(0, "STRIP");} //STRIP001 virtual void	Command( const CommandEvent &rEvt );
	virtual void	MouseButtonDown( const MouseEvent& rMEvt ){DBG_BF_ASSERT(0, "STRIP");} //STRIP001 virtual void	MouseButtonDown( const MouseEvent& rMEvt );
	virtual void	MouseMove( const MouseEvent& rMEvt );
	virtual void	MouseButtonUp( const MouseEvent& rMEvt ){DBG_BF_ASSERT(0, "STRIP");} //STRIP001 virtual void	MouseButtonUp( const MouseEvent& rMEvt );
	virtual void	UserDraw( const UserDrawEvent& rUDEvt);
	virtual void	KeyInput( const KeyEvent& rKEvent ){DBG_BF_ASSERT(0, "STRIP");} //STRIP001 virtual void	KeyInput( const KeyEvent& rKEvent );

public:
					SfxStatusBar_Impl( Window* pParent,
									   SfxStatusBarManager& rMgr );

};

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

/*N*/ SfxStatusBar_Impl::SfxStatusBar_Impl( Window* pParent,
/*N*/ 									  SfxStatusBarManager& rMgr )
/*N*/ :	StatusBar( pParent, WinBits( WB_LEFT | WB_3DLOOK ) ),
/*N*/ 	pMgr( &rMgr ),
/*N*/ 	nLastItemId( 0 ),
/*N*/ 	pLastControl( 0 ),
/*N*/ 	bCaptured(FALSE),
/*N*/ 	bMoving(FALSE),
/*N*/ 	nMoveId(0),
/*N*/ 	nLastItemPos(STATUSBAR_ITEM_NOTFOUND),
/*N*/ 	nMovePos(0),
/*N*/ 	bCapt(FALSE),
/*N*/ 	bShow(TRUE),
/*N*/ 	bLock(FALSE),
/*N*/ 	pLastFocusWin(0)
/*N*/ {
/*N*/ 	SetUniqueId( HID_STATUSBAR );
/*N*/ }


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







/*N*/ void SfxStatusBar_Impl::MouseMove( const MouseEvent& rEvt )
/*N*/ {
/*N*/ 	StatusBar::MouseMove(rEvt);
/*N*/ }




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

/*N*/ void SfxStatusBar_Impl::UserDraw(const UserDrawEvent& rUDEvt)
/*N*/ {
/*N*/ 	if ( !bLock )
/*N*/ 	{
/*N*/ 		// MI/#31218#: da kam ein Paint als keine Items gebunden waren, warum?
/*N*/ 		DBG_ASSERT( pMgr, "StatusBar: UserDraw without StatusBarManager" );
/*N*/ 		SfxStatusBarControl *pCtrl = pMgr
/*N*/ 								? pMgr->FindControl_Impl( rUDEvt.GetItemId() )
/*N*/ 								: 0;
/*N*/ 		DBG_ASSERT( !pMgr->GetBindings_Impl() || pCtrl, "StatusBar: unknown UserDraw (no items bound)" );
/*N*/ 		if ( pCtrl )
/*N*/ 			pCtrl->Paint( rUDEvt );
/*N*/ 	}
/*N*/ }

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

/*N*/ void SfxStatusBarManager::UseDefault()
/*N*/ {
/*N*/ 	((SfxStatusBar_Impl*)pBar)->bLock = TRUE;
/*N*/ 	pBindings->ENTERREGISTRATIONS();
/*N*/ 
/*N*/ 	if ( pBar->GetItemCount() )
/*N*/ 		// Falls neu initialisiert wird
/*?*/ 		{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 Clear_Impl();
/*N*/ 
/*N*/ 	pShell->FillStatusBar( *pBar );
/*N*/ 
/*N*/ 	// Visible-Status merken
/*N*/     ((SfxStatusBar_Impl*)pBar)->bShow = TRUE;
/*N*/ 
/*N*/ 	// Controller erzeugen
/*N*/ 	Construct();
/*N*/ 
/*N*/ 	pBindings->LEAVEREGISTRATIONS();
/*N*/ 	((SfxStatusBar_Impl*)pBar)->bLock = FALSE;
/*N*/ 
/*N*/ 	// Die Daten der vorhandenen Items merken
/*N*/ 	for (USHORT n=0; n<pItems->Count(); n++)
/*?*/ 		delete (*pItems)[n];
/*N*/ 	pItems->Clear();
/*N*/ 	for ( USHORT nItem = 0; nItem < pBar->GetItemCount(); ++nItem )
/*N*/ 	{
/*N*/ 		USHORT nId = pBar->GetItemId(nItem);
/*N*/ 		long nWidth = pBar->GetItemWidth(nId);
/*N*/ 		StatusBarItemBits aBits = pBar->GetItemBits(nId);
/*N*/ 		long nOffs = pBar->GetItemOffset(nId);
/*N*/ 		SfxStatusItemInf_Impl* pItem = new SfxStatusItemInf_Impl(nId, nWidth, aBits, nOffs);
/*N*/ 		pItems->Append(pItem);
/*N*/ 	}
/*N*/ 
/*N*/     SetDefault( TRUE );
/*N*/ }


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

/*N*/ void SfxStatusBarManager::Construct()
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 	DBG_ASSERT(pBindings, "Statuszeile ohne Bindings!");
/*N*/ 
/*N*/ 	pBoundItems = new SfxStatusItemArr_Impl;
/*N*/ 
/*N*/ 	Font aFont( pBar->GetFont() );
/*N*/ 	aFont.SetWeight( WEIGHT_NORMAL );
/*N*/ 	pBar->SetFont( aFont );
/*N*/ 
/*N*/ 	const SfxSlotPool& rSlotPool = SFX_APP()->GetSlotPool( pBindings->GetDispatcher_Impl()->GetFrame() );
/*N*/ 
/*N*/ 	for ( USHORT nItem = 0; nItem < pBar->GetItemCount(); ++nItem )
/*N*/ 	{
/*N*/ 		USHORT nId = pBar->GetItemId( nItem );
/*N*/ #ifdef DBG_UTIL
/*N*/ 		const SfxSlot *pSlot = SFX_SLOTPOOL().GetSlot( nId );
/*N*/ 		if ( pSlot && !pSlot->IsMode( SFX_SLOT_STATUSBARCONFIG ) )
/*N*/ 		{
/*?*/ 			ByteString aStr( "Slot " );
/*?*/ 			aStr += ByteString::CreateFromInt32( nId );
/*?*/ 			aStr += ByteString( " : StatusbarConfig fehlt!" );
/*?*/ 			DBG_ERROR( aStr.GetBuffer() );
/*N*/ 		}
/*N*/ #endif
/*N*/ 		pBoundItems->Append( SfxStatusBarControl::CreateControl(
/*N*/ 				nId, pBar, *pBindings, pShell->GetInterface()->GetModule() ) );
/*N*/ 		pBar->SetHelpId( nId, nId );
/*N*/ 		pBar->SetAccessibleName( nId, rSlotPool.GetSlotName_Impl( nId ) );
/*N*/ 	}
/*N*/ 
/*N*/     // Immer anzeigen, Statuszeile wird "uber #Taskbar ein/ausgeschaltet
/*N*/ 	pBar->Show();
/*N*/ }


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

/*N*/ SfxStatusBarManager::SfxStatusBarManager(Window* pParent, SfxBindings &rBindings,
/*N*/ 						SfxShell *pSh, SfxConfigManager* pMgr, USHORT nId, StatusBar *p) :
/*N*/     SfxConfigItem( nId, pMgr ),
/*N*/ 	pBar( p ),
/*N*/ 	pBoundItems( 0 ),
/*N*/ 	pShell(pSh),
/*N*/ 	pBindings(&rBindings)
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 
/*N*/ 	if ( pBar )
/*?*/ 		{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 ((SfxStatusBar_Impl*)pBar)->Init( this );
/*N*/ 	else
/*N*/ 		pBar = new SfxStatusBar_Impl( pParent, *this );
/*N*/ 
/*N*/ 	pItems = new SfxStatusItemInfArr_Impl;
/*N*/ 	StartListening(rBindings);
/*N*/ 	Initialize();
/*N*/ }


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

/*N*/ SfxStatusBarManager::~SfxStatusBarManager()
/*N*/ {
/*N*/ 	DBG_MEMTEST();
/*N*/ 
/*N*/ 	((SfxStatusBar_Impl*)pBar)->pMgr = 0;
/*N*/ 
/*N*/     // allen SfxProgress bescheid geben; auch nicht sichtbare Dokumente können einen Progress laufen haben,
/*N*/     // nämlich in einer anderen View, wenn sie gerade geladen werden!
/*N*/     for ( SfxObjectShell* pObjSh = SfxObjectShell::GetFirst( 0, sal_False );
/*N*/ 		  pObjSh;
/*N*/           pObjSh = SfxObjectShell::GetNext( *pObjSh, 0, sal_False ) )
/*N*/ 		if ( pObjSh->GetProgress() &&
/*N*/ 			 pObjSh->GetProgress()->StatusBarManagerGone_Impl(this) )
/*N*/ 			break;
/*N*/ 
/*N*/ 	if (pBindings)
/*N*/ 	{
/*N*/ 		pBindings->ENTERREGISTRATIONS();
/*N*/ 		for ( USHORT n = pBoundItems->Count(); n > 0; --n )
/*N*/ 			delete pBoundItems->GetObject(n-1);
/*N*/ 		pBindings->LEAVEREGISTRATIONS();
/*N*/ 		EndListening(*pBindings);
/*N*/ 		pBindings = 0;
/*N*/ 	}
/*N*/ 
/*N*/ 	delete pBoundItems;
/*N*/ 
/*N*/ 	for (USHORT n=0; n<pItems->Count(); n++)
/*N*/ 		delete (*pItems)[n];
/*N*/ 
/*N*/ 	delete pItems;
/*N*/ }


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



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



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


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


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

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

// Beginn Fortschrittsanzeige

/*N*/ void    SfxStatusBarManager::StartProgressMode(
/*N*/ 	const String &rText,		// Text, der waehrend der Forrtschrittsanzeige in der Statuszeile erscheint
/*N*/ 	ULONG nMax)					// Maximalwert (100 %)
/*N*/ {
/*N*/ 	nMaxProgress = nMax;
/*N*/ 	pBar->StartProgressMode(rText);
/*N*/ }

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

// Status Fortschrittsanzeige

/*N*/ void SfxStatusBarManager::SetProgressState
/*N*/ (
/*N*/ 	ULONG nPosition	// Status relativ zum initial "ubergebenen Maximalwert
/*N*/ )
/*N*/ {
/*N*/ 	DBG_ASSERT( nPosition < ULONG_MAX / 100, "ULONG overflow" );
/*N*/ 	USHORT nVal = nMaxProgress ? (USHORT)(nPosition * 100L / nMaxProgress) : 0;
/*N*/ 	pBar->SetProgressValue( nVal );
/*N*/ }

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

// Ende Fortschrittsanzeige

/*N*/ void    SfxStatusBarManager::EndProgressMode()
/*N*/ {
/*N*/ 	pBar->EndProgressMode();
/*N*/ }

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

// Hilfetext anzeigen


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

/*N*/ SfxStatusBarControl* SfxStatusBarManager::FindControl_Impl( USHORT nId ) const
/*N*/ {
/*N*/ 	DBG_ASSERT( pBoundItems, "StatusBar: no items bound" );
/*N*/ 	if ( !pBoundItems )
/*N*/ 		return 0;
/*N*/ 
/*N*/ 	for ( USHORT nPos = 0; nPos < pBoundItems->Count(); ++nPos )
/*N*/ 		if ( pBoundItems->GetObject(nPos)->GetId() == nId )
/*N*/ 			return pBoundItems->GetObject(nPos);
/*N*/ 	return 0;
/*N*/ }



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



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



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


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

/*N*/ void SfxStatusBarManager::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
/*N*/ {
/*N*/ 	if ( rHint.IsA(TYPE(SfxSimpleHint)) )
/*N*/ 	{
/*N*/ 		switch( ( (SfxSimpleHint&) rHint ).GetId() )
/*N*/ 		{
/*N*/ 			case SFX_HINT_DYING:
/*?*/ 				if ( rBC.IsA(TYPE(SfxBindings)) )
/*?*/ 					{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 DestroyingBindings(PTR_CAST(SfxBindings,&rBC));
/*N*/ 				break;
/*N*/ 		}
/*N*/ 	}
/*N*/ }


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

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

/*N*/ BOOL SfxStatusBarManager::Import( SvStream& rInStream, SvStream& rOutStream )
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 
/*N*/ }

/*N*/ BOOL SfxStatusBarManager::Export( SvStream& rInStream, SvStream& rOutStream )
/*N*/ {DBG_BF_ASSERT(0, "STRIP");return FALSE; //STRIP001 
/*N*/ }
}
