/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

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

// #include <math.h>
#include <rangelst.hxx>
#include <sfx2/app.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/event.hxx>
#include <sfx2/imgmgr.hxx>
#include <sfx2/navigat.hxx>
#include <svl/stritem.hxx>
#include <svl/urlbmk.hxx>
#include <vcl/sound.hxx>
#include <unotools/charclass.hxx>
#include <stdlib.h>

#include "viewdata.hxx"
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "document.hxx"
#include "dbcolect.hxx"
#include "rangenam.hxx"
#include "rangeutl.hxx"
#include "popmenu.hxx"
#include "scresid.hxx"
#include "scmod.hxx"
#include "navicfg.hxx"
#include "navcitem.hxx"
#include "navipi.hrc"
#include "navipi.hxx"
#include "navsett.hxx"

//	Timeout, um Notizen zu suchen
#define SC_CONTENT_TIMEOUT	1000

//	Toleranz, wieviel ueber der eingeklappten Groesse noch klein ist
#define SCNAV_MINTOL		5

//  maximum values for UI
#define SCNAV_MAXCOL        (MAXCOLCOUNT)
// macro is sufficient since only used in ctor
#define SCNAV_COLDIGITS     (static_cast<xub_StrLen>( floor( log10( static_cast<double>(SCNAV_MAXCOL)))) + 1)   // 1...256...18278
// precomputed constant because it is used in every change of spin button field
static const xub_StrLen SCNAV_COLLETTERS = ::ScColToAlpha(SCNAV_MAXCOL).Len();    // A...IV...ZZZ

#define SCNAV_MAXROW        (MAXROWCOUNT)

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

//	static
void ScNavigatorDlg::ReleaseFocus()
{
	SfxViewShell* pCurSh = SfxViewShell::Current();

	if ( pCurSh )
	{
		Window* pShellWnd = pCurSh->GetWindow();
		if ( pShellWnd )
			pShellWnd->GrabFocus();
	}
}

//==================================================================
//	class ColumnEdit
//==================================================================

ColumnEdit::ColumnEdit( ScNavigatorDlg* pParent, const ResId& rResId )
	:	SpinField	( pParent, rResId ),
		rDlg		( *pParent ),
		nCol		( 0 ),
		nKeyGroup	( KEYGROUP_ALPHA )
{
    SetMaxTextLen( SCNAV_COLDIGITS );   // 1...256...18278 or A...IV...ZZZ
}

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

__EXPORT ColumnEdit::~ColumnEdit()
{
}

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

long __EXPORT ColumnEdit::Notify( NotifyEvent& rNEvt )
{
	long nHandled = SpinField::Notify( rNEvt );

	sal_uInt16 nType = rNEvt.GetType();
	if ( nType == EVENT_KEYINPUT )
	{
		const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
		KeyCode aCode = pKEvt->GetKeyCode();

		if ( !aCode.IsMod1() && !aCode.IsMod2() )
		{
			//!	Eingabeueberpruefung (nur Zahlen oder nur Buchstaben, max 2 bzw 3 Stellen)
			//!	war vor VCL per nicht weitergeleitetem KeyInput
			//!	dafuer was neues ausdenken!!!

			if ( aCode.GetCode() == KEY_RETURN )
			{
				ScNavigatorDlg::ReleaseFocus();
				ExecuteCol();
				nHandled = 1;
			}
		}
	}
	else if ( nType == EVENT_LOSEFOCUS )	// LoseFocus wird bei VCL nicht gerufen
		EvalText();							// nCol setzen

	return nHandled;
}

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

void __EXPORT ColumnEdit::LoseFocus()
{
	EvalText();
}


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

void __EXPORT ColumnEdit::Up()
{
    nCol++;

#ifdef OS2
    if ( nCol > SCNAV_MAXCOL )
		nCol = 1;
#endif

    if ( nCol <= SCNAV_MAXCOL )
		SetCol( nCol );
	else
        nCol--;
}

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

void __EXPORT ColumnEdit::Down()
{
	if ( nCol>1 )
		SetCol( nCol-1 );
#ifdef OS2
	else
        SetCol( SCNAV_MAXCOL );
#endif
}

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

void __EXPORT ColumnEdit::First()
{
    nCol = 1;
	SetText( 'A' );
}

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

void __EXPORT ColumnEdit::Last()
{
    String aStr;
    nCol = NumToAlpha( SCNAV_MAXCOL, aStr );
    SetText( aStr );
}


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

void ColumnEdit::EvalText()
{
	String aStrCol = GetText();

	if ( aStrCol.Len() > 0 )
	{
		//	nKeyGroup wird bei VCL mangels KeyInput nicht mehr gesetzt

		if ( CharClass::isAsciiNumeric(aStrCol) )
			nCol = NumStrToAlpha( aStrCol );
		else
			nCol = AlphaToNum( aStrCol );
	}
	else
		nCol = 0;

	SetText( aStrCol );
	nKeyGroup = KEYGROUP_ALPHA;
}

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

void ColumnEdit::ExecuteCol()
{
	SCROW nRow = rDlg.aEdRow.GetRow();

	EvalText(); // setzt nCol

	if ( (nCol > 0) && (nRow > 0) )
		rDlg.SetCurrentCell( nCol-1, nRow-1 );
}

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

void ColumnEdit::SetCol( SCCOL nColNo )
{
	String aStr;

	if ( nColNo == 0 )
	{
		nCol = 0;
		SetText( aStr );
	}
	else
	{
		nColNo = NumToAlpha( nColNo, aStr );
		nCol = nColNo;
		SetText( aStr );
	}
}

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

SCCOL ColumnEdit::AlphaToNum( String& rStr )
{
	SCCOL  nColumn = 0;

	if ( CharClass::isAsciiAlpha( rStr) )
	{
		rStr.ToUpperAscii();

        if (::AlphaToCol( nColumn, rStr))
            ++nColumn;

        if ( (rStr.Len() > SCNAV_COLLETTERS) || (nColumn > SCNAV_MAXCOL) )
        {
            nColumn = SCNAV_MAXCOL;
            NumToAlpha( nColumn, rStr );
        }
	}
    else
        rStr.Erase();

	return nColumn;
}

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

SCCOL ColumnEdit::NumStrToAlpha( String& rStr )
{
	SCCOL  nColumn = 0;

	if ( CharClass::isAsciiNumeric(rStr) )
		nColumn = NumToAlpha( (SCCOL)rStr.ToInt32(), rStr );
	else
		rStr.Erase();

	return nColumn;
}

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

SCCOL ColumnEdit::NumToAlpha( SCCOL nColNo, String& rStr )
{
    if ( nColNo > SCNAV_MAXCOL )
        nColNo = SCNAV_MAXCOL;
    else if ( nColNo < 1 )
		nColNo = 1;

    ::ScColToAlpha( rStr, nColNo - 1);

    return nColNo;
}

//==================================================================
//	class RowEdit
//==================================================================

RowEdit::RowEdit( ScNavigatorDlg* pParent, const ResId& rResId )
	:	NumericField( pParent, rResId ),
		rDlg		( *pParent )
{
    SetMax( SCNAV_MAXROW);
    SetLast( SCNAV_MAXROW);
}

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

__EXPORT RowEdit::~RowEdit()
{
}

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

long __EXPORT RowEdit::Notify( NotifyEvent& rNEvt )
{
	long nHandled = NumericField::Notify( rNEvt );

	if ( rNEvt.GetType() == EVENT_KEYINPUT )
	{
		const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
		KeyCode aCode = pKEvt->GetKeyCode();
		if ( aCode.GetCode() == KEY_RETURN && !aCode.IsMod1() && !aCode.IsMod2() )
		{
			ScNavigatorDlg::ReleaseFocus();
			ExecuteRow();
			nHandled = 1;
		}
	}

	return nHandled;
}

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

void __EXPORT RowEdit::LoseFocus()
{
}

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

void RowEdit::ExecuteRow()
{
	SCCOL nCol = rDlg.aEdCol.GetCol();
	SCROW nRow = (SCROW)GetValue();

	if ( (nCol > 0) && (nRow > 0) )
		rDlg.SetCurrentCell( nCol-1, nRow-1 );
}

//==================================================================
//	class ScDocListBox
//==================================================================

ScDocListBox::ScDocListBox( ScNavigatorDlg* pParent, const ResId& rResId )
	:	ListBox	( pParent, rResId ),
		rDlg	( *pParent )
{
}

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

__EXPORT ScDocListBox::~ScDocListBox()
{
}

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

void __EXPORT ScDocListBox::Select()
{
	ScNavigatorDlg::ReleaseFocus();

	String aDocName = GetSelectEntry();
	rDlg.aLbEntries.SelectDoc( aDocName );
}

//==================================================================
//	class CommandToolBox
//==================================================================

CommandToolBox::CommandToolBox( ScNavigatorDlg* pParent, const ResId& rResId )
	:	ToolBox	( pParent, rResId ),
		rDlg	( *pParent )
{
	InitImageList();	// ImageList members of ScNavigatorDlg must be initialized before!

	SetSizePixel( CalcWindowSizePixel() );
    SetDropdownClickHdl( LINK(this, CommandToolBox, ToolBoxDropdownClickHdl) );
    SetItemBits( IID_DROPMODE, GetItemBits( IID_DROPMODE ) | TIB_DROPDOWNONLY );
//	EnableItem( IID_UP, sal_False );
//	EnableItem( IID_DOWN, sal_False );
}

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

__EXPORT CommandToolBox::~CommandToolBox()
{
}

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

void CommandToolBox::Select( sal_uInt16 nSelId )
{
	//	Modus umschalten ?

	if ( nSelId == IID_ZOOMOUT || nSelId == IID_SCENARIOS )
	{
		NavListMode eOldMode = rDlg.eListMode;
		NavListMode eNewMode = eOldMode;

		if ( nSelId == IID_SCENARIOS )					// auf Szenario
		{
			if ( eOldMode == NAV_LMODE_SCENARIOS )
				eNewMode = NAV_LMODE_AREAS;
			else
				eNewMode = NAV_LMODE_SCENARIOS;
		}
		else											// ein/aus
		{
			if ( eOldMode == NAV_LMODE_NONE )
				eNewMode = NAV_LMODE_AREAS;
			else
				eNewMode = NAV_LMODE_NONE;
		}
		rDlg.SetListMode( eNewMode );
		UpdateButtons();
	}
	else
		switch ( nSelId )
		{
			case IID_DATA:
				rDlg.MarkDataArea();
				break;
			case IID_UP:
				rDlg.StartOfDataArea();
				break;
			case IID_DOWN:
				rDlg.EndOfDataArea();
				break;
			// IID_DROPMODE ist in Click
			case IID_CHANGEROOT:
				rDlg.aLbEntries.ToggleRoot();
				UpdateButtons();
				break;
		}
}

void __EXPORT CommandToolBox::Select()
{
	Select( GetCurItemId() );
}

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

void __EXPORT CommandToolBox::Click()
{
}

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

IMPL_LINK( CommandToolBox, ToolBoxDropdownClickHdl, ToolBox*, EMPTYARG )
{
	//	Das Popupmenue fuer den Dropmodus muss im Click (Button Down)
	//	statt im Select (Button Up) aufgerufen werden.

	if ( GetCurItemId() == IID_DROPMODE )
	{
		ScPopupMenu aPop( ScResId( RID_POPUP_DROPMODE ) );
		aPop.CheckItem( RID_DROPMODE_URL + rDlg.GetDropMode() );
		aPop.Execute( this, GetItemRect(IID_DROPMODE), POPUPMENU_EXECUTE_DOWN );
		sal_uInt16 nId = aPop.GetSelected();

		EndSelection();		// vor SetDropMode (SetDropMode ruft SetItemImage)

		if ( nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY )
			rDlg.SetDropMode( nId - RID_DROPMODE_URL );

		//	#49956# den gehighlighteten Button aufheben
		Point aPoint;
		MouseEvent aLeave( aPoint, 0, MOUSE_LEAVEWINDOW | MOUSE_SYNTHETIC );
		MouseMove( aLeave );
	}

    return 1;
}

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

void CommandToolBox::UpdateButtons()
{
	NavListMode eMode = rDlg.eListMode;
	CheckItem( IID_SCENARIOS,	eMode == NAV_LMODE_SCENARIOS );
	CheckItem( IID_ZOOMOUT,		eMode != NAV_LMODE_NONE );

	//	Umschalten-Button:
	if ( eMode == NAV_LMODE_SCENARIOS || eMode == NAV_LMODE_NONE )
	{
		EnableItem( IID_CHANGEROOT,	sal_False );
		CheckItem( IID_CHANGEROOT, sal_False );
	}
	else
	{
		EnableItem( IID_CHANGEROOT,	sal_True );
		sal_Bool bRootSet = rDlg.aLbEntries.GetRootType() != SC_CONTENT_ROOT;
		CheckItem( IID_CHANGEROOT, bRootSet );
	}

	sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode();

	sal_uInt16 nImageId = 0;
	switch ( rDlg.nDropMode )
	{
		case SC_DROPMODE_URL:	nImageId = bHC ? RID_IMG_H_DROP_URL  : RID_IMG_DROP_URL;  break;
		case SC_DROPMODE_LINK:	nImageId = bHC ? RID_IMG_H_DROP_LINK : RID_IMG_DROP_LINK; break;
		case SC_DROPMODE_COPY:	nImageId = bHC ? RID_IMG_H_DROP_COPY : RID_IMG_DROP_COPY; break;
	}
	SetItemImage( IID_DROPMODE, Image(ScResId(nImageId)) );
}

void CommandToolBox::InitImageList()
{
	sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode();

    ImageList& rImgLst = bHC ? rDlg.aCmdImageListH : rDlg.aCmdImageList;

	sal_uInt16 nCount = GetItemCount();
    for (sal_uInt16 i = 0; i < nCount; i++)
    {
    	sal_uInt16 nId = GetItemId(i);
		SetItemImage( nId, rImgLst.GetImage( nId ) );
    }
}

void CommandToolBox::DataChanged( const DataChangedEvent& rDCEvt )
{
	if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
	{
		//	update item images

		InitImageList();
		UpdateButtons();	// drop mode
	}

    ToolBox::DataChanged( rDCEvt );
}

//==================================================================
//  class ScNavigatorSettings
//==================================================================

ScNavigatorSettings::ScNavigatorSettings() :
    maExpandedVec( SC_CONTENT_COUNT, sal_False ),
    mnRootSelected( SC_CONTENT_ROOT ),
    mnChildSelected( SC_CONTENT_NOCHILD )
{
}

//==================================================================
//	class ScNavigatorDlgWrapper
//==================================================================

SFX_IMPL_CHILDWINDOWCONTEXT( ScNavigatorDialogWrapper, SID_NAVIGATOR )

#define IS_MODE(bit)(((nFlags)&(bit))==(bit))

ScNavigatorDialogWrapper::ScNavigatorDialogWrapper(
									Window*			 pParent,
									sal_uInt16			 nId,
									SfxBindings*	 pBind,
                                    SfxChildWinInfo* /* pInfo */ ) :
		SfxChildWindowContext( nId )
{
	pNavigator = new ScNavigatorDlg( pBind, this, pParent );
	SetWindow( pNavigator );

	//	Einstellungen muessen anderswo gemerkt werden,
	//	pInfo geht uns (ausser der Groesse) nichts mehr an

	Size aInfoSize = pParent->GetOutputSizePixel();		// von aussen vorgegebene Groesse
	Size aNavSize = pNavigator->GetOutputSizePixel();	// Default-Groesse

	aNavSize.Width()  = Max( aInfoSize.Width(),  aNavSize.Width() );
	aNavSize.Height() = Max( aInfoSize.Height(), aNavSize.Height() );
	pNavigator->nListModeHeight = Max( aNavSize.Height(), pNavigator->nListModeHeight );

	//	Die Groesse kann in einem anderen Modul geaendert worden sein,
	//	deshalb muessen in Abhaengigkeit von der momentanen Groesse die
	//	Inhalte eingeblendet werden oder nicht

	sal_Bool bSmall = ( aInfoSize.Height() <= pNavigator->aInitSize.Height() + SCNAV_MINTOL );
	NavListMode eNavMode = NAV_LMODE_NONE;
	if (!bSmall)
	{
		//	wenn Szenario aktiv war, wieder einschalten

		ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
		NavListMode eLastMode = (NavListMode) rCfg.GetListMode();
		if ( eLastMode == NAV_LMODE_SCENARIOS )
			eNavMode = NAV_LMODE_SCENARIOS;
		else
			eNavMode = NAV_LMODE_AREAS;
	}

	//	Die Groesse des Floats nicht neu setzen (sal_False bei SetListMode), damit der
	//	Navigator nicht aufgeklappt wird, wenn er minimiert war (#38872#).

	pNavigator->SetListMode( eNavMode, sal_False );		// FALSE: Groesse des Float nicht setzen

	sal_uInt16 nCmdId;
	switch (eNavMode)
	{
		case NAV_LMODE_DOCS:		nCmdId = IID_DOCS; 		break;
		case NAV_LMODE_AREAS:		nCmdId = IID_AREAS; 	break;
		case NAV_LMODE_DBAREAS:		nCmdId = IID_DBAREAS; 	break;
		case NAV_LMODE_SCENARIOS:	nCmdId = IID_SCENARIOS; break;
        default:                    nCmdId = 0;
	}
	if (nCmdId)
	{
		pNavigator->aTbxCmd.CheckItem( nCmdId );
		pNavigator->DoResize();
	}

	pNavigator->bFirstBig = ( nCmdId == 0 );	// dann spaeter

/*???
	FloatingWindow* pFloat = GetFloatingWindow();
	if ( pFloat )
		pFloat->SetMinOutputSizePixel( pNavigator->GetMinOutputSizePixel() );
*/

//!?	pNavigator->Show();
}

void __EXPORT ScNavigatorDialogWrapper::Resizing( Size& rSize )
{
	((ScNavigatorDlg*)GetWindow())->Resizing(rSize);
}

//========================================================================
// class ScNavigatorPI
//========================================================================

#define CTRL_ITEMS 4

#define REGISTER_SLOT(i,id) \
	ppBoundItems[i]=new ScNavigatorControllerItem(id,*this,rBindings);

ScNavigatorDlg::ScNavigatorDlg( SfxBindings* pB, SfxChildWindowContext* pCW, Window* pParent ) :
		Window( pParent, ScResId(RID_SCDLG_NAVIGATOR) ),
		rBindings	( *pB ),								// is used in CommandToolBox ctor
		aCmdImageList( ScResId( IL_CMD ) ),
    	aCmdImageListH( ScResId( ILH_CMD ) ),
		aFtCol		( this, ScResId( FT_COL ) ),
		aEdCol		( this, ScResId( ED_COL ) ),
		aFtRow		( this, ScResId( FT_ROW ) ),
		aEdRow		( this, ScResId( ED_ROW ) ),
		aTbxCmd		( this, ScResId( TBX_CMD ) ),
		aLbEntries	( this, ScResId( LB_ENTRIES ) ),
        aWndScenarios( this,ScResId( STR_QHLP_SCEN_LISTBOX), ScResId(STR_QHLP_SCEN_COMMENT)),
		aLbDocuments( this, ScResId( LB_DOCUMENTS ) ),
		aStrDragMode ( ScResId( STR_DRAGMODE ) ),
		aStrDisplay  ( ScResId( STR_DISPLAY ) ),
		aStrActiveWin( ScResId( STR_ACTIVEWIN ) ),
		pContextWin	( pCW ),
		pMarkArea	( NULL ),
		pViewData	( NULL ),
		nListModeHeight( 0 ),
		nInitListHeight( 0 ),
		eListMode	( NAV_LMODE_NONE ),
		nDropMode	( SC_DROPMODE_URL ),
		nCurCol		( 0 ),
		nCurRow		( 0 ),
		nCurTab		( 0 ),
		bFirstBig	( sal_False )
{
	ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
	nDropMode = rCfg.GetDragMode();
	//	eListMode wird von aussen gesetzt, Root weiter unten

	aLbDocuments.SetDropDownLineCount(9);
	String aOpen = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
	aStrActive = aOpen;
	aStrActive += String( ScResId( STR_ACTIVE ) );
	aStrActive += ')';										// " (aktiv)"
	aStrNotActive = aOpen;
	aStrNotActive += String( ScResId( STR_NOTACTIVE ) );
	aStrNotActive += ')';									// " (inaktiv)"
	aStrHidden = aOpen;
	aStrHidden += String( ScResId( STR_HIDDEN ) );
	aStrHidden += ')';										// " (versteckt)"

	aTitleBase = GetText();

    long nListboxYPos = aTbxCmd.GetPosPixel().Y() + aTbxCmd.GetSizePixel().Height() + 4;
    aLbEntries.SetPosSizePixel( 0, nListboxYPos, 0, 0, WINDOW_POSSIZE_Y);

	nBorderOffset = aLbEntries.GetPosPixel().X();

	aInitSize.Width()  =  aTbxCmd.GetPosPixel().X()
						+ aTbxCmd.GetSizePixel().Width()
						+ nBorderOffset;
	aInitSize.Height() = aLbEntries.GetPosPixel().Y();

	nInitListHeight	= aLbEntries.GetSizePixel().Height();
	nListModeHeight	=  aInitSize.Height()
					 + nInitListHeight;

	//	kein Resize, eh der ganze Kontext-Kram initialisiert ist!
//	SetOutputSizePixel( aInitSize );		//???
/*!	FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
	if ( pFloat)
		pFloat->SetMinOutputSizePixel( aInitSize );
*/
	ppBoundItems = new ScNavigatorControllerItem* [CTRL_ITEMS];

	rBindings.ENTERREGISTRATIONS();
	//-----------------------------
	REGISTER_SLOT( 0, SID_CURRENTCELL		);
	REGISTER_SLOT( 1, SID_CURRENTTAB		);
	REGISTER_SLOT( 2, SID_CURRENTDOC		);
	REGISTER_SLOT( 3, SID_SELECT_SCENARIO	);
	//-----------------------------
	rBindings.LEAVEREGISTRATIONS();

	StartListening( *(SFX_APP()) );
	StartListening( rBindings );

	aLbDocuments.Hide();		// bei NAV_LMODE_NONE gibts die nicht

	aLbEntries.InitWindowBits(sal_True);

	aLbEntries.SetSpaceBetweenEntries(0);
	aLbEntries.SetSelectionMode( SINGLE_SELECTION );
	aLbEntries.SetDragDropMode( 	SV_DRAGDROP_CTRL_MOVE |
									SV_DRAGDROP_CTRL_COPY |
									SV_DRAGDROP_ENABLE_TOP );

	//	war eine Kategorie als Root ausgewaehlt?
	sal_uInt16 nLastRoot = rCfg.GetRootType();
	if ( nLastRoot )
		aLbEntries.SetRootType( nLastRoot );

	aLbEntries.Refresh();
	GetDocNames();

	aTbxCmd.UpdateButtons();

	UpdateColumn();
	UpdateRow();
	UpdateTable();
	aLbEntries.Hide();
	aWndScenarios.Hide();
	aWndScenarios.SetPosPixel( aLbEntries.GetPosPixel() );

	aContentTimer.SetTimeoutHdl( LINK( this, ScNavigatorDlg, TimeHdl ) );
	aContentTimer.SetTimeout( SC_CONTENT_TIMEOUT );

	FreeResource();

	aLbEntries.SetAccessibleRelationLabeledBy(&aLbEntries);
	aTbxCmd.SetAccessibleRelationLabeledBy(&aTbxCmd);
	aLbDocuments.SetAccessibleName(aStrActiveWin);
}

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

__EXPORT ScNavigatorDlg::~ScNavigatorDlg()
{
	aContentTimer.Stop();

	sal_uInt16 i;
	for ( i=0; i<CTRL_ITEMS; i++ )
		delete ppBoundItems[i];

	delete [] ppBoundItems;
	delete pMarkArea;

	EndListening( *(SFX_APP()) );
	EndListening( rBindings );
}

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

void __EXPORT ScNavigatorDlg::Resizing( Size& rNewSize )  // Size = Outputsize?
{
	FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
	if ( pFloat )
	{
		Size aMinOut = pFloat->GetMinOutputSizePixel();

		if ( rNewSize.Width() < aMinOut.Width() )
			rNewSize.Width() = aMinOut.Width();

		if ( eListMode == NAV_LMODE_NONE )
			rNewSize.Height() = aInitSize.Height();
		else
		{
			if ( rNewSize.Height() < aMinOut.Height() )
				rNewSize.Height() = aMinOut.Height();
		}
	}
//	else
//		SfxDockingWindow::Resizing(rNewSize);
}



void ScNavigatorDlg::Paint( const Rectangle& rRec )
{
	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
	Color aBgColor = rStyleSettings.GetFaceColor();
	Wallpaper aBack( aBgColor );

	SetBackground( aBack );
	aFtCol.SetBackground( aBack );
	aFtRow.SetBackground( aBack );

	Window::Paint( rRec );
}

void ScNavigatorDlg::DataChanged( const DataChangedEvent& rDCEvt )
{
	if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
	{
		//	toolbox images are exchanged in CommandToolBox::DataChanged
		Invalidate();
	}

    Window::DataChanged( rDCEvt );
}

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

void __EXPORT ScNavigatorDlg::Resize()
{
	DoResize();
}

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

void ScNavigatorDlg::DoResize()
{
	Size aNewSize = GetOutputSizePixel();
	long nTotalHeight = aNewSize.Height();

	//	#41403# bei angedocktem Navigator wird das Fenster evtl. erst klein erzeugt,
	//	dann kommt ein Resize auf die wirkliche Groesse -> dann Inhalte einschalten

	sal_Bool bSmall = ( nTotalHeight <= aInitSize.Height() + SCNAV_MINTOL );
	if ( !bSmall && bFirstBig )
	{
		//	Inhalte laut Config wieder einschalten

		bFirstBig = sal_False;
		NavListMode eNavMode = NAV_LMODE_AREAS;
		ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
		NavListMode eLastMode = (NavListMode) rCfg.GetListMode();
		if ( eLastMode == NAV_LMODE_SCENARIOS )
			eNavMode = NAV_LMODE_SCENARIOS;
		SetListMode( eNavMode, sal_False );			// FALSE: Groesse des Float nicht setzen
	}

	//	auch wenn die Inhalte nicht sichtbar sind, die Groessen anpassen,
	//	damit die Breite stimmt

	//@@ 03.11.97 changes begin
	Point aEntryPos = aLbEntries.GetPosPixel();
	Point aListPos = aLbDocuments.GetPosPixel();
	aNewSize.Width() -= 2*nBorderOffset;
	Size aDocSize = aLbDocuments.GetSizePixel();
	aDocSize.Width() = aNewSize.Width();

	if(!bSmall)
	{

		long nListHeight = aLbDocuments.GetSizePixel().Height();
		aNewSize.Height() -= ( aEntryPos.Y() + nListHeight + 2*nBorderOffset );
		if(aNewSize.Height()<0)	aNewSize.Height()=0;

		aListPos.Y() = aEntryPos.Y() + aNewSize.Height() + nBorderOffset;

		if(aListPos.Y() > aLbEntries.GetPosPixel().Y())
							aLbDocuments.SetPosPixel( aListPos );

	}
	aLbEntries.SetSizePixel( aNewSize );
	aWndScenarios.SetSizePixel( aNewSize );
	aLbDocuments.SetSizePixel( aDocSize );

	//@@ 03.11.97 end

	sal_Bool bListMode = (eListMode != NAV_LMODE_NONE);
	FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
	if ( pFloat && bListMode )
		nListModeHeight = nTotalHeight;
}

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

void __EXPORT ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
	if ( rHint.ISA(SfxSimpleHint) )
	{
		sal_uLong nHintId = ((SfxSimpleHint&)rHint).GetId();

		if ( nHintId == SC_HINT_DOCNAME_CHANGED )
		{
			aLbEntries.ActiveDocChanged();
		}
		else if ( NAV_LMODE_NONE == eListMode )
		{
			//	Tabellen hier nicht mehr
		}
		else
		{
			switch ( nHintId )
			{
				case SC_HINT_TABLES_CHANGED:
					aLbEntries.Refresh( SC_CONTENT_TABLE );
					break;

				case SC_HINT_DBAREAS_CHANGED:
					aLbEntries.Refresh( SC_CONTENT_DBAREA );
					break;

				case SC_HINT_AREAS_CHANGED:
					aLbEntries.Refresh( SC_CONTENT_RANGENAME );
					break;

				case SC_HINT_DRAW_CHANGED:
					aLbEntries.Refresh( SC_CONTENT_GRAPHIC );
					aLbEntries.Refresh( SC_CONTENT_OLEOBJECT );
					aLbEntries.Refresh( SC_CONTENT_DRAWING );
					break;

				case SC_HINT_AREALINKS_CHANGED:
					aLbEntries.Refresh( SC_CONTENT_AREALINK );
					break;

				//	SFX_HINT_DOCCHANGED kommt nicht nur bei Dokument-Wechsel

				case SC_HINT_NAVIGATOR_UPDATEALL:
					UpdateAll();
					break;

				case FID_DATACHANGED:
				case FID_ANYDATACHANGED:
					aContentTimer.Start();		// Notizen nicht sofort suchen
					break;

				default:
					break;
			}
		}
	}
	else if ( rHint.ISA(SfxEventHint) )
	{
		sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId();
		if ( nEventId == SFX_EVENT_ACTIVATEDOC )
		{
			aLbEntries.ActiveDocChanged();
			UpdateAll();
		}
	}
}

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

IMPL_LINK( ScNavigatorDlg, TimeHdl, Timer*, pTimer )
{
	if ( pTimer != &aContentTimer )
		return 0;

	aLbEntries.Refresh( SC_CONTENT_NOTE );
	return 0;
}

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

void ScNavigatorDlg::SetDropMode(sal_uInt16 nNew)
{
	nDropMode = nNew;
	aTbxCmd.UpdateButtons();

	ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
	rCfg.SetDragMode(nDropMode);
}

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

void ScNavigatorDlg::CursorPosChanged()
{
	//!	Eintraege selektieren ???

//	if ( GetDBAtCursor( aStrDbName ) )
//	if ( GetAreaAtCursor( aStrAreaName ) )
}

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

void ScNavigatorDlg::SetCurrentCell( SCCOL nColNo, SCROW nRowNo )
{
	if ( (nColNo+1 != nCurCol) || (nRowNo+1 != nCurRow) )
	{
		// SID_CURRENTCELL == Item #0 Cache leeren, damit das Setzen der
		// aktuellen Zelle auch in zusammengefassten Bereichen funktioniert.
		ppBoundItems[0]->ClearCache();

		ScAddress aScAddress( nColNo, nRowNo, 0 );
		String	aAddr;
		aScAddress.Format( aAddr, SCA_ABS );

		sal_Bool bUnmark = sal_False;
		if ( GetViewData() )
			bUnmark = !pViewData->GetMarkData().IsCellMarked( nColNo, nRowNo );

		SfxStringItem	aPosItem( SID_CURRENTCELL, aAddr );
		SfxBoolItem		aUnmarkItem( FN_PARAM_1, bUnmark );		// ggf. Selektion aufheben

		rBindings.GetDispatcher()->Execute( SID_CURRENTCELL,
								  SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
								  &aPosItem, &aUnmarkItem, 0L );
	}
}

void ScNavigatorDlg::SetCurrentCellStr( const String rName )
{
	ppBoundItems[0]->ClearCache();
	SfxStringItem	aNameItem( SID_CURRENTCELL, rName );

	rBindings.GetDispatcher()->Execute( SID_CURRENTCELL,
							  SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
							  &aNameItem, 0L );
}

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

void ScNavigatorDlg::SetCurrentTable( SCTAB nTabNo )
{
	if ( nTabNo != nCurTab )
	{
		//	Tabelle fuer Basic ist 1-basiert
		SfxUInt16Item aTabItem( SID_CURRENTTAB, static_cast<sal_uInt16>(nTabNo) + 1 );
		rBindings.GetDispatcher()->Execute( SID_CURRENTTAB,
								  SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
								  &aTabItem, 0L );
	}
}

void ScNavigatorDlg::SetCurrentTableStr( const String rName )
{
	if (!GetViewData()) return;

	ScDocument* pDoc = pViewData->GetDocument();
	SCTAB nCount	 = pDoc->GetTableCount();
	String aTabName;

	for ( SCTAB i=0; i<nCount; i++ )
	{
		pDoc->GetName( i, aTabName );
		if ( aTabName == rName )
		{
			SetCurrentTable( i );
			return;
		}
	}

	Sound::Beep();					// Tabelle nicht gefunden
}

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

void ScNavigatorDlg::SetCurrentObject( const String rName )
{
	SfxStringItem aNameItem( SID_CURRENTOBJECT, rName );
	rBindings.GetDispatcher()->Execute( SID_CURRENTOBJECT,
							  SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
							  &aNameItem, 0L );
}

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

void ScNavigatorDlg::SetCurrentDoc( const String& rDocName )		// aktivieren
{
	SfxStringItem aDocItem( SID_CURRENTDOC, rDocName );
	rBindings.GetDispatcher()->Execute( SID_CURRENTDOC,
							  SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
							  &aDocItem, 0L );
}

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

ScTabViewShell* ScNavigatorDlg::GetTabViewShell() const
{
    return PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
}

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

ScNavigatorSettings* ScNavigatorDlg::GetNavigatorSettings()
{
    //  #95791# Don't store the settings pointer here, because the settings belong to
    //  the view, and the view may be closed while the navigator is open (reload).
    //  If the pointer is cached here again later for performance reasons, it has to
    //  be forgotten when the view is closed.

    ScTabViewShell* pViewSh = GetTabViewShell();
    return pViewSh ? pViewSh->GetNavigatorSettings() : NULL;
}

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

sal_Bool ScNavigatorDlg::GetViewData()
{
    ScTabViewShell* pViewSh = GetTabViewShell();
	pViewData = pViewSh ? pViewSh->GetViewData() : NULL;

	return ( pViewData != NULL );
}

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

void ScNavigatorDlg::UpdateColumn( const SCCOL* pCol )
{
	if ( pCol )
		nCurCol = *pCol;
	else if ( GetViewData() )
		nCurCol = pViewData->GetCurX() + 1;

	aEdCol.SetCol( nCurCol );
	CheckDataArea();
}

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

void ScNavigatorDlg::UpdateRow( const SCROW* pRow )
{
	if ( pRow )
		nCurRow = *pRow;
	else if ( GetViewData() )
		nCurRow = pViewData->GetCurY() + 1;

	aEdRow.SetRow( nCurRow );
	CheckDataArea();
}

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

void ScNavigatorDlg::UpdateTable( const SCTAB* pTab )
{
	if ( pTab )
		nCurTab = *pTab;
	else if ( GetViewData() )
		nCurTab = pViewData->GetTabNo();

//	aLbTables.SetTab( nCurTab );
	CheckDataArea();
}

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

void ScNavigatorDlg::UpdateAll()
{
	switch ( eListMode )
	{
		case NAV_LMODE_DOCS:
		case NAV_LMODE_DBAREAS:
		case NAV_LMODE_AREAS:
            aLbEntries.Refresh();
			break;

		case NAV_LMODE_NONE:
			//!	???
			break;

		default:
			break;
	}

	aContentTimer.Stop();		// dann nicht nochmal
}

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

void ScNavigatorDlg::SetListMode( NavListMode eMode, sal_Bool bSetSize )
{
	if ( eMode != eListMode )
	{
		if ( eMode != NAV_LMODE_NONE )
			bFirstBig = sal_False;				// nicht mehr automatisch umschalten

		eListMode = eMode;

		switch ( eMode )
		{
			case NAV_LMODE_NONE:
				ShowList( sal_False, bSetSize );
				break;

			case NAV_LMODE_AREAS:
			case NAV_LMODE_DBAREAS:
			case NAV_LMODE_DOCS:
				aLbEntries.Refresh();
				ShowList( sal_True, bSetSize );
				break;

			case NAV_LMODE_SCENARIOS:
				ShowScenarios( sal_True, bSetSize );
				break;
		}

		aTbxCmd.UpdateButtons();

		if ( eMode != NAV_LMODE_NONE )
		{
			ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
			rCfg.SetListMode( (sal_uInt16) eMode );
		}
	}

	if ( pMarkArea )
		UnmarkDataArea();
}

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

void ScNavigatorDlg::ShowList( sal_Bool bShow, sal_Bool bSetSize )
{
	FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
	Size aSize = GetParent()->GetOutputSizePixel();

	if ( bShow )
	{
		Size aMinSize = aInitSize;

		aMinSize.Height() += nInitListHeight;
		if ( pFloat )
			pFloat->SetMinOutputSizePixel( aMinSize );
		aSize.Height() = nListModeHeight;
		aLbEntries.Show();
		aLbDocuments.Show();
	}
	else
	{
		if ( pFloat )
		{
			pFloat->SetMinOutputSizePixel( aInitSize );
			nListModeHeight = aSize.Height();
		}
		aSize.Height() = aInitSize.Height();
		aLbEntries.Hide();
		aLbDocuments.Hide();
	}
	aWndScenarios.Hide();

	if ( pFloat )
	{
		if ( bSetSize )
			pFloat->SetOutputSizePixel( aSize );
	}
	else
	{
		SfxNavigator* pNav = (SfxNavigator*)GetParent();
		Size aFloating = pNav->GetFloatingSize();
		aFloating.Height() = aSize.Height();
		pNav->SetFloatingSize( aFloating );
	}
}

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

void ScNavigatorDlg::ShowScenarios( sal_Bool bShow, sal_Bool bSetSize )
{
	FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
	Size aSize = GetParent()->GetOutputSizePixel();

	if ( bShow )
	{
		Size aMinSize = aInitSize;
		aMinSize.Height() += nInitListHeight;
		if ( pFloat )
			pFloat->SetMinOutputSizePixel( aMinSize );
		aSize.Height() = nListModeHeight;

		rBindings.Invalidate( SID_SELECT_SCENARIO );
		rBindings.Update( SID_SELECT_SCENARIO );

		aWndScenarios.Show();
		aLbDocuments.Show();
	}
	else
	{
		if ( pFloat )
		{
			pFloat->SetMinOutputSizePixel( aInitSize );
			nListModeHeight = aSize.Height();
		}
		aSize.Height() = aInitSize.Height();
		aWndScenarios.Hide();
		aLbDocuments.Hide();
	}
	aLbEntries.Hide();

	if ( pFloat )
	{
		if ( bSetSize )
			pFloat->SetOutputSizePixel( aSize );
	}
	else
	{
		SfxNavigator* pNav = (SfxNavigator*)GetParent();
		Size aFloating = pNav->GetFloatingSize();
		aFloating.Height() = aSize.Height();
		pNav->SetFloatingSize( aFloating );
	}
}


//------------------------------------------------------------------------
//
//		Dokumente fuer Dropdown-Listbox
//
//------------------------------------------------------------------------

void ScNavigatorDlg::GetDocNames( const String* pManualSel )
{
	aLbDocuments.Clear();
	aLbDocuments.SetUpdateMode( sal_False );

	ScDocShell* pCurrentSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );

	String aSelEntry;
	SfxObjectShell* pSh = SfxObjectShell::GetFirst();
	while ( pSh )
	{
		if ( pSh->ISA(ScDocShell) )
		{
			String aName = pSh->GetTitle();
			String aEntry = aName;
			if (pSh == pCurrentSh)
				aEntry += aStrActive;
			else
				aEntry += aStrNotActive;
			aLbDocuments.InsertEntry( aEntry );

			if ( pManualSel ? ( aName == *pManualSel )
							: ( pSh == pCurrentSh ) )
				aSelEntry = aEntry;						// kompletter Eintrag zum Selektieren
		}

		pSh = SfxObjectShell::GetNext( *pSh );
	}

	aLbDocuments.InsertEntry( aStrActiveWin );

	String aHidden =  aLbEntries.GetHiddenTitle();
	if (aHidden.Len())
	{
		String aEntry = aHidden;
		aEntry += aStrHidden;
		aLbDocuments.InsertEntry( aEntry );

		if ( pManualSel && aHidden == *pManualSel )
			aSelEntry = aEntry;
	}

	aLbDocuments.SetUpdateMode( sal_True );

	aLbDocuments.SelectEntry( aSelEntry );
}

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

void ScNavigatorDlg::MarkDataArea()
{
    ScTabViewShell* pViewSh = GetTabViewShell();

	if ( pViewSh )
	{
		if ( !pMarkArea )
			pMarkArea = new	ScArea;

		pViewSh->MarkDataArea();
		ScRange aMarkRange;
		pViewSh->GetViewData()->GetMarkData().GetMarkArea(aMarkRange);
		pMarkArea->nColStart = aMarkRange.aStart.Col();
		pMarkArea->nRowStart = aMarkRange.aStart.Row();
		pMarkArea->nColEnd = aMarkRange.aEnd.Col();
		pMarkArea->nRowEnd = aMarkRange.aEnd.Row();
		pMarkArea->nTab = aMarkRange.aStart.Tab();
	}
}

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

void ScNavigatorDlg::UnmarkDataArea()
{
    ScTabViewShell* pViewSh = GetTabViewShell();

	if ( pViewSh )
	{
		pViewSh->Unmark();
		DELETEZ( pMarkArea );
	}
}

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

void ScNavigatorDlg::CheckDataArea()
{
	if ( aTbxCmd.IsItemChecked( IID_DATA ) && pMarkArea )
	{
		if (   nCurTab   != pMarkArea->nTab
			|| nCurCol <  pMarkArea->nColStart+1
			|| nCurCol >  pMarkArea->nColEnd+1
			|| nCurRow <  pMarkArea->nRowStart+1
			|| nCurRow >  pMarkArea->nRowEnd+1 )
		{
			aTbxCmd.SetItemState( IID_DATA, TriState(STATE_CHECK) );
			aTbxCmd.Select( IID_DATA );
		}
	}
}

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

void ScNavigatorDlg::StartOfDataArea()
{
	//	pMarkArea auswerten ???

	if ( GetViewData() )
	{
		ScMarkData& rMark = pViewData->GetMarkData();
		ScRange aMarkRange;
		rMark.GetMarkArea( aMarkRange );

		SCCOL nCol = aMarkRange.aStart.Col();
		SCROW nRow = aMarkRange.aStart.Row();

		if ( (nCol+1 != aEdCol.GetCol()) || (nRow+1 != aEdRow.GetRow()) )
			SetCurrentCell( nCol, nRow );
	}
}

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

void ScNavigatorDlg::EndOfDataArea()
{
	//	pMarkArea auswerten ???

	if ( GetViewData() )
	{
		ScMarkData& rMark = pViewData->GetMarkData();
		ScRange aMarkRange;
		rMark.GetMarkArea( aMarkRange );

		SCCOL nCol = aMarkRange.aEnd.Col();
		SCROW nRow = aMarkRange.aEnd.Row();

		if ( (nCol+1 != aEdCol.GetCol()) || (nRow+1 != aEdRow.GetRow()) )
			SetCurrentCell( nCol, nRow );
	}
}

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

SfxChildAlignment __EXPORT ScNavigatorDlg::CheckAlignment(
							SfxChildAlignment eActAlign, SfxChildAlignment eAlign )
{
	SfxChildAlignment eRetAlign;

	//!	kein Andocken, wenn Listbox nicht da ???

	switch (eAlign)
	{
		case SFX_ALIGN_TOP:
		case SFX_ALIGN_HIGHESTTOP:
		case SFX_ALIGN_LOWESTTOP:
		case SFX_ALIGN_BOTTOM:
		case SFX_ALIGN_LOWESTBOTTOM:
		case SFX_ALIGN_HIGHESTBOTTOM:
			eRetAlign = eActAlign;				// nicht erlaubt
			break;

		case SFX_ALIGN_LEFT:
		case SFX_ALIGN_RIGHT:
		case SFX_ALIGN_FIRSTLEFT:
		case SFX_ALIGN_LASTLEFT:
		case SFX_ALIGN_FIRSTRIGHT:
		case SFX_ALIGN_LASTRIGHT:
			eRetAlign = eAlign;					// erlaubt
			break;

		default:
			eRetAlign = eAlign;
			break;
	}
	return eRetAlign;
}

//------------------------------------------------------------------------
//
//	Drop auf den Navigator - andere Datei laden (File oder Bookmark)
//
//------------------------------------------------------------------------

#if 0
sal_Bool __EXPORT ScNavigatorDlg::Drop( const DropEvent& rEvt )
{
	sal_Bool bReturn = sal_False;

	if ( !aLbEntries.IsInDrag() )		// kein Verschieben innerhalb der TreeListBox
	{
		String aFileName;

		SvScDataObjectRef pObject = SvScDataObject::PasteDragServer(rEvt);

		sal_uLong nFormat = INetBookmark::HasFormat(*pObject);
		INetBookmark aBookmark;
		if (aBookmark.Paste(*pObject,nFormat))
			aFileName = aBookmark.GetURL();
		else
		{
			//	FORMAT_FILE direkt aus DragServer

			sal_uInt16 nCount = DragServer::GetItemCount();
			for ( sal_uInt16 i = 0; i < nCount && !aFileName.Len(); ++i )
				if (DragServer::HasFormat( i, FORMAT_FILE ))
					aFileName = DragServer::PasteFile( i );
		}

		if ( aFileName.Len() )
			bReturn = aLbEntries.LoadFile( aFileName );
	}
	return bReturn;
}

sal_Bool __EXPORT ScNavigatorDlg::QueryDrop( DropEvent& rEvt )
{
	sal_Bool bReturn = sal_False;

	if ( !aLbEntries.IsInDrag() )		// kein Verschieben innerhalb der TreeListBox
	{
		SvScDataObjectRef pObject = SvScDataObject::PasteDragServer(rEvt);
		if ( pObject->HasFormat(FORMAT_FILE)
			|| INetBookmark::HasFormat(*pObject) )
		{
			rEvt.SetAction(DROP_COPY);		// Kopier-Cursor anzeigen
			bReturn = sal_True;
		}
	}

	return bReturn;
}
#endif



