/**************************************************************
 *
 * 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"

#ifndef _TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif
#ifndef _RCID_H
#include <tools/rcid.h>
#endif
#include <unotools/viewoptions.hxx>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <cppuhelper/implbase1.hxx>

#ifndef GCC
#endif

#include <sfx2/childwin.hxx>
#include <sfx2/app.hxx>
#include "arrdecl.hxx"
#include <sfx2/bindings.hxx>
#include <sfx2/module.hxx>
#include <sfx2/dockwin.hxx>
#include <sfx2/dispatch.hxx>
#include "workwin.hxx"

static const sal_uInt16 nVersion = 2;

DBG_NAME(SfxChildWindow)

SV_IMPL_PTRARR( SfxChildWinContextArr_Impl, SfxChildWinContextFactory* );

struct SfxChildWindow_Impl
{
	::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > 			xFrame;
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >      xListener;
	SfxChildWinFactory* pFact;
	sal_Bool				bHideNotDelete;
	sal_Bool				bVisible;
	sal_Bool				bHideAtToggle;
	sal_Bool				bWantsFocus;
	SfxModule*			pContextModule;
	SfxWorkWindow*		pWorkWin;
};

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

class DisposeListener : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener >
{
    public:
        DisposeListener( SfxChildWindow*      pOwner ,
                         SfxChildWindow_Impl* pData  )
            :   m_pOwner( pOwner )
            ,   m_pData ( pData  )
        {}

        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aSource ) throw (::com::sun::star::uno::RuntimeException)
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > xSelfHold( this );

            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( aSource.Source, ::com::sun::star::uno::UNO_QUERY );
            if( xComp.is() )
                xComp->removeEventListener( this );

            if( m_pOwner && m_pData )
            {
	            m_pData->xListener = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >();

				if ( m_pData->pWorkWin )
				{
					// m_pOwner and m_pData will be killed
		            m_pData->xFrame    = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >();
	                m_pData->pWorkWin->GetBindings().Execute( m_pOwner->GetType() );
				}
				else
				{
					delete m_pOwner;
				}

                m_pOwner = NULL;
                m_pData  = NULL;
            }
        }

    private:
        SfxChildWindow*      m_pOwner;
        SfxChildWindow_Impl* m_pData ;
};

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

sal_Bool GetPosSizeFromString( const String& rStr, Point& rPos, Size& rSize )
{
	if ( rStr.GetTokenCount('/') != 4 )
		return sal_False;

	xub_StrLen nIdx = 0;
	rPos.X() = rStr.GetToken(0, '/', nIdx).ToInt32();
	rPos.Y() = rStr.GetToken(0, '/', nIdx).ToInt32();
	rSize.Width() = rStr.GetToken(0, '/', nIdx).ToInt32();
	rSize.Height() = rStr.GetToken(0, '/', nIdx).ToInt32();

	// negative sizes are invalid
	if ( rSize.Width() < 0 || rSize.Height() < 0 )
		return sal_False;

	return sal_True;
}

sal_Bool GetSplitSizeFromString( const String& rStr, Size& rSize )
{
    xub_StrLen nIndex = rStr.Search( ',' );
    if ( nIndex != STRING_NOTFOUND )
    {
        String aStr = rStr.Copy( nIndex+1 );

        sal_Int32 nCount = aStr.GetTokenCount(';');
        if ( nCount != 2 )
            return sal_False;

	    rSize.Width() = aStr.GetToken(0, ';' ).ToInt32();
	    rSize.Height() = aStr.GetToken(1, ';' ).ToInt32();

	    // negative sizes are invalid
	    if ( rSize.Width() < 0 || rSize.Height() < 0 )
		    return sal_False;

	    return sal_True;
    }

    return sal_False;
}

//=========================================================================
SfxChildWindow::SfxChildWindow(Window *pParentWindow, sal_uInt16 nId)
	: pParent(pParentWindow)
	, nType(nId)
	, eChildAlignment(SFX_ALIGN_NOALIGNMENT)
	, pWindow(0L)
{
	pImp = new SfxChildWindow_Impl;
	pImp->pFact = 0L;
	pImp->bHideNotDelete = sal_False;
	pImp->bHideAtToggle = sal_False;
	pImp->bWantsFocus = sal_True;
	pImp->bVisible = sal_True;
	pImp->pContextModule = NULL;
	pImp->pWorkWin = NULL;

	pContext = 0L;
	DBG_CTOR(SfxChildWindow,0);
}

void SfxChildWindow::Destroy()
{
	if ( GetFrame().is() )
	{
		pImp->pWorkWin = NULL;
		try
		{
			::com::sun::star::uno::Reference < ::com::sun::star::util::XCloseable > xClose( GetFrame(), ::com::sun::star::uno::UNO_QUERY );
			if ( xClose.is() )
				xClose->close( sal_True );
			else
				GetFrame()->dispose();
		}
		catch ( com::sun::star::uno::Exception& )
		{
		}
	}
	else
		delete this;
}

//-------------------------------------------------------------------------
SfxChildWindow::~SfxChildWindow()
{
	DBG_DTOR(SfxChildWindow,0);
	if ( pContext )
		delete pContext;
	if ( pWindow )
	    delete pWindow;
	delete pImp;
}

//-------------------------------------------------------------------------
SfxChildWindow* SfxChildWindow::CreateChildWindow( sal_uInt16 nId,
		Window *pParent, SfxBindings* pBindings, SfxChildWinInfo& rInfo)
{
	SfxChildWindow *pChild=0;
	SfxChildWinFactory* pFact=0;
    sal_uInt16 nOldMode = Application::GetSystemWindowMode();

	// Zuerst ChildWindow im SDT suchen; "Uberlagerungen m"ussen mit einem
	// ChildWindowContext realisiert werden
	SfxApplication *pApp = SFX_APP();
    {
	    SfxChildWinFactArr_Impl &rFactories = pApp->GetChildWinFactories_Impl();
	    for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory )
	    {
		    pFact = rFactories[nFactory];
		    if ( pFact->nId == nId )
		    {
			    SfxChildWinInfo& rFactInfo = pFact->aInfo;
			    if ( rInfo.bVisible )
			    {
				    if ( pBindings )
					    pBindings->ENTERREGISTRATIONS();
				    SfxChildWinInfo aInfo = rFactInfo;
                    Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_NOAUTOMODE );
				    pChild = pFact->pCtor( pParent, nId, pBindings, &aInfo );
                    Application::SetSystemWindowMode( nOldMode );
				    if ( pBindings )
					    pBindings->LEAVEREGISTRATIONS();
			    }

			    break;
		    }
	    }
    }

	SfxDispatcher *pDisp = pBindings->GetDispatcher_Impl();
    SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0;
	if ( !pChild &&  pMod )
	{
		SfxChildWinFactArr_Impl *pFactories = pMod->GetChildWinFactories_Impl();
		if ( pFactories )
		{
			SfxChildWinFactArr_Impl &rFactories = *pFactories;
			for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory )
			{
				pFact = rFactories[nFactory];
				if ( pFact->nId == nId )
				{
					SfxChildWinInfo& rFactInfo = pFact->aInfo;
					if ( rInfo.bVisible )
					{
						if ( pBindings )
							pBindings->ENTERREGISTRATIONS();
						SfxChildWinInfo aInfo = rFactInfo;
                        Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_NOAUTOMODE );
						pChild = pFact->pCtor( pParent, nId, pBindings, &aInfo );
                        Application::SetSystemWindowMode( nOldMode );
						if ( pBindings )
							pBindings->LEAVEREGISTRATIONS();
					}

					break;
				}
			}
		}
	}

	if ( pChild )
		pChild->SetFactory_Impl( pFact );

	DBG_ASSERT(pFact && (pChild || !rInfo.bVisible), "ChildWindow-Typ nicht registriert!");

	if ( pChild && !pChild->pWindow )
	{
		DELETEZ(pChild);
		DBG_WARNING("ChildWindow hat kein Fenster!");
	}

	return pChild;
}

//-------------------------------------------------------------------------
void SfxChildWindow::SaveStatus(const SfxChildWinInfo& rInfo)
{
    sal_uInt16 nID = GetType();

    String aWinData( 'V' );
    aWinData += String::CreateFromInt32( nVersion );
    aWinData += ',';
    aWinData += rInfo.bVisible ? 'V' : 'H';
    aWinData += ',';
    aWinData += String::CreateFromInt32( rInfo.nFlags );
    if ( rInfo.aExtraString.Len() )
    {
        aWinData += ',';
        aWinData += rInfo.aExtraString;
    }

    SvtViewOptions aWinOpt( E_WINDOW, String::CreateFromInt32( nID ) );
    // aWinOpt.SetPosition( rInfo.aPos.X(), rInfo.aPos.Y() );
    // aWinOpt.SetSize( rInfo.aSize.Width(), rInfo.aSize.Height() );
    aWinOpt.SetWindowState( String( rInfo.aWinState, RTL_TEXTENCODING_UTF8 ) );

    ::com::sun::star::uno::Sequence < ::com::sun::star::beans::NamedValue > aSeq(1);
    aSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Data") );
    aSeq[0].Value <<= ::rtl::OUString( aWinData );
    aWinOpt.SetUserData( aSeq );

    // ... but save status at runtime!
    pImp->pFact->aInfo = rInfo;
}

//-------------------------------------------------------------------------
void SfxChildWindow::SetAlignment(SfxChildAlignment eAlign)
{
	DBG_CHKTHIS(SfxChildWindow,0);

	eChildAlignment = eAlign;
}

//-------------------------------------------------------------------------
void SfxChildWindow::SetPosSizePixel(const Point& rPoint, Size& rSize)
{
	DBG_CHKTHIS(SfxChildWindow,0);

	pWindow->SetPosSizePixel(rPoint, rSize);
}

//-------------------------------------------------------------------------
SfxChildWinInfo SfxChildWindow::GetInfo() const
{
	DBG_CHKTHIS(SfxChildWindow,0);

	SfxChildWinInfo aInfo;
	aInfo.aPos	= pWindow->GetPosPixel();
	aInfo.aSize = pWindow->GetSizePixel();
    if ( pWindow->IsSystemWindow() )
    {
        sal_uIntPtr nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE;
        if ( pWindow->GetStyle() & WB_SIZEABLE )
            nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT );
        aInfo.aWinState = ((SystemWindow*)pWindow)->GetWindowState( nMask );
    }
    else if ( pWindow->GetType() == RSC_DOCKINGWINDOW )
    {
        if (((DockingWindow*)pWindow)->GetFloatingWindow() )
            aInfo.aWinState = ((DockingWindow*)pWindow)->GetFloatingWindow()->GetWindowState();
        else
        {
            SfxChildWinInfo aTmpInfo;
            ((SfxDockingWindow*)pWindow)->FillInfo( aTmpInfo );
            aInfo.aExtraString = aTmpInfo.aExtraString;
        }
    }

	aInfo.bVisible = pImp->bVisible;
	aInfo.nFlags = 0;
	return aInfo;
}

//-------------------------------------------------------------------------
sal_uInt16 SfxChildWindow::GetPosition()
{
	return pImp->pFact->nPos;
}

#if 0
static void ImplWindowStateFromStr( Point rPos, Size rSize, const ByteString& rStr )
{
    sal_uIntPtr       nValidMask  = 0;
    xub_StrLen  nIndex      = 0;
    ByteString  aTokenStr;

    aTokenStr = rStr.GetToken( 0, ',', nIndex );
    if ( aTokenStr.Len() )
    {
        rPos.X() = aTokenStr.ToInt32();
        nValidMask |= WINDOWSTATE_MASK_X;
    }

    aTokenStr = rStr.GetToken( 0, ',', nIndex );
    if ( aTokenStr.Len() )
    {
        rPos.Y() = aTokenStr.ToInt32();
        nValidMask |= WINDOWSTATE_MASK_Y;
    }

    aTokenStr = rStr.GetToken( 0, ',', nIndex );
    if ( aTokenStr.Len() )
    {
        rSize.Width() = aTokenStr.ToInt32();
        nValidMask |= WINDOWSTATE_MASK_WIDTH;
    }

    aTokenStr = rStr.GetToken( 0, ';', nIndex );
    if ( aTokenStr.Len() )
    {
        rSize.Height() = aTokenStr.ToInt32();
        nValidMask |= WINDOWSTATE_MASK_HEIGHT;
    }
}
#endif

//-------------------------------------------------------------------------
void SfxChildWindow::InitializeChildWinFactory_Impl( sal_uInt16 nId, SfxChildWinInfo& rInfo )
{
	// load configuration
	SvtViewOptions aWinOpt( E_WINDOW, String::CreateFromInt32( nId ) );

    if ( aWinOpt.Exists() )
        rInfo.bVisible  = aWinOpt.IsVisible(); // set state from configuration. Can be overwritten by UserData, see below

    ::com::sun::star::uno::Sequence < ::com::sun::star::beans::NamedValue > aSeq = aWinOpt.GetUserData();

    ::rtl::OUString aTmp;
    if ( aSeq.getLength() )
        aSeq[0].Value >>= aTmp;

    String aWinData( aTmp );
    rInfo.aWinState = ByteString( String(aWinOpt.GetWindowState()), RTL_TEXTENCODING_UTF8 );

    //ImplWindowStateFromStr( rInfo.aPos, rInfo.aSize, ByteString( aWinState, RTL_TEXTENCODING_UTF8 ) );

    if ( aWinData.Len() )
	{
		// Nach Versionskennung suchen
		if ( aWinData.GetChar((sal_uInt16)0) != 0x0056 ) // 'V' = 56h
			// Keine Versionskennung, daher nicht verwenden
			return;

		// 'V' l"oschen
		aWinData.Erase(0,1);

		// Version lesen
		char cToken = ',';
		sal_uInt16 nPos = aWinData.Search( cToken );
        sal_uInt16 nActVersion = (sal_uInt16)aWinData.Copy( 0, nPos + 1 ).ToInt32();
        if ( nActVersion != nVersion )
            return;

		aWinData.Erase(0,nPos+1);

        //aWinOpt.GetPosition( rInfo.aPos.X(), rInfo.aPos.Y() );
        //aWinOpt.GetSize( rInfo.aSize.Width(), rInfo.aSize.Height() );

		// Sichtbarkeit laden: ist als ein char codiert
        rInfo.bVisible = (aWinData.GetChar(0) == 0x0056); // 'V' = 56h
        aWinData.Erase(0,1);
        nPos = aWinData.Search( cToken );
		if (nPos != STRING_NOTFOUND)
		{
            sal_uInt16 nNextPos = aWinData.Search( cToken, 2 );
            if ( nNextPos != STRING_NOTFOUND )
            {
                // es gibt noch Extra-Information
                rInfo.nFlags = (sal_uInt16)aWinData.Copy( nPos+1, nNextPos - nPos - 1 ).ToInt32();
                aWinData.Erase( nPos, nNextPos-nPos+1 );
                rInfo.aExtraString = aWinData;
            }
            else
                rInfo.nFlags = (sal_uInt16)aWinData.Copy( nPos+1 ).ToInt32();
		}
	}
}

void SfxChildWindow::CreateContext( sal_uInt16 nContextId, SfxBindings& rBindings )
{
	SfxChildWindowContext *pCon = NULL;
	SfxChildWinFactory* pFact=0;
	SfxApplication *pApp = SFX_APP();
	SfxDispatcher *pDisp = rBindings.GetDispatcher_Impl();
    SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0;
	if ( pMod )
	{
		SfxChildWinFactArr_Impl *pFactories = pMod->GetChildWinFactories_Impl();
		if ( pFactories )
		{
			SfxChildWinFactArr_Impl &rFactories = *pFactories;
			for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory )
			{
				pFact = rFactories[nFactory];
				if ( pFact->nId == GetType() )
				{
					DBG_ASSERT( pFact->pArr, "Kein Kontext angemeldet!" );
					if ( !pFact->pArr )
						break;

					SfxChildWinContextFactory *pConFact=0;
					for ( sal_uInt16 n=0; n<pFact->pArr->Count(); ++n )
					{
						pConFact = (*pFact->pArr)[n];
						rBindings.ENTERREGISTRATIONS();
						if ( pConFact->nContextId == nContextId )
						{
							SfxChildWinInfo aInfo = pFact->aInfo;
							pCon = pConFact->pCtor( GetWindow(), &rBindings, &aInfo );
							pCon->nContextId = pConFact->nContextId;
							pImp->pContextModule = pMod;
						}
						rBindings.LEAVEREGISTRATIONS();
					}
					break;
				}
			}
		}
	}

	if ( !pCon )
	{
		SfxChildWinFactArr_Impl &rFactories = pApp->GetChildWinFactories_Impl();
		for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory )
		{
			pFact = rFactories[nFactory];
			if ( pFact->nId == GetType() )
			{
				DBG_ASSERT( pFact->pArr, "Kein Kontext angemeldet!" );
				if ( !pFact->pArr )
					break;

				SfxChildWinContextFactory *pConFact=0;
				for ( sal_uInt16 n=0; n<pFact->pArr->Count(); ++n )
				{
					pConFact = (*pFact->pArr)[n];
					rBindings.ENTERREGISTRATIONS();
					if ( pConFact->nContextId == nContextId )
					{
						SfxChildWinInfo aInfo = pFact->aInfo;
						pCon = pConFact->pCtor( GetWindow(), &rBindings, &aInfo );
						pCon->nContextId = pConFact->nContextId;
						pImp->pContextModule = NULL;
					}
					rBindings.LEAVEREGISTRATIONS();
				}
				break;
			}
		}
	}

	if ( !pCon )
	{
		DBG_ERROR( "Kein geeigneter Context gefunden!" );
		return;
	}

	if ( pContext )
		delete( pContext );
	pContext = pCon;
	pContext->GetWindow()->SetSizePixel( pWindow->GetOutputSizePixel() );
	pContext->GetWindow()->Show();
}

SfxChildWindowContext::SfxChildWindowContext( sal_uInt16 nId )
	: pWindow( NULL )
	, nContextId( nId )
{
}

SfxChildWindowContext::~SfxChildWindowContext()
{
	delete pWindow;
}

FloatingWindow*	SfxChildWindowContext::GetFloatingWindow() const
{
	Window *pParent = pWindow->GetParent();
	if ( pParent->GetType() == RSC_DOCKINGWINDOW || pParent->GetType() == RSC_TOOLBOX )
	{
		return ((DockingWindow*)pParent)->GetFloatingWindow();
	}
	else if ( pParent->GetType() == RSC_FLOATINGWINDOW )
	{
		return (FloatingWindow*) pParent;
	}
	else
	{
		DBG_ERROR("Kein FloatingWindow-Context!");
		return NULL;
	}
}

SfxChildAlignment SfxChildWindowContext::GetAlignment() const
{
	Window *pParent = pWindow->GetParent();
	if ( pParent->GetType() == RSC_DOCKINGWINDOW )
	{
		return ((SfxDockingWindow*)pParent)->GetAlignment();
	}
	else if ( pParent->GetType() == RSC_TOOLBOX )
	{
		HACK(noch nicht verwendet und noch nicht implementiert);
		return SFX_ALIGN_NOALIGNMENT;
	}
	else
		return SFX_ALIGN_NOALIGNMENT;
}

void SfxChildWindowContext::Resizing( Size& )
{
}

sal_Bool SfxChildWindowContext::Close()
{
	return sal_True;
}

void SfxChildWindow::SetFactory_Impl( SfxChildWinFactory *pF )
{
	pImp->pFact = pF;
}

void SfxChildWindow::SetHideNotDelete( sal_Bool bOn )
{
	pImp->bHideNotDelete = bOn;
}

sal_Bool SfxChildWindow::IsHideNotDelete() const
{
	return pImp->bHideNotDelete;
}

void SfxChildWindow::SetHideAtToggle( sal_Bool bOn )
{
	pImp->bHideAtToggle = bOn;
}

sal_Bool SfxChildWindow::IsHideAtToggle() const
{
	return pImp->bHideAtToggle;
}

void SfxChildWindow::SetWantsFocus( sal_Bool bSet )
{
	pImp->bWantsFocus = bSet;
}

sal_Bool SfxChildWindow::WantsFocus() const
{
	return pImp->bWantsFocus;
}

sal_Bool SfxChildWinInfo::GetExtraData_Impl
(
	SfxChildAlignment	*pAlign,
	SfxChildAlignment	*pLastAlign,
	Size				*pSize,
	sal_uInt16			*pLine,
	sal_uInt16			*pPos
)   const
{
	// ung"ultig?
	if ( !aExtraString.Len() )
		return sal_False;
	String aStr;
	sal_uInt16 nPos = aExtraString.SearchAscii("AL:");
	if ( nPos == STRING_NOTFOUND )
		return sal_False;

	// Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn
	// er nicht vorhanden ist, liegt eine "altere Version vor
	if ( nPos != STRING_NOTFOUND )
	{
		sal_uInt16 n1 = aExtraString.Search('(', nPos);
		if ( n1 != STRING_NOTFOUND )
		{
			sal_uInt16 n2 = aExtraString.Search(')', n1);
			if ( n2 != STRING_NOTFOUND )
			{
				// Alignment-String herausschneiden
				aStr = aExtraString.Copy(nPos, n2 - nPos + 1);
				aStr.Erase(nPos, n1-nPos+1);
			}
		}
	}

	// Zuerst das Alignment extrahieren
	if ( !aStr.Len() )
		return sal_False;
	if ( pAlign )
		*pAlign = (SfxChildAlignment) (sal_uInt16) aStr.ToInt32();

	// Dann das LastAlignment
	nPos = aStr.Search(',');
	if ( nPos == STRING_NOTFOUND )
		return sal_False;
	aStr.Erase(0, nPos+1);
	if ( pLastAlign )
		*pLastAlign = (SfxChildAlignment) (sal_uInt16) aStr.ToInt32();

	// Dann die Splitting-Informationen
	nPos = aStr.Search(',');
	if ( nPos == STRING_NOTFOUND )
		// Dockt nicht in einem Splitwindow
		return sal_True;
	aStr.Erase(0, nPos+1);
	Point aChildPos;
	Size aChildSize;
	if ( GetPosSizeFromString( aStr, aChildPos, aChildSize ) )
	{
		if ( pSize )
			*pSize = aChildSize;
		if ( pLine )
			*pLine = (sal_uInt16) aChildPos.X();
		if ( pPos )
			*pPos = (sal_uInt16) aChildPos.Y();
		return sal_True;
	}
	return sal_False;
}

sal_Bool SfxChildWindow::IsVisible() const
{
	return pImp->bVisible;
}

void SfxChildWindow::SetVisible_Impl( sal_Bool bVis )
{
	pImp->bVisible = bVis;
}

void SfxChildWindow::Hide()
{
	switch ( pWindow->GetType() )
	{
		case RSC_DOCKINGWINDOW :
			((DockingWindow*)pWindow)->Hide();
			break;
		case RSC_TOOLBOX :
			((ToolBox*)pWindow)->Hide();
			break;
		default:
			pWindow->Hide();
			break;
	}
}



void SfxChildWindow::Show( sal_uInt16 nFlags )
{
	switch ( pWindow->GetType() )
	{
		case RSC_DOCKINGWINDOW :
            ((DockingWindow*)pWindow)->Show( sal_True, nFlags );
			break;
		case RSC_TOOLBOX :
            ((ToolBox*)pWindow)->Show( sal_True, nFlags );
			break;
		default:
            pWindow->Show( sal_True, nFlags );
			break;
	}
}

Window*	SfxChildWindow::GetContextWindow( SfxModule *pModule ) const
{
	return pModule == pImp->pContextModule && pContext ? pContext->GetWindow(): 0;
}

void SfxChildWindow::SetWorkWindow_Impl( SfxWorkWindow* pWin )
{
	pImp->pWorkWin = pWin;
	if ( pWin && pWindow->HasChildPathFocus() )
		pImp->pWorkWin->SetActiveChild_Impl( pWindow );
}

//SfxWorkWindow* SfxChildWindow::GetWorkWindow_Impl() const
//{
//	return pImp->pWorkWin;
//}

void SfxChildWindow::Activate_Impl()
{
	if(pImp->pWorkWin!=NULL) //@#60568#
		pImp->pWorkWin->SetActiveChild_Impl( pWindow );
}

void SfxChildWindow::Deactivate_Impl()
{
//	pImp->pWorkWin->SetActiveChild_Impl( NULL );
}

sal_Bool SfxChildWindow::QueryClose()
{
    sal_Bool bAllow = sal_True;

	if ( pImp->xFrame.is() )
	{
		::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >  xCtrl = pImp->xFrame->getController();
		if ( xCtrl.is() )
			bAllow = xCtrl->suspend( sal_True );
	}

	if ( bAllow )
		bAllow = !GetWindow()->IsInModalMode();

	return bAllow;
}

::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >  SfxChildWindow::GetFrame()
{
	return pImp->xFrame;
}

void SfxChildWindow::SetFrame( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > & rFrame )
{
    // Do nothing if nothing will be changed ...
    if( pImp->xFrame != rFrame )
    {
        // ... but stop listening on old frame, if connection exist!
        if( pImp->xFrame.is() )
            pImp->xFrame->removeEventListener( pImp->xListener );

        // If new frame isnt NULL -> we must guarantee valid listener for disposing events.
        // Use already existing or create new one.
        if( rFrame.is() )
            if( !pImp->xListener.is() )
                pImp->xListener = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >( new DisposeListener( this, pImp ) );

        // Set new frame in data container
        // and build new listener connection, if necessary.
        pImp->xFrame = rFrame;
        if( pImp->xFrame.is() )
            pImp->xFrame->addEventListener( pImp->xListener );
    }
}

sal_Bool SfxChildWindow::CanGetFocus() const
{
	return !(pImp->pFact->aInfo.nFlags & SFX_CHILDWIN_CANTGETFOCUS);
}

void SfxChildWindowContext::RegisterChildWindowContext(SfxModule* pMod, sal_uInt16 nId, SfxChildWinContextFactory* pFact)
{
    SFX_APP()->RegisterChildWindowContext_Impl( pMod, nId, pFact );
}

void SfxChildWindow::RegisterChildWindow(SfxModule* pMod, SfxChildWinFactory* pFact)
{
    SFX_APP()->RegisterChildWindow_Impl( pMod, pFact );
}
