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

#ifndef _SV_DECOVIEW_HXX
#include <vcl/decoview.hxx>
#endif
#pragma hdrstop

#include "dockwin.hxx"
#include "viewfrm.hxx"
#include "dispatch.hxx"
#include "workwin.hxx"
#include "splitwin.hxx"
#include "viewsh.hxx"
#include "sfxhelp.hxx"

#ifndef _SFX_SFXUNO_HXX
#include "sfxuno.hxx"
#endif

namespace binfilter {

#define MAX_TOGGLEAREA_WIDTH 		20
#define MAX_TOGGLEAREA_HEIGHT		20

// implemented in 'bf_sfx2/source/appl/childwin.cxx'
extern sal_Bool GetPosSizeFromString( const String& rStr, Point& rPos, Size& rSize );

class SfxDockingWindow_Impl
{
friend class SfxDockingWindow;

	SfxChildAlignment	eLastAlignment;
	SfxChildAlignment	eDockAlignment;
	BOOL				bConstructed;
	Size				aMinSize;
	SfxSplitWindow*		pSplitWin;
	BOOL				bSplitable;
//	BOOL				bAutoHide;

	// Folgende members sind nur in der Zeit von StartDocking bis EndDocking
	// g"ultig:
	BOOL				bEndDocked;
	Size				aSplitSize;
    long                nHorizontalSize;
    long                nVerticalSize;
	USHORT				nLine;
	USHORT 				nPos;
	USHORT 				nDockLine;
	USHORT				nDockPos;
	BOOL				bNewLine;
	BOOL 				bDockingPrevented;
    ByteString          aWinState;

	SfxChildAlignment	GetLastAlignment() const
						{ return eLastAlignment; }
	void				SetLastAlignment(SfxChildAlignment eAlign)
						{ eLastAlignment = eAlign; }
	SfxChildAlignment	GetDockAlignment() const
						{ return eDockAlignment; }
	void				SetDockAlignment(SfxChildAlignment eAlign)
						{ eDockAlignment = eAlign; }
};

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

/*N*/ void SfxDockingWindow::Resize()

/*  [Beschreibung]

	Diese virtuelle Methode der Klasse DockingWindow merkt sich ggf. eine
	ver"anderte FloatingSize.
	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
	auch SfxDockingWindow::Resize() gerufen werden.
*/
/*N*/ {
/*N*/ 	DockingWindow::Resize();
/*N*/     Invalidate();
/*N*/     if ( pImp->bConstructed && pMgr )
/*N*/     {
/*?*/         if ( IsFloatingMode() )
/*?*/         {
/*?*/             if( !GetFloatingWindow()->IsRollUp() )
/*?*/                 SetFloatingSize( GetOutputSizePixel() );
/*?*/             pImp->aWinState = GetFloatingWindow()->GetWindowState();
/*?*/             SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
/*?*/             SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
/*?*/             if ( pImp->bSplitable )
/*?*/                 eIdent = SFX_CHILDWIN_SPLITWINDOW;
/*?*/             pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() );
/*?*/         }
/*?*/ 		else
/*?*/ 		{
/*?*/             Size aSize( GetSizePixel() );
/*?*/             switch ( pImp->GetDockAlignment() )
/*?*/             {
/*?*/                 case SFX_ALIGN_LEFT:
/*?*/                 case SFX_ALIGN_FIRSTLEFT:
/*?*/                 case SFX_ALIGN_LASTLEFT:
/*?*/                 case SFX_ALIGN_RIGHT:
/*?*/                 case SFX_ALIGN_FIRSTRIGHT:
/*?*/                 case SFX_ALIGN_LASTRIGHT:
/*?*/                     pImp->nHorizontalSize = aSize.Width();
/*?*/                     break;
/*?*/                 case SFX_ALIGN_TOP:
/*?*/                 case SFX_ALIGN_LOWESTTOP:
/*?*/                 case SFX_ALIGN_HIGHESTTOP:
/*?*/                 case SFX_ALIGN_BOTTOM:
/*?*/                 case SFX_ALIGN_HIGHESTBOTTOM:
/*?*/                 case SFX_ALIGN_LOWESTBOTTOM:
/*?*/                     pImp->nVerticalSize = aSize.Height();
/*N*/                     break;
/*N*/             }
/*N*/ 		}
/*N*/     }
/*N*/ }

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

/*N*/ BOOL SfxDockingWindow::PrepareToggleFloatingMode()

/*  [Beschreibung]

	Diese virtuelle Methode der Klasse DockingWindow erm"oglicht ein Eingreifen
	in das Umschalten des floating mode.
	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
	danach SfxDockingWindow::PrepareToggleFloatingMode() gerufen werden,
	wenn nicht FALSE zur"uckgegeben wird.
*/

/*N*/ {
/*N*/ 	if (!pImp->bConstructed)
/*N*/ 		return TRUE;
/*N*/ 
/*?*/ 	if ( Application::IsInModalMode() && IsFloatingMode() || !pMgr )
/*?*/ 		return FALSE;
/*?*/ 
/*?*/     if ( pImp->bDockingPrevented )
/*?*/ 		return FALSE;
/*?*/ 
/*?*/ 	if (!IsFloatingMode())
/*?*/ 	{
/*?*/ 		// Testen, ob FloatingMode erlaubt ist
/*?*/         if ( CheckAlignment(GetAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT )
/*?*/ 			return FALSE;
/*?*/ 
/*?*/ 		if ( pImp->pSplitWin )
/*?*/ 		{
/*?*/ 			// Das DockingWindow sitzt in einem SplitWindow und wird abgerissen
/*?*/ 			pImp->pSplitWin->RemoveWindow(this/*, FALSE*/);
/*?*/ 			pImp->pSplitWin = 0;
/*?*/ 		}
/*?*/ 	}
/*?*/ 	else if ( pMgr )
/*?*/ 	{
/*?*/ 		pImp->aWinState = GetFloatingWindow()->GetWindowState();
/*?*/ 
/*?*/ 		// Testen, ob es erlaubt ist, anzudocken
/*?*/         if (CheckAlignment(GetAlignment(),pImp->GetLastAlignment()) == SFX_ALIGN_NOALIGNMENT)
/*?*/ 			return FALSE;
/*?*/ 
/*?*/ 		// Testen, ob das Workwindow gerade ein Andocken erlaubt
/*?*/ 		SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
/*?*/ 		if ( !pWorkWin->IsDockingAllowed() )
/*?*/ 			return FALSE;
/*?*/ 	}
/*?*/ 
/*?*/ 	return TRUE;
/*N*/ }

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

/*N*/ void SfxDockingWindow::ToggleFloatingMode()

/*  [Beschreibung]

	Diese virtuelle Methode der Klasse DockingWindow setzt die internen
	Daten des SfxDockingWindow und sorgt f"ur korrektes Alignment am
	parent window.
	Durch PrepareToggleFloatMode und Initialize ist sichergestellt, da\s
	pImp->GetLastAlignment() immer eine erlaubtes Alignment liefert.
	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
	zuerst SfxDockingWindow::ToggleFloatingMode() gerufen werden.
*/
/*N*/ {
/*N*/ 	if ( !pImp->bConstructed || !pMgr )
/*N*/ 		return;					// Kein Handler-Aufruf
/*N*/ 
/*N*/ 	// Altes Alignment merken und dann umschalten.
/*N*/ 	// Sv hat jetzt schon umgeschaltet, aber Alignment am SfxDockingWindow
/*N*/ 	// ist noch das alte!
/*N*/ 	// Was war ich bisher ?
/*?*/ 	SfxChildAlignment eLastAlign = GetAlignment();
/*?*/ 
/*?*/ 	SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
/*?*/ 	SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
/*?*/ 	if ( pImp->bSplitable )
/*?*/ 		eIdent = SFX_CHILDWIN_SPLITWINDOW;
/*?*/ 
/*?*/ 	if (IsFloatingMode())
/*?*/ 	{
/*?*/ 		SetAlignment(SFX_ALIGN_NOALIGNMENT);
/*?*/         if ( pImp->aWinState.Len() )
/*?*/             GetFloatingWindow()->SetWindowState( pImp->aWinState );
/*?*/         else
/*?*/             GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() );
/*
		if ( pImp->bSplitable && !pImp->bEndDocked )
			// Wenn das Fenster vorher in einem SplitWindow lag, kommt von
			// Sv kein Show
			Show();
*/
/*?*/ 	}
/*?*/ 	else
/*?*/ 	{
/*?*/ 		if (pImp->GetDockAlignment() == eLastAlign)
/*?*/ 		{
/*?*/ 			// Wenn ToggleFloatingMode aufgerufen wurde, das DockAlignment
/*?*/ 			// aber noch unver"andert ist, mu\s das ein Toggeln durch DClick
/*?*/ 			// gewesen sein, also LastAlignment verwenden
/*?*/ 			SetAlignment (pImp->GetLastAlignment());
/*?*/             if ( !pImp->bSplitable )
/*?*/ 				SetSizePixel( CalcDockingSize(GetAlignment()) );
/*?*/ 		}
/*?*/ 		else
/*?*/ 		{
/*?*/ 			// Toggeln wurde durch Draggen ausgel"ost
/*?*/ 			pImp->nLine = pImp->nDockLine;
/*?*/ 			pImp->nPos = pImp->nDockPos;
/*?*/ 			SetAlignment (pImp->GetDockAlignment());
/*?*/ 		}
/*?*/ 
/*?*/ 		if ( pImp->bSplitable )
/*?*/ 		{
/*?*/ 			// Das DockingWindow kommt jetzt in ein SplitWindow
/*?*/ 			pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment());
/*?*/ 
/*?*/ 			// Das LastAlignment ist jetzt immer noch das zuletzt angedockte
/*?*/             SfxSplitWindow *pSplit = pWorkWin->GetSplitWindow_Impl(pImp->GetLastAlignment());
/*?*/ 
/*?*/             DBG_ASSERT( pSplit, "LastAlignment kann nicht stimmen!" );
/*?*/ 			if ( pSplit && pSplit != pImp->pSplitWin )
/*?*/ 				{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pSplit->ReleaseWindow_Impl(this);
/*?*/ 			if ( pImp->GetDockAlignment() == eLastAlign )
/*?*/                 {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize );
/*?*/ 			else
/*?*/                 {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nLine, pImp->nPos, pImp->bNewLine );
/*?*/ 			if ( !pImp->pSplitWin->IsFadeIn() )
/*?*/ 				pImp->pSplitWin->FadeIn();
/*?*/ 		}
/*?*/ 	}
/*?*/ 
/*?*/ 	// altes Alignment festhalten f"ur n"achstes Togglen; erst jetzt setzen
/*?*/ 	// wg. Abmelden beim SplitWindow!
/*?*/ 	pImp->SetLastAlignment(eLastAlign);
/*?*/ 
/*?*/ 	// DockAlignment zur"ucksetzen, falls noch EndDocking gerufen wird
/*?*/ 	pImp->SetDockAlignment(GetAlignment());
/*?*/ 
/*?*/ 	// SfxChildWindow korrekt andocken bzw. entdocken
/*?*/ 	if ( pMgr )
/*?*/ 		pWorkWin->ConfigChild_Impl( eIdent, SFX_TOGGLEFLOATMODE, pMgr->GetType() );
/*N*/ }

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

/*?*/ void SfxDockingWindow::StartDocking()

/*  [Beschreibung]

	Diese virtuelle Methode der Klasse DockingWindow holt vom parent window
	das innere und "au\sere docking rectangle.
	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
	am Ende SfxDockingWindow::StartDocking() gerufen werden.
*/
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

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

/*?*/ BOOL SfxDockingWindow::Docking( const Point& rPos, Rectangle& rRect )

/*  [Beschreibung]

	Diese virtuelle Methode der Klasse DockingWindow berechnet das aktuelle
	tracking rectangle. Dazu benutzt sie die Methode CalcAlignment(rPos,rRect),
	deren Verhalten von abgeleiteten Klassen beeinflu\st werden kann (s.u.).
	Diese Methode sollte nach M"oglichkeit nicht "uberschrieben werden.
*/
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 
/*?*/ }

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

/*?*/ void SfxDockingWindow::EndDocking( const Rectangle& rRect, BOOL bFloatMode )

/*  [Beschreibung]

	Diese virtuelle Methode der Klasse DockingWindow sorgt f"ur das korrekte
	Alignment am parent window.
	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
	zuerst SfxDockingWindow::EndDocking() gerufen werden.
*/
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

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

/*?*/ void SfxDockingWindow::Resizing( Size& rSize )

/*	[Beschreibung]

	Virtuelle Methode der Klasse DockingWindow.
	Hier kann das interaktive Umgr"o\sern im FloatingMode beeinflu\t werden,
	z.B. indem nur diskrete Werte f"ur Breite und/oder H"ohe zugelassen werden.
	Die Basisimplementation verhindert, da\s die OutputSize kleiner wird als
	eine mit SetMinOutputSizePixel() gesetzte Gr"o\se.
*/

/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ }

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


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

/*N*/ SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW,
/*N*/ 	Window* pParent, const ResId& rResId) :
/*N*/ 	pBindings(pBindinx),
/*N*/ 	pMgr(pCW),
/*N*/ 	DockingWindow(pParent, rResId)

/*  [Beschreibung]

	ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt,
	da das Andocken im Sfx "uber SfxChildWindows realisiert wird.
*/

/*N*/ {
/*N*/ 	ULONG nId = GetHelpId();
/*N*/ 	SetHelpId(0);
/*N*/ 	SetUniqueId( nId );
/*N*/ 
/*N*/ 	pImp = new SfxDockingWindow_Impl;
/*N*/ 	pImp->bConstructed = FALSE;
/*N*/ 	pImp->pSplitWin = 0;
/*N*/ 	pImp->bEndDocked = FALSE;
/*N*/ 	pImp->bDockingPrevented = FALSE;
/*N*/ 
/*N*/ 	pImp->bSplitable = TRUE;
/*N*/ //	pImp->bAutoHide = FALSE;
/*N*/ 
/*N*/ 	// Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt
/*N*/ 	pImp->nLine = pImp->nDockLine = 0;
/*N*/ 	pImp->nPos  = pImp->nDockPos = 0;
/*N*/ 	pImp->bNewLine = FALSE;
/*N*/ 	pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT);
/*N*/ 
/*N*/ //	DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!");
/*N*/ }

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

/*N*/ void SfxDockingWindow::Initialize(SfxChildWinInfo *pInfo)
/*  [Beschreibung]

	Initialisierung der Klasse SfxDockingWindow "uber ein SfxChildWinInfo.
	Die Initialisierung erfolgt erst in einem 2.Schritt nach dem ctor und sollte
	vom ctor der abgeleiteten Klasse oder vom ctor des SfxChildWindows
	aufgerufen werden.
*/
/*N*/ {
/*N*/ 	if ( !pMgr )
/*N*/ 	{
/*N*/ 		// Bugfix #39771
/*?*/ 		pImp->SetDockAlignment( SFX_ALIGN_NOALIGNMENT );
/*?*/ 		pImp->bConstructed = TRUE;
/*?*/ 		return;
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( pInfo->nFlags & SFX_CHILDWIN_FORCEDOCK )
/*N*/ 		pImp->bDockingPrevented = TRUE;
/*N*/ 
/*N*/     pImp->aSplitSize = GetOutputSizePixel();
/*N*/     if ( !GetFloatingSize().Width() )
/*N*/     {
/*N*/         Size aMinSize( GetMinOutputSizePixel() );
/*N*/         SetFloatingSize( pImp->aSplitSize );
/*N*/         if ( pImp->aSplitSize.Width() < aMinSize.Width() )
/*?*/             pImp->aSplitSize.Width() = aMinSize.Width();
/*N*/         if ( pImp->aSplitSize.Height() < aMinSize.Height() )
/*?*/             pImp->aSplitSize.Height() = aMinSize.Height();
/*N*/     }
/*N*/ 
/*N*/     if ( pInfo->aExtraString.Len() )
/*N*/     {
/*N*/         // get information about alignment, split size and position in SplitWindow
/*N*/         String aStr;
/*N*/         USHORT nPos = pInfo->aExtraString.SearchAscii("AL:");
/*N*/         if ( nPos != STRING_NOTFOUND )
/*N*/         {
/*N*/             // alignment information
/*N*/             USHORT n1 = pInfo->aExtraString.Search('(', nPos);
/*N*/             if ( n1 != STRING_NOTFOUND )
/*N*/             {
/*N*/                 USHORT n2 = pInfo->aExtraString.Search(')', n1);
/*N*/                 if ( n2 != STRING_NOTFOUND )
/*N*/                 {
/*N*/                     // extract alignment information from extrastring
/*N*/                     aStr = pInfo->aExtraString.Copy(nPos, n2 - nPos + 1);
/*N*/                     pInfo->aExtraString.Erase(nPos, n2 - nPos + 1);
/*N*/                     aStr.Erase(nPos, n1-nPos+1);
/*N*/                 }
/*N*/             }
/*N*/         }
/*N*/ 
/*N*/         if ( aStr.Len() )
/*N*/         {
/*N*/             // accept window state only if alignment is also set
/*N*/             pImp->aWinState = pInfo->aWinState;
/*N*/ 
/*N*/             // check for valid alignment
/*N*/ 			SfxChildAlignment eLocalAlignment = (SfxChildAlignment) (USHORT) aStr.ToInt32();
/*N*/ 			if ( pImp->bDockingPrevented )
/*N*/ 				// docking prevented, ignore old configuration and take alignment from default
/*N*/ 				aStr.Erase();
/*N*/ 			else
/*N*/             	SetAlignment( eLocalAlignment );
/*N*/ 
/*N*/             SfxChildAlignment eAlign = CheckAlignment(GetAlignment(),GetAlignment());
/*N*/             if ( eAlign != GetAlignment() )
/*N*/             {
/*?*/                 DBG_ERROR("Invalid Alignment!");
/*?*/                 SetAlignment( eAlign );
/*?*/                 aStr.Erase();
/*N*/             }
/*N*/ 
/*N*/             // get last alignment (for toggeling)
/*N*/             nPos = aStr.Search(',');
/*N*/             if ( nPos != STRING_NOTFOUND )
/*N*/             {
/*N*/                 aStr.Erase(0, nPos+1);
/*N*/                 pImp->SetLastAlignment( (SfxChildAlignment) (USHORT) aStr.ToInt32() );
/*N*/             }
/*N*/ 
/*N*/             nPos = aStr.Search(',');
/*N*/             if ( nPos != STRING_NOTFOUND )
/*N*/             {
/*N*/                 // get split size and position in SplitWindow
/*N*/                 Point aPos;
/*N*/                 aStr.Erase(0, nPos+1);
/*N*/                 if ( GetPosSizeFromString( aStr, aPos, pImp->aSplitSize ) )
/*N*/                 {
/*N*/                     pImp->nLine = pImp->nDockLine = (USHORT) aPos.X();
/*N*/                     pImp->nPos  = pImp->nDockPos  = (USHORT) aPos.Y();
/*N*/                 }
/*N*/             }
/*N*/         }
/*N*/         else
/*N*/             DBG_ERROR( "Information is missing!" );
/*N*/     }
/*N*/ 
/*N*/     pImp->nVerticalSize = pImp->aSplitSize.Height();
/*N*/     pImp->nHorizontalSize = pImp->aSplitSize.Width();
/*N*/ 
/*N*/ 	SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
/*N*/ 	if ( GetAlignment() != SFX_ALIGN_NOALIGNMENT )
/*N*/ 	{
/*N*/         // check if SfxWorkWindow is able to allow docking at its border
/*N*/ 		if ( !pWorkWin->IsDockingAllowed() || ( GetFloatStyle() & WB_STANDALONE )
/*N*/ 			&& Application::IsInModalMode() )
/*N*/ 			SetAlignment( SFX_ALIGN_NOALIGNMENT );
/*N*/ 	}
/*N*/ 
/*N*/     // detect floating mode
/*N*/     // toggeling mode will not execute code in handlers, because pImp->bConstructed is not set yet
/*N*/ 	BOOL bFloatMode = IsFloatingMode();
/*N*/     if ( bFloatMode != ((GetAlignment() == SFX_ALIGN_NOALIGNMENT)) )
/*N*/     {
/*N*/         bFloatMode = !bFloatMode;
/*N*/         SetFloatingMode( bFloatMode );
/*N*/         if ( bFloatMode )
/*N*/         {
/*N*/             if ( pImp->aWinState.Len() )
/*N*/                 GetFloatingWindow()->SetWindowState( pImp->aWinState );
/*N*/             else
/*N*/                 GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() );
/*N*/         }
/*N*/     }
/*N*/ 
/*N*/     if ( IsFloatingMode() )
/*N*/ 	{
/*N*/         // validate last alignment
/*N*/         SfxChildAlignment eLastAlign = pImp->GetLastAlignment();
/*N*/ 		if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
/*N*/ 			eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_LEFT);
/*N*/ 		if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
/*?*/ 			eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_RIGHT);
/*N*/ 		if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
/*?*/ 			eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_TOP);
/*N*/ 		if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
/*?*/ 			eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_BOTTOM);
/*N*/ 		pImp->SetLastAlignment(eLastAlign);
/*N*/ 	}
/*N*/ 	else
/*N*/ 	{
/*N*/         // docked window must have NOALIGNMENT as last alignment
/*N*/ 		pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT);
/*N*/ 
/*N*/         if ( pImp->bSplitable )
/*N*/ 		{
/*N*/ //			pImp->bAutoHide = ( pInfo->nFlags & SFX_CHILDWIN_AUTOHIDE) != 0;
/*N*/ 			pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment());
/*N*/ 			pImp->pSplitWin->InsertWindow(this, pImp->aSplitSize);
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/             //?????? Currently not supported
/*N*/ 			// Fenster ist individuell angedockt; Gr"o\se berechnen.
/*N*/ 			// Dazu mu\s sie mit der FloatingSize initialisiert werden, falls
/*N*/ 			// irgendwer sich darauf verl"a\st, da\s eine vern"unftige Gr"o\se
/*N*/             // gesetzt ist
/*?*/ 			SetSizePixel(GetFloatingSize());
/*?*/ 			SetSizePixel(CalcDockingSize(GetAlignment()));
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/     // save alignment
/*N*/     pImp->SetDockAlignment( GetAlignment() );
/*N*/ }

/*N*/ void SfxDockingWindow::Initialize_Impl()
/*N*/ {
/*N*/ 	if ( !pMgr )
/*N*/     {
/*N*/ 		// Bugfix #39771
/*?*/         pImp->bConstructed = TRUE;
/*?*/ 		return;
/*N*/     }
/*N*/ 
/*N*/     FloatingWindow* pFloatWin = GetFloatingWindow();
/*N*/     BOOL bSet = FALSE;
/*N*/     if ( pFloatWin )
/*N*/     {
/*N*/         bSet = !pFloatWin->IsDefaultPos();
/*N*/     }
/*N*/     else
/*N*/     {
/*?*/         Point aPos = GetFloatingPos();
/*?*/         if ( aPos != Point() )
/*?*/             bSet = TRUE;
/*N*/     }
/*N*/ 
/*N*/     if ( !bSet)
/*N*/ 	{
/*?*/ 		SfxViewFrame *pFrame = pBindings->GetDispatcher_Impl()->GetFrame();
/*?*/ 		Window* pEditWin = pFrame->GetViewShell()->GetWindow();
/*?*/         Point aPos = pEditWin->OutputToScreenPixel( pEditWin->GetPosPixel() );
/*?*/ 		aPos = GetParent()->ScreenToOutputPixel( aPos );
/*?*/ 		SetFloatingPos( aPos );
/*N*/ 	}
/*N*/ 
/*N*/     if ( pFloatWin )
/*N*/     {
/*N*/         // initialize floating window
/*N*/         if ( !pImp->aWinState.Len() )
/*N*/             // window state never set before, get if from defaults
/*N*/             pImp->aWinState = pFloatWin->GetWindowState();
/*N*/ 
/*N*/         // trick: use VCL method SetWindowState to adjust position and size
/*N*/         pFloatWin->SetWindowState( pImp->aWinState );
/*N*/ 
/*N*/         // remember floating size for calculating alignment and tracking rectangle
/*N*/         SetFloatingSize( pFloatWin->GetSizePixel() );
/*N*/ 
/*N*/         // some versions of VCL didn't call resize in the current situation
/*N*/ 		//Resize();
/*N*/     }
/*N*/ 
/*N*/     // allow calling of docking handlers
/*N*/ 	pImp->bConstructed = TRUE;
/*N*/ }

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

/*N*/ void SfxDockingWindow::FillInfo(SfxChildWinInfo& rInfo) const

/*  [Beschreibung]

	F"ullt ein SfxChildWinInfo mit f"ur SfxDockingWindow spezifischen Daten,
	damit sie in die INI-Datei geschrieben werden koennen.
	Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in
	der ChildWindow-Klasse erh"alt.
	Eingetragen werden hier gemerkten Gr"o\sen, das ZoomIn-Flag und die
	f"ur das Docking relevanten Informationen.
	Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung
	gerufen werden.
*/

/*N*/ {
/*N*/ 	if ( !pMgr )
/*N*/ 		return;
/*N*/ 
/*N*/     if ( GetFloatingWindow() && pImp->bConstructed )
/*N*/         pImp->aWinState = GetFloatingWindow()->GetWindowState();
/*N*/ 
/*N*/     rInfo.aWinState = pImp->aWinState;
/*N*/ 	rInfo.aExtraString += DEFINE_CONST_UNICODE("AL:(");
/*N*/     rInfo.aExtraString += String::CreateFromInt32((USHORT) GetAlignment());
/*N*/ 	rInfo.aExtraString += ',';
/*N*/     rInfo.aExtraString += String::CreateFromInt32 ((USHORT) pImp->GetLastAlignment());
/*N*/ 	if ( pImp->bSplitable )
/*N*/ 	{
/*N*/ 		Point aPos(pImp->nLine, pImp->nPos);
/*N*/ 		rInfo.aExtraString += ',';
/*N*/     	rInfo.aExtraString += String::CreateFromInt32( aPos.X() );
/*N*/ 		rInfo.aExtraString += '/';
/*N*/     	rInfo.aExtraString += String::CreateFromInt32( aPos.Y() );
/*N*/ 		rInfo.aExtraString += '/';
/*N*/         rInfo.aExtraString += String::CreateFromInt32( pImp->nHorizontalSize );
/*N*/ 		rInfo.aExtraString += '/';
/*N*/         rInfo.aExtraString += String::CreateFromInt32( pImp->nVerticalSize );
/*N*/ 	}
/*N*/ 
/*N*/ 	rInfo.aExtraString += ')';
/*N*/ }

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

/*N*/ SfxDockingWindow::~SfxDockingWindow()
/*N*/ {
/*N*/     ReleaseChildWindow_Impl();
/*N*/ 	delete pImp;
/*N*/ }

/*N*/ void SfxDockingWindow::ReleaseChildWindow_Impl()
/*N*/ {
/*N*/     if ( pMgr && pMgr->GetFrame() == pBindings->GetActiveFrame() )
/*?*/         pBindings->SetActiveFrame( NULL );
/*N*/ 
/*N*/ 	if ( pMgr && pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) )
/*N*/ 		pImp->pSplitWin->RemoveWindow(this);
/*N*/ 
/*N*/     pMgr=NULL;
/*N*/ }

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


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

/*N*/ Size SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign)
/*N*/ 
/*	[Beschreibung]

	Virtuelle Methode der Klasse SfxDockingWindow.
	Hier wird festgelegt, wie sich die Gr"o\se des DockingWindows abh"angig vom
	Alignment "andert.
	Die Basisimplementation setzt im Floating Mode die Gr"o\se auf die gemerkte
	Floating Size.
	Bei horizontalem Alignment wird die Breite auf die Breite des "au\seren
	DockingRects, bei vertikalem Alignment die H"ohe auf die H"ohe des inneren
	DockingRects (ergibt sich aus der Reihenfolge, in der im SFX ChildWindows
	ausgegeben werden). Die jeweils andere Gr"o\se wird auf die aktuelle
	Floating Size gesetzt, hier k"onnte eine abgeleitete Klasse "andernd
	eingreifen.
	Die DockingSize mu\s f"ur Left/Right und Top/Bottom jeweils gleich sein.
*/

/*N*/ {
/*N*/ 	// Achtung: falls das Resizing auch im angedockten Zustand geht, mu\s dabei
/*N*/ 	// auch die Floating Size angepa\st werden !?
/*N*/ DBG_BF_ASSERT(0, "STRIP"); Size aSize; //STRIP001 
/*N*/ 	return aSize;
/*N*/ }

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

/*N*/ SfxChildAlignment SfxDockingWindow::CheckAlignment(SfxChildAlignment,
/*N*/ 	SfxChildAlignment eAlign)
/*N*/ 
/*	[Beschreibung]

	Virtuelle Methode der Klasse SfxDockingWindow.
	Hier kann eine abgeleitete Klasse bestimmte Alignments verbieten.
	Die Basisimplementation verbietet kein Alignment.
*/

/*N*/ {
/*N*/ 	return eAlign;
/*N*/ }

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

/*?*/ BOOL SfxDockingWindow::Close()

/*	[Beschreibung]

	Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des
	ChildWindow-Slots zerst"ort wird.
	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
	danach SfxDockingWindow::Close() gerufen werden, wenn nicht das Close()
	mit "return FALSE" abgebrochen wird.

*/
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 
/*?*/ }

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

/*N*/ void SfxDockingWindow::Paint(const Rectangle& rRect)

/*	[Beschreibung]

	Es wird im angedockten Zustand eine Begrenzungslinie an der angedockten
	Kante und ein Rahmen ausgegeben. Dabei wird SVLOOK ber"ucksichtigt.
*/

/*N*/ {
/*N*/ 	if ( pImp->bSplitable || IsFloatingMode() )
/*N*/ 		return;
/*N*/ 
/*?*/ 	Rectangle aRect = Rectangle(Point(0, 0),
/*?*/ 								GetOutputSizePixel());
/*?*/ 	switch (GetAlignment())
/*?*/ 	{
/*?*/ 		case SFX_ALIGN_TOP:
/*?*/ 		{
/*?*/ 			DrawLine(aRect.BottomLeft(), aRect.BottomRight());
/*?*/ 			aRect.Bottom()--;
/*?*/ 			break;
/*?*/ 		}
/*?*/ 
/*?*/ 		case SFX_ALIGN_BOTTOM:
/*?*/ 		{
/*?*/ 			DrawLine(aRect.TopLeft(), aRect.TopRight());
/*?*/ 			aRect.Top()++;
/*?*/ 			break;
/*?*/ 		}
/*?*/ 
/*?*/ 		case SFX_ALIGN_LEFT:
/*?*/ 		{
/*?*/ 			DrawLine(aRect.TopRight(), aRect.BottomRight());
/*?*/ 			aRect.Right()--;
/*?*/ 			break;
/*?*/ 		}
/*?*/ 
/*?*/ 		case SFX_ALIGN_RIGHT:
/*?*/ 		{
/*?*/ 			DrawLine(aRect.TopLeft(), aRect.BottomLeft());
/*?*/ 			aRect.Left()++;
/*?*/ 			break;
/*?*/ 		}
/*?*/ 	}
/*N*/ 
/*N*/ 	DecorationView aView( this );
/*N*/ 	aView.DrawFrame( aRect, FRAME_DRAW_OUT );
/*N*/ }

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

/*N*/ void SfxDockingWindow::SetMinOutputSizePixel( const Size& rSize )

/*	[Beschreibung]

	Mit dieser Methode kann eine minimale OutpuSize gesetzt werden, die
	im Resizing()-Handler abgefragt wird.
*/

/*N*/ {
/*N*/ 	pImp->aMinSize = rSize;
/*N*/     DockingWindow::SetMinOutputSizePixel( rSize );
/*N*/ }

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

/*N*/ Size SfxDockingWindow::GetMinOutputSizePixel() const
/*N*/ 
/*	[Beschreibung]

	Die gesetzte minimale Gr"o\se wird zur"uckgegeben.
*/
/*N*/ 
/*N*/ {
/*N*/ 	return pImp->aMinSize;
/*N*/ }

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

/*N*/ long SfxDockingWindow::Notify( NotifyEvent& rEvt )
/*N*/ {
/*N*/     if ( rEvt.GetType() == EVENT_GETFOCUS )
/*N*/ 	{
/*N*/ 		pBindings->SetActiveFrame( pMgr->GetFrame() );
/*N*/ 
/*N*/ 		if ( pImp->pSplitWin )
/*N*/ 			pImp->pSplitWin->SetActiveWindow_Impl( this );
/*N*/ 		else
/*?*/ 			{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pMgr->Activate_Impl();
/*N*/ 
/*N*/         Window* pWindow = rEvt.GetWindow();
/*N*/         ULONG nHelpId  = 0;
/*N*/         while ( !nHelpId && pWindow )
/*N*/         {
/*N*/             nHelpId = pWindow->GetHelpId();
/*N*/             pWindow = pWindow->GetParent();
/*N*/         }
/*N*/ 
/*N*/         if ( nHelpId )
/*N*/             SfxHelp::OpenHelpAgent( pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), nHelpId );
/*
		// Nur wg. PlugIn
		SfxViewFrame *pFrame = pBindings->GetDispatcher_Impl()->GetFrame();
		if ( pFrame )
			pFrame->MakeActive_Impl();
*/
/*N*/ 		// In VCL geht Notify zun"achst an das Fenster selbst,
/*N*/ 		// also base class rufen, sonst erf"ahrt der parent nichts
/*N*/         if ( rEvt.GetWindow() == this )
/*N*/ 			DockingWindow::Notify( rEvt );
/*N*/ 		return TRUE;
/*N*/ 	}
/*N*/ 	else if( rEvt.GetType() == EVENT_KEYINPUT )
/*N*/ 	{
/*N*/ 		// KeyInput zuerst f"ur Dialogfunktionen zulassen
/*?*/ 		if ( !DockingWindow::Notify( rEvt ) )
/*?*/ 			// dann auch global g"ultige Acceleratoren verwenden
/*?*/ 			{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() );
/*?*/ 		return TRUE;
/*N*/ 	}
/*N*/     else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() )
/*N*/ 	{
/*N*/ //        pBindings->SetActiveFrame( XFrameRef() );
/*N*/         pMgr->Deactivate_Impl();
/*N*/ 	}
/*N*/ 
/*N*/ 	return DockingWindow::Notify( rEvt );
/*N*/ }


/*N*/ USHORT SfxDockingWindow::GetWinBits_Impl() const
/*N*/ {
/*N*/ 	USHORT nBits = 0;
/*N*/ //	if ( pImp->bAutoHide )
/*N*/ //		nBits |= SWIB_AUTOHIDE;
/*N*/ 	return nBits;
/*N*/ }

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



/*N*/ void SfxDockingWindow::Reappear_Impl()
/*N*/ {
/*N*/ 	if ( pImp->pSplitWin && !pImp->pSplitWin->IsItemValid( GetType() ) )
/*N*/ 	{
/*?*/ 		pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize );
/*N*/ 	}
/*N*/ }




/*
void SfxDockingWindow::Pin_Impl( BOOL bPinned )
{
	if ( pImp->pSplitWin )
		pImp->pSplitWin->Pin_Impl( bPinned );
}
*/


/*N*/ void SfxDockingWindow::FadeIn( BOOL bFadeIn )
/*N*/ {
/*N*/ }

/*N*/ void SfxDockingWindow::StateChanged( StateChangedType nStateChange )
/*N*/ {
/*N*/ 	if ( nStateChange == STATE_CHANGE_INITSHOW )
/*N*/ 		Initialize_Impl();
/*N*/ 
/*N*/ 	DockingWindow::StateChanged( nStateChange );
/*N*/ }

/*N*/ void SfxDockingWindow::Move()
/*N*/ {
/*N*/     if ( IsReallyVisible() && IsFloatingMode() )
/*N*/     {
/*N*/         SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
/*N*/         if ( pImp->bSplitable )
/*N*/             eIdent = SFX_CHILDWIN_SPLITWINDOW;
/*N*/         SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
/*N*/         pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() );
/*N*/     }
/*N*/ }

}
