/**************************************************************
 * 
 * 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_basctl.hxx"

#include <vector>
#define _BASIC_TEXTPORTIONS
#include <basic/sbdef.hxx>
#include <ide_pch.hxx>


#include <tools/urlobj.hxx>
#include <unotools/charclass.hxx>
#include <svl/urihelper.hxx>
#include <basic/sbx.hxx>
#include <vcl/sound.hxx>
#include <svtools/xtextedt.hxx>
#include <svtools/txtattr.hxx>
#include <svtools/textwindowpeer.hxx>
#include <basic/sbuno.hxx>

#include <helpid.hrc>
#include <baside2.hrc>
#include <baside2.hxx>
#include <brkdlg.hxx>
#include <objdlg.hxx>
#include <basobj.hxx>
#include <iderdll.hxx>
#include <iderdll2.hxx>
#include <vcl/taskpanelist.hxx>
#include <vcl/help.hxx>

//#ifndef _SFX_HELP_HXX //autogen
//#include <sfx2/sfxhelp.hxx>
//#endif
#include <unotools/sourceviewconfig.hxx>

#ifndef _COM_SUN_STAR_SCRIPT_XLIBRYARYCONTAINER2_HPP_
#include <com/sun/star/script/XLibraryContainer2.hpp>
#endif
#include <comphelper/processfactory.hxx>


using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;


long nVirtToolBoxHeight;	// wird im WatchWindow init., im Stackwindow verw.
long nHeaderBarHeight;

#define SCROLL_LINE		12
#define SCROLL_PAGE		60

#define DWBORDER		3

static const char cSuffixes[] = "%&!#@$";

MapUnit eEditMapUnit = MAP_100TH_MM;


// #108672 Helper functions to get/set text in TextEngine
// using the stream interface (get/setText() only supports
// tools Strings limited to 64K).
::rtl::OUString getTextEngineText( ExtTextEngine* pEngine )
{
    SvMemoryStream aMemStream;
    aMemStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
    aMemStream.SetLineDelimiter( LINEEND_LF );
    pEngine->Write( aMemStream );
    sal_uLong nSize = aMemStream.Tell();
    ::rtl::OUString aText( (const sal_Char*)aMemStream.GetData(),
        nSize, RTL_TEXTENCODING_UTF8 );
    return aText;
}

void setTextEngineText( ExtTextEngine* pEngine, const ::rtl::OUString aStr )
{
    pEngine->SetText( String() );
    ::rtl::OString aUTF8Str = ::rtl::OUStringToOString( aStr, RTL_TEXTENCODING_UTF8 );
	SvMemoryStream aMemStream( (void*)aUTF8Str.getStr(), aUTF8Str.getLength(),
        STREAM_READ | STREAM_SEEK_TO_BEGIN );
    aMemStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
    aMemStream.SetLineDelimiter( LINEEND_LF );
	pEngine->Read( aMemStream );
}

void lcl_DrawIDEWindowFrame( DockingWindow* pWin )
{
    // The result of using explicit colors here appears to be harmless when
    // switching to high contrast mode:
	if ( !pWin->IsFloatingMode() )
	{
		Size aSz = pWin->GetOutputSizePixel();
		const Color aOldLineColor( pWin->GetLineColor() );
		pWin->SetLineColor( Color( COL_WHITE ) );
		// oben eine weisse..
		pWin->DrawLine( Point( 0, 0 ), Point( aSz.Width(), 0 ) );
		// unten eine schwarze...
		pWin->SetLineColor( Color( COL_BLACK ) );
		pWin->DrawLine( Point( 0, aSz.Height() - 1 ), Point( aSz.Width(), aSz.Height() - 1 ) );
		pWin->SetLineColor( aOldLineColor );
	}
}

void lcl_SeparateNameAndIndex( const String& rVName, String& rVar, String& rIndex )
{
	rVar = rVName;
	rIndex.Erase();
	sal_uInt16 nIndexStart = rVar.Search( '(' );
	if ( nIndexStart != STRING_NOTFOUND )
	{
		sal_uInt16 nIndexEnd = rVar.Search( ')', nIndexStart );
		if ( nIndexStart != STRING_NOTFOUND )
		{
			rIndex = rVar.Copy( nIndexStart+1, nIndexEnd-nIndexStart-1 );
			rVar.Erase( nIndexStart );
			rVar.EraseTrailingChars();
			rIndex.EraseLeadingChars();
			rIndex.EraseTrailingChars();
		}
	}

	if ( rVar.Len() )
	{
		sal_uInt16 nLastChar = rVar.Len()-1;
		if ( strchr( cSuffixes, rVar.GetChar( nLastChar ) ) )
			rVar.Erase( nLastChar, 1 );
	}
	if ( rIndex.Len() )
	{
		sal_uInt16 nLastChar = rIndex.Len()-1;
		if ( strchr( cSuffixes, rIndex.GetChar( nLastChar ) ) )
			rIndex.Erase( nLastChar, 1 );
	}
}


EditorWindow::EditorWindow( Window* pParent ) :
	Window( pParent, WB_BORDER )
{
	bDoSyntaxHighlight = sal_True;
	bDelayHighlight = sal_True;
	pModulWindow = 0;
	pEditView = 0;
	pEditEngine = 0;
    pSourceViewConfig = new utl::SourceViewConfig;
	bHighlightning = sal_False;
	pProgress = 0;
	nCurTextWidth = 0;
	SetBackground(
        Wallpaper(GetSettings().GetStyleSettings().GetFieldColor()));
	SetPointer( Pointer( POINTER_TEXT ) );

	SetHelpId( HID_BASICIDE_EDITORWINDOW );
    pSourceViewConfig->AddListener(this);
}



__EXPORT EditorWindow::~EditorWindow()
{
    pSourceViewConfig->RemoveListener(this);
    delete pSourceViewConfig;

	aSyntaxIdleTimer.Stop();

	if ( pEditEngine )
	{
		EndListening( *pEditEngine );
		pEditEngine->RemoveView( pEditView );
//		pEditEngine->SetViewWin( 0 );
		delete pEditView;
		delete pEditEngine;
	}
}

String EditorWindow::GetWordAtCursor()
{
    String aWord;

    if ( pEditView )
    {
        TextEngine* pTextEngine = pEditView->GetTextEngine();
        if ( pTextEngine )
        {
            // check first, if the cursor is at a help URL
            const TextSelection& rSelection = pEditView->GetSelection();
            const TextPaM& rSelStart = rSelection.GetStart();
            const TextPaM& rSelEnd = rSelection.GetEnd();
            String aText = pTextEngine->GetText( rSelEnd.GetPara() );
            CharClass aClass( ::comphelper::getProcessServiceFactory() , Application::GetSettings().GetLocale() );
            xub_StrLen nSelStart = static_cast< xub_StrLen >( rSelStart.GetIndex() );
            xub_StrLen nSelEnd = static_cast< xub_StrLen >( rSelEnd.GetIndex() );
            xub_StrLen nLength = static_cast< xub_StrLen >( aText.Len() );
            xub_StrLen nStart = 0;
            xub_StrLen nEnd = nLength;
            while ( nStart < nLength )
            {
                String aURL( URIHelper::FindFirstURLInText( aText, nStart, nEnd, aClass ) );
	            INetURLObject aURLObj( aURL );
                if ( aURLObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP
                     && nSelStart >= nStart && nSelStart <= nEnd && nSelEnd >= nStart && nSelEnd <= nEnd )
                {
                    aWord = aURL;
                    break;
                }
                nStart = nEnd;
                nEnd = nLength;
            }

            // Nicht den Selektierten Bereich, sondern an der CursorPosition,
            // falls Teil eines Worts markiert.
            if ( !aWord.Len() )
                aWord = pTextEngine->GetWord( rSelEnd );

            // Kann leer sein, wenn komplettes Word markiert, da Cursor dahinter.
            if ( !aWord.Len() && pEditView->HasSelection() )
                aWord = pTextEngine->GetWord( rSelStart );
        }
    }

    return aWord;
}

void __EXPORT EditorWindow::RequestHelp( const HelpEvent& rHEvt )
{
    sal_Bool bDone = sal_False;

	// Sollte eigentlich mal aktiviert werden...
	if ( pEditEngine )
	{
        if ( rHEvt.GetMode() & HELPMODE_CONTEXT )
		{
			String aKeyword = GetWordAtCursor();
			Application::GetHelp()->SearchKeyword( aKeyword );
            bDone = sal_True;
        }
		else if ( rHEvt.GetMode() & HELPMODE_QUICK )
		{
			String aHelpText;
			Point aTopLeft;
			if ( StarBASIC::IsRunning() )
			{
				Point aWindowPos = rHEvt.GetMousePosPixel();
				aWindowPos = ScreenToOutputPixel( aWindowPos );
				Point aDocPos = GetEditView()->GetDocPos( aWindowPos );
				TextPaM aCursor = GetEditView()->GetTextEngine()->GetPaM( aDocPos, sal_False );
				TextPaM aStartOfWord;
				String aWord = GetEditView()->GetTextEngine()->GetWord( aCursor, &aStartOfWord );
				if ( aWord.Len() && !ByteString( aWord, RTL_TEXTENCODING_UTF8 ).IsNumericAscii() )
				{
					sal_uInt16 nLastChar =aWord.Len()-1;
					if ( strchr( cSuffixes, aWord.GetChar( nLastChar ) ) )
						aWord.Erase( nLastChar, 1 );
					SbxBase* pSBX = StarBASIC::FindSBXInCurrentScope( aWord );
					if ( pSBX && dynamic_cast< SbxVariable* >(pSBX) && !dynamic_cast< SbxMethod* >(pSBX) )
					{
						SbxVariable* pVar = (SbxVariable*)pSBX;
						SbxDataType eType = pVar->GetType();
						if ( (sal_uInt8)eType == (sal_uInt8)SbxOBJECT )
							// Kann zu Absturz, z.B. bei Selections-Objekt fuehren
							// Type == Object heisst nicht, dass pVar == Object!
							; // aHelpText = ((SbxObject*)pVar)->GetClassName();
						else if ( eType & SbxARRAY )
							; // aHelpText = "{...}";
						else if ( (sal_uInt8)eType != (sal_uInt8)SbxEMPTY )
						{
							aHelpText = pVar->GetName();
							if ( !aHelpText.Len() ) 	// Bei Uebergabeparametern wird der Name nicht kopiert
								aHelpText = aWord;
							aHelpText += '=';
							aHelpText += pVar->GetString();
						}
					}
					if ( aHelpText.Len() )
					{
						aTopLeft = GetEditView()->GetTextEngine()->PaMtoEditCursor( aStartOfWord ).BottomLeft();
						aTopLeft = GetEditView()->GetWindowPos( aTopLeft );
						aTopLeft.X() += 5;
						aTopLeft.Y() += 5;
						aTopLeft = OutputToScreenPixel( aTopLeft );
					}
				}
			}
			Help::ShowQuickHelp( this, Rectangle( aTopLeft, Size( 1, 1 ) ), aHelpText, QUICKHELP_TOP|QUICKHELP_LEFT);
            bDone = sal_True;
		}
	}

    if ( !bDone )
        Window::RequestHelp( rHEvt );
}


void __EXPORT EditorWindow::Resize()
{
	// ScrollBars, etc. passiert in Adjust...
	if ( pEditView )
	{
		long nVisY = pEditView->GetStartDocPos().Y();
//		pEditView->SetOutputArea( Rectangle( Point( 0, 0 ), GetOutputSize() ) );
		pEditView->ShowCursor();
		Size aOutSz( GetOutputSizePixel() );
		long nMaxVisAreaStart = pEditView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
		if ( nMaxVisAreaStart < 0 )
			nMaxVisAreaStart = 0;
		if ( pEditView->GetStartDocPos().Y() > nMaxVisAreaStart )
		{
			Point aStartDocPos( pEditView->GetStartDocPos() );
			aStartDocPos.Y() = nMaxVisAreaStart;
			pEditView->SetStartDocPos( aStartDocPos );
			pEditView->ShowCursor();
			pModulWindow->GetBreakPointWindow().GetCurYOffset() = aStartDocPos.Y();
		}
		InitScrollBars();
		if ( nVisY != pEditView->GetStartDocPos().Y() )
			Invalidate();
	}
}



void __EXPORT EditorWindow::MouseMove( const MouseEvent &rEvt )
{
	if ( pEditView )
		pEditView->MouseMove( rEvt );
}



void __EXPORT EditorWindow::MouseButtonUp( const MouseEvent &rEvt )
{
	if ( pEditView )
	{
		pEditView->MouseButtonUp( rEvt );
        SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
        if ( pBindings )
        {
            pBindings->Invalidate( SID_COPY );
            pBindings->Invalidate( SID_CUT );
            pBindings->Invalidate( SID_BASICIDE_STAT_POS );
        }
	}
}

void __EXPORT EditorWindow::MouseButtonDown( const MouseEvent &rEvt )
{
	GrabFocus();
	if ( pEditView )
	{
		pEditView->MouseButtonDown( rEvt );
	}
}

void __EXPORT EditorWindow::Command( const CommandEvent& rCEvt )
{
	if ( pEditView )
	{
		pEditView->Command( rCEvt );
		if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
			 ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
			 ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
		{
			HandleScrollCommand( rCEvt, pModulWindow->GetHScrollBar(), &pModulWindow->GetEditVScrollBar() );
		} else if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU ) {
            BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
            SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
            SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
            if ( pDispatcher )
            {
                pDispatcher->ExecutePopup();
            }
        }
	}
}

sal_Bool EditorWindow::ImpCanModify()
{
	sal_Bool bCanModify = sal_True;
	if ( StarBASIC::IsRunning() )
	{
		// Wenn im Trace-Mode, entweder Trace abbrechen oder
		// Eingabe verweigern
		// Im Notify bei Basic::Stoped die Markierungen in den Modulen
		// entfernen!
		if ( QueryBox( 0, WB_OK_CANCEL, String( IDEResId( RID_STR_WILLSTOPPRG ) ) ).Execute() == RET_OK )
		{
			pModulWindow->GetBasicStatus().bIsRunning = sal_False;
			BasicIDE::StopBasic();
		}
		else
			bCanModify = sal_False;
	}
	return bCanModify;
}

void __EXPORT EditorWindow::KeyInput( const KeyEvent& rKEvt )
{
	if ( !pEditView )	// Passiert unter W95 bei letzte Version, Ctrl-Tab
		return;

#if OSL_DEBUG_LEVEL > 1
    Range aRange = pModulWindow->GetHScrollBar()->GetRange(); (void)aRange;
    long nVisSz = pModulWindow->GetHScrollBar()->GetVisibleSize(); (void)nVisSz;
    long nPapSz = pModulWindow->GetHScrollBar()->GetPageSize(); (void)nPapSz;
    long nLinSz = pModulWindow->GetHScrollBar()->GetLineSize(); (void)nLinSz;
    long nThumb = pModulWindow->GetHScrollBar()->GetThumbPos(); (void)nThumb;
#endif
	sal_Bool bDone = sal_False;
	sal_Bool bWasModified = pEditEngine->IsModified();
	if ( !TextEngine::DoesKeyChangeText( rKEvt ) || ImpCanModify() )
	{
		if ( ( rKEvt.GetKeyCode().GetCode() == KEY_Y ) && rKEvt.GetKeyCode().IsMod1() )
			bDone = sal_True; // CTRL-Y schlucken, damit kein Vorlagenkatalog
		else
		{
			if ( ( rKEvt.GetKeyCode().GetCode() == KEY_TAB ) && !rKEvt.GetKeyCode().IsMod1() &&
				  !rKEvt.GetKeyCode().IsMod2() && !GetEditView()->IsReadOnly() )
			{
				TextSelection aSel( pEditView->GetSelection() );
				if ( aSel.GetStart().GetPara() != aSel.GetEnd().GetPara() )
				{
					bDelayHighlight = sal_False;
					if ( !rKEvt.GetKeyCode().IsShift() )
						pEditView->IndentBlock();
					else
						pEditView->UnindentBlock();
					bDelayHighlight = sal_True;
					bDone = sal_True;
				}
			}
			if ( !bDone )
				bDone = pEditView->KeyInput( rKEvt );
		}
	}
	if ( !bDone )
	{
		if ( !SfxViewShell::Current()->KeyInput( rKEvt ) )
			Window::KeyInput( rKEvt );
	}
	else
	{
        SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
        if ( pBindings )
        {
            pBindings->Invalidate( SID_CUT );
            pBindings->Invalidate( SID_COPY );
            pBindings->Invalidate( SID_BASICIDE_STAT_POS );

            if ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_CURSOR )
                pBindings->Update( SID_BASICIDE_STAT_POS );

            if ( !bWasModified && pEditEngine->IsModified() )
            {
                pBindings->Invalidate( SID_SAVEDOC );
                pBindings->Invalidate( SID_DOC_MODIFIED );
                pBindings->Invalidate( SID_UNDO );
            }

            if ( rKEvt.GetKeyCode().GetCode() == KEY_INSERT )
                pBindings->Invalidate( SID_ATTR_INSERT );
        }
	}
}

void __EXPORT EditorWindow::Paint( const Rectangle& rRect )
{
	if ( !pEditEngine )		// spaetestens jetzt brauche ich sie...
		CreateEditEngine();

	pEditView->Paint( rRect );
}

void __EXPORT EditorWindow::LoseFocus()
{
	SetSourceInBasic();
	Window::LoseFocus();
}

sal_Bool EditorWindow::SetSourceInBasic( sal_Bool bQuiet )
{
	(void)bQuiet;

	sal_Bool bChanged = sal_False;
	if ( pEditEngine && pEditEngine->IsModified()
		&& !GetEditView()->IsReadOnly() )	// Added because of #i60626, otherwise
			// any read only bug in the text engine could lead to a crash later
	{
        if ( !StarBASIC::IsRunning() ) // Nicht zur Laufzeit!
		{
            ::rtl::OUString aModule = getTextEngineText( pEditEngine );

            // update module in basic
#ifdef DBG_UTIL
            SbModule* pModule = pModulWindow->GetSbModule();
#endif
            DBG_ASSERT(pModule, "EditorWindow::SetSourceInBasic: No Module found!");

            // update module in module window
            pModulWindow->SetModule( aModule );

            // update module in library
            ScriptDocument aDocument( pModulWindow->GetDocument() );
            String aLibName = pModulWindow->GetLibName();
	        String aName = pModulWindow->GetName();
            OSL_VERIFY( aDocument.updateModule( aLibName, aName, aModule ) );

            pEditEngine->SetModified( sal_False );
            BasicIDE::MarkDocumentModified( aDocument );
            bChanged = sal_True;
		}
	}
	return bChanged;
}


// Returns the position of the last character of any of the following
// EOL char combinations: CR, CR/LF, LF, return -1 if no EOL is found
sal_Int32 searchEOL( const ::rtl::OUString& rStr, sal_Int32 fromIndex )
{
	sal_Int32 iRetPos = -1;

	sal_Int32 iLF = rStr.indexOf( LINE_SEP, fromIndex );
	if( iLF != -1 )
	{
		iRetPos = iLF;
	}
	else
	{
		iRetPos = rStr.indexOf( LINE_SEP_CR, fromIndex );
	}
	return iRetPos;
}


void EditorWindow::CreateEditEngine()
{
	if ( pEditEngine )
		return;

	pEditEngine = new ExtTextEngine;
	pEditView = new ExtTextView( pEditEngine, this );
	pEditView->SetAutoIndentMode( sal_True );
	pEditEngine->SetUpdateMode( sal_False );
	pEditEngine->InsertView( pEditView );

	ImplSetFont();

	aSyntaxIdleTimer.SetTimeout( 200 );
	aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, EditorWindow, SyntaxTimerHdl ) );

	aHighlighter.initialize( HIGHLIGHT_BASIC );

	sal_Bool bWasDoSyntaxHighlight = bDoSyntaxHighlight;
	bDoSyntaxHighlight = sal_False;	// Bei grossen Texten zu langsam...
    ::rtl::OUString aOUSource( pModulWindow->GetModule() );
	sal_Int32 nLines = 0;
    sal_Int32 nIndex = -1;
    do
    {
        nLines++;
		nIndex = searchEOL( aOUSource, nIndex+1 );
    }
    while ( nIndex >= 0 );

	// nLines*4: SetText+Formatting+DoHighlight+Formatting
	// 1 Formatting koennte eingespart werden, aber dann wartet man
	// bei einem langen Sourcecode noch laenger auf den Text...
	pProgress = new ProgressInfo( IDE_DLL()->GetShell()->GetViewFrame()->GetObjectShell(), String( IDEResId( RID_STR_GENERATESOURCE ) ), nLines*4 );
    setTextEngineText( pEditEngine, aOUSource );

	pEditView->SetStartDocPos( Point( 0, 0 ) );
	pEditView->SetSelection( TextSelection() );
	pModulWindow->GetBreakPointWindow().GetCurYOffset() = 0;
	pEditEngine->SetUpdateMode( sal_True );
	Update();	// Es wurde bei UpdateMode = sal_True nur Invalidiert

	// Die anderen Fenster auch, damit keine halben Sachen auf dem Bildschirm!
	pModulWindow->GetLayout()->GetWatchWindow().Update();
	pModulWindow->GetLayout()->GetStackWindow().Update();
	pModulWindow->GetBreakPointWindow().Update();

	pEditView->ShowCursor( sal_True, sal_True );

	StartListening( *pEditEngine );

	// Das Syntax-Highlightning legt ein rel. groesse VDev an.
	aSyntaxIdleTimer.Stop();
	bDoSyntaxHighlight = bWasDoSyntaxHighlight;


	for ( sal_uInt16 nLine = 0; nLine < nLines; nLine++ )
		aSyntaxLineTable.Insert( nLine, (void*)(sal_uInt16)1 );
	ForceSyntaxTimeout();

	DELETEZ( pProgress );

	pEditView->EraseVirtualDevice();
	pEditEngine->SetModified( sal_False );
	pEditEngine->EnableUndo( sal_True );

	InitScrollBars();

    SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
    if ( pBindings )
        pBindings->Invalidate( SID_BASICIDE_STAT_POS );

	DBG_ASSERT( pModulWindow->GetBreakPointWindow().GetCurYOffset() == 0, "CreateEditEngine: Brechpunkte verschoben?" );

    // set readonly mode for readonly libraries
    ScriptDocument aDocument( pModulWindow->GetDocument() );
    ::rtl::OUString aOULibName( pModulWindow->GetLibName() );
    Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
    if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && xModLibContainer->isLibraryReadOnly( aOULibName ) )
    {
        pModulWindow->SetReadOnly( sal_True );
    }

    if ( aDocument.isDocument() && aDocument.isReadOnly() )
		pModulWindow->SetReadOnly( sal_True );
}

// virtual
void EditorWindow::DataChanged(DataChangedEvent const & rDCEvt)
{
    Window::DataChanged(rDCEvt);
    if (rDCEvt.GetType() == DATACHANGED_SETTINGS
        && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
    {
        Color aColor(GetSettings().GetStyleSettings().GetFieldColor());
        if (aColor
            != rDCEvt.GetOldSettings()->GetStyleSettings().GetFieldColor())
        {
            SetBackground(Wallpaper(aColor));
            Invalidate();
        }
        if (pEditEngine != 0)
        {
            aColor = GetSettings().GetStyleSettings().GetFieldTextColor();
            if (aColor != rDCEvt.GetOldSettings()->
                GetStyleSettings().GetFieldTextColor())
            {
                Font aFont(pEditEngine->GetFont());
                aFont.SetColor(aColor);
                pEditEngine->SetFont(aFont);
            }
        }
    }
}

void EditorWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
{
	const TextHint* pTextHint = dynamic_cast< const TextHint* >(&rHint);

	if ( pTextHint )
	{
		if( pTextHint->GetId() == TEXT_HINT_VIEWSCROLLED )
		{
			if ( pModulWindow->GetHScrollBar() )
				pModulWindow->GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
			pModulWindow->GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
			pModulWindow->GetBreakPointWindow().DoScroll
				( 0, pModulWindow->GetBreakPointWindow().GetCurYOffset() - pEditView->GetStartDocPos().Y() );
		}
		else if( pTextHint->GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
		{
			if ( pEditView->GetStartDocPos().Y() )
			{
				long nOutHeight = GetOutputSizePixel().Height();
				long nTextHeight = pEditEngine->GetTextHeight();
				if ( nTextHeight < nOutHeight )
					pEditView->Scroll( 0, pEditView->GetStartDocPos().Y() );
			}

			SetScrollBarRanges();
		}
		else if( pTextHint->GetId() == TEXT_HINT_TEXTFORMATTED )
		{
			if ( pModulWindow->GetHScrollBar() )
			{
				sal_uLong nWidth = pEditEngine->CalcTextWidth();
				if ( (long)nWidth != nCurTextWidth )
				{
					nCurTextWidth = nWidth;
					pModulWindow->GetHScrollBar()->SetRange( Range( 0, (long)nCurTextWidth-1) );
					pModulWindow->GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
				}
			}
			long nPrevTextWidth = nCurTextWidth;
			nCurTextWidth = pEditEngine->CalcTextWidth();
			if ( nCurTextWidth != nPrevTextWidth )
				SetScrollBarRanges();
		}
		else if( pTextHint->GetId() == TEXT_HINT_PARAINSERTED )
		{
			ParagraphInsertedDeleted( pTextHint->GetValue(), sal_True );
			DoDelayedSyntaxHighlight( pTextHint->GetValue() );
		}
		else if( pTextHint->GetId() == TEXT_HINT_PARAREMOVED )
		{
			ParagraphInsertedDeleted( pTextHint->GetValue(), sal_False );
		}
		else if( pTextHint->GetId() == TEXT_HINT_PARACONTENTCHANGED )
		{
			DoDelayedSyntaxHighlight( pTextHint->GetValue() );
		}
	}
}

void EditorWindow::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 )
{
    ImplSetFont();
}

void EditorWindow::SetScrollBarRanges()
{
	// Extra-Methode, nicht InitScrollBars, da auch fuer EditEngine-Events.
	if ( !pEditEngine )
		return;

	if ( pModulWindow->GetHScrollBar() )
		pModulWindow->GetHScrollBar()->SetRange( Range( 0, nCurTextWidth-1 ) );

	pModulWindow->GetEditVScrollBar().SetRange( Range( 0, pEditEngine->GetTextHeight()-1 ) );
}

void EditorWindow::InitScrollBars()
{
	if ( !pEditEngine )
		return;

	SetScrollBarRanges();
	Size aOutSz( GetOutputSizePixel() );
	pModulWindow->GetEditVScrollBar().SetVisibleSize( aOutSz.Height() );
	pModulWindow->GetEditVScrollBar().SetPageSize( aOutSz.Height() * 8 / 10 );
	pModulWindow->GetEditVScrollBar().SetLineSize( GetTextHeight() );
	pModulWindow->GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
	pModulWindow->GetEditVScrollBar().Show();

	if ( pModulWindow->GetHScrollBar() )
	{
		pModulWindow->GetHScrollBar()->SetVisibleSize( aOutSz.Width() );
		pModulWindow->GetHScrollBar()->SetPageSize( aOutSz.Width() * 8 / 10 );
		pModulWindow->GetHScrollBar()->SetLineSize( GetTextWidth( 'x' ) );
		pModulWindow->GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
		pModulWindow->GetHScrollBar()->Show();
	}
}

void EditorWindow::ImpDoHighlight( sal_uLong nLine )
{
	if ( bDoSyntaxHighlight )
	{
		String aLine( pEditEngine->GetText( nLine ) );
		Range aChanges = aHighlighter.notifyChange( nLine, 0, &aLine, 1 );
		if ( aChanges.Len() )
		{
			for ( long n = aChanges.Min() + 1; n <= aChanges.Max(); n++ )
				aSyntaxLineTable.Insert( n, (void*)(sal_uLong)1 );
			aSyntaxIdleTimer.Start();
		}

		sal_Bool bWasModified = pEditEngine->IsModified();
		pEditEngine->RemoveAttribs( nLine, sal_True );
		HighlightPortions aPortions;
		aHighlighter.getHighlightPortions( nLine, aLine, aPortions );

		for ( size_t i = 0; i < aPortions.size(); i++ )
		{
			HighlightPortion& r = aPortions[i];
			const Color& rColor = ((ModulWindowLayout*)pModulWindow->GetLayoutWindow())->getSyntaxColor(r.tokenType);
			pEditEngine->SetAttrib( TextAttribFontColor( rColor ), nLine, r.nBegin, r.nEnd, sal_True );
		}

		// Das Highlighten soll kein Modify setzen
		pEditEngine->SetModified( bWasModified );
	}
}

void EditorWindow::ImplSetFont()
{
    if ( pSourceViewConfig )
	{
		String sFontName = pSourceViewConfig->GetFontName();
		if ( !sFontName.Len() )
		{
			Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, Application::GetSettings().GetUILanguage(), 0 , this ) );
			sFontName = aTmpFont.GetName();
		}
		Size aFontSize( 0, pSourceViewConfig->GetFontHeight() );
		Font aFont( sFontName, aFontSize );
		aFont.SetColor( GetSettings().GetStyleSettings().GetFieldTextColor() );
		SetPointFont( aFont );
		aFont = GetFont();

		if ( pModulWindow )
			pModulWindow->GetBreakPointWindow().SetFont( aFont );

		if ( pEditEngine )
		{
			sal_Bool bModified = pEditEngine->IsModified();
			pEditEngine->SetFont( aFont );
			pEditEngine->SetModified( bModified );
		}
	}
}

void EditorWindow::DoSyntaxHighlight( sal_uLong nPara )
{
	// Durch das DelayedSyntaxHighlight kann es passieren,
	// dass die Zeile nicht mehr existiert!
	if ( nPara < pEditEngine->GetParagraphCount() )
	{
		// leider weis ich nicht, ob genau diese Zeile Modified() ...
		if ( pProgress )
			pProgress->StepProgress();
		ImpDoHighlight( nPara );
	}
}

void EditorWindow::DoDelayedSyntaxHighlight( sal_uLong nPara )
{
	// Zeile wird nur in 'Liste' aufgenommen, im TimerHdl abgearbeitet.
	// => Nicht Absaetze manipulieren, waehrend EditEngine formatiert.
	if ( pProgress )
		pProgress->StepProgress();

	if ( !bHighlightning && bDoSyntaxHighlight )
	{
		if ( bDelayHighlight )
		{
			aSyntaxLineTable.Insert( nPara, (void*)(sal_uLong)1 );
			aSyntaxIdleTimer.Start();
		}
		else
			DoSyntaxHighlight( nPara );
	}
}

IMPL_LINK( EditorWindow, SyntaxTimerHdl, Timer *, EMPTYARG )
{
	DBG_ASSERT( pEditView, "Noch keine View, aber Syntax-Highlight ?!" );

	sal_Bool bWasModified = pEditEngine->IsModified();
	// pEditEngine->SetUpdateMode( sal_False );

	bHighlightning = sal_True;
	sal_uInt16 nLine;
	void* p = aSyntaxLineTable.First();
	while ( p )
	{
		nLine = (sal_uInt16)aSyntaxLineTable.GetCurKey();
		DoSyntaxHighlight( nLine );
		p = aSyntaxLineTable.Next();
	}

    // MT: Removed, because of idle format now when set/remove attribs...
    // pEditView->SetAutoScroll( sal_False );  // #101043# Don't scroll because of syntax highlight
    // pEditEngine->SetUpdateMode( sal_True );
	// pEditView->ShowCursor( sal_False, sal_True );
    // pEditView->SetAutoScroll( sal_True );

    // #i45572#
    if ( pEditView )
        pEditView->ShowCursor( sal_False, sal_True );

	pEditEngine->SetModified( bWasModified );

	aSyntaxLineTable.Clear();
	bHighlightning = sal_False;

	return 0;
}

void EditorWindow::ParagraphInsertedDeleted( sal_uLong nPara, sal_Bool bInserted )
{
	if ( pProgress )
		pProgress->StepProgress();

	if ( !bInserted && ( nPara == TEXT_PARA_ALL ) )
	{
		pModulWindow->GetBreakPoints().reset();
		pModulWindow->GetBreakPointWindow().Invalidate();
		aHighlighter.initialize( HIGHLIGHT_BASIC );
	}
	else
	{
		// Brechpunkte Aktualisieren...
		// keine Sonderbehandlung fuer EditEngine-CTOR ( Erste-Zeile-Problem ),
		// da in diesem Moment noch keine BreakPoints.
		// +1: Basic-Zeilen beginnen bei 1!
		pModulWindow->GetBreakPoints().AdjustBreakPoints( (sal_uInt16)nPara+1, bInserted );

		// Im BreakPointWindow invalidieren...
		long nLineHeight = GetTextHeight();
		Size aSz = pModulWindow->GetBreakPointWindow().GetOutputSize();
		Rectangle aInvRec( Point( 0, 0 ), aSz );
		long nY = nPara*nLineHeight - pModulWindow->GetBreakPointWindow().GetCurYOffset();
		aInvRec.Top() = nY;
		pModulWindow->GetBreakPointWindow().Invalidate( aInvRec );

		if ( bDoSyntaxHighlight )
		{
			String aDummy;
			aHighlighter.notifyChange( nPara, bInserted ? 1 : (-1), &aDummy, 1 );
		}
	}
}

void EditorWindow::CreateProgress( const String& rText, sal_uLong nRange )
{
	DBG_ASSERT( !pProgress, "ProgressInfo existiert schon" );
	pProgress = new ProgressInfo( IDE_DLL()->GetShell()->GetViewFrame()->GetObjectShell(), rText, nRange );
}

void EditorWindow::DestroyProgress()
{
	DELETEZ( pProgress );
}

void EditorWindow::ForceSyntaxTimeout()
{
	aSyntaxIdleTimer.Stop();
	((Link&)aSyntaxIdleTimer.GetTimeoutHdl()).Call( &aSyntaxIdleTimer );
}



BreakPointWindow::BreakPointWindow( Window* pParent ) :
	Window( pParent, WB_BORDER )
{
	pModulWindow = 0;
	nCurYOffset = 0;
    setBackgroundColor(GetSettings().GetStyleSettings().GetFieldColor());
    m_bHighContrastMode = GetSettings().GetStyleSettings().GetHighContrastMode();
	nMarkerPos = MARKER_NOMARKER;

	// nCurYOffset merken und nicht von EditEngine holen.
	// Falls in EditEngine autom. gescrollt wurde, wuesste ich sonst nicht,
	// wo ich gerade stehe.

	SetHelpId( HID_BASICIDE_BREAKPOINTWINDOW );
}



__EXPORT BreakPointWindow::~BreakPointWindow()
{
}



void __EXPORT BreakPointWindow::Resize()
{
///	Invalidate();
}



void __EXPORT BreakPointWindow::Paint( const Rectangle& )
{
	if ( SyncYOffset() )
		return;

	Size aOutSz( GetOutputSize() );
	long nLineHeight = GetTextHeight();

	Image aBrk1(((ModulWindowLayout *) pModulWindow->GetLayoutWindow())->
                getImage(IMGID_BRKENABLED, m_bHighContrastMode));
	Image aBrk0(((ModulWindowLayout *) pModulWindow->GetLayoutWindow())->
                getImage(IMGID_BRKDISABLED, m_bHighContrastMode));
	Size aBmpSz( aBrk1.GetSizePixel() );
	aBmpSz = PixelToLogic( aBmpSz );
	Point aBmpOff( 0, 0 );
	aBmpOff.X() = ( aOutSz.Width() - aBmpSz.Width() ) / 2;
	aBmpOff.Y() = ( nLineHeight - aBmpSz.Height() ) / 2;

	BreakPoint* pBrk = GetBreakPoints().First();
	while ( pBrk )
	{
		sal_uLong nLine = pBrk->nLine-1;
		sal_uLong nY = nLine*nLineHeight - nCurYOffset;
		DrawImage( Point( 0, nY ) + aBmpOff, pBrk->bEnabled ? aBrk1 : aBrk0 );
		pBrk = GetBreakPoints().Next();
	}
	ShowMarker( sal_True );
}



void BreakPointWindow::DoScroll( long nHorzScroll, long nVertScroll )
{
	nCurYOffset -= nVertScroll;
	Window::Scroll( nHorzScroll, nVertScroll );
}



void BreakPointWindow::SetMarkerPos( sal_uInt16 nLine, sal_Bool bError )
{
	if ( SyncYOffset() )
		Update();

	ShowMarker( sal_False );	// Alten wegzeichen...
	nMarkerPos = nLine;
	bErrorMarker = bError;
	ShowMarker( sal_True );		// Neuen zeichnen...
}

void BreakPointWindow::ShowMarker( sal_Bool bShow )
{
	if ( nMarkerPos == MARKER_NOMARKER )
		return;

	Size aOutSz( GetOutputSize() );
	long nLineHeight = GetTextHeight();

	Image aMarker(((ModulWindowLayout*)pModulWindow->GetLayoutWindow())->
                  getImage(bErrorMarker
                           ? IMGID_ERRORMARKER : IMGID_STEPMARKER,
                           m_bHighContrastMode));

	Size aMarkerSz( aMarker.GetSizePixel() );
	aMarkerSz = PixelToLogic( aMarkerSz );
	Point aMarkerOff( 0, 0 );
	aMarkerOff.X() = ( aOutSz.Width() - aMarkerSz.Width() ) / 2;
	aMarkerOff.Y() = ( nLineHeight - aMarkerSz.Height() ) / 2;

	sal_uLong nY = nMarkerPos*nLineHeight - nCurYOffset;
	Point aPos( 0, nY );
	aPos += aMarkerOff;
	if ( bShow )
		DrawImage( aPos, aMarker );
	else
		Invalidate( Rectangle( aPos, aMarkerSz ) );
}




BreakPoint*	BreakPointWindow::FindBreakPoint( const Point& rMousePos )
{
	long nLineHeight = GetTextHeight();
	long nYPos = rMousePos.Y() + nCurYOffset;
//	Image aBrk( ((ModulWindowLayout*)pModulWindow->GetLayoutWindow())->GetImage( IMGID_BRKENABLED ) );
//	Size aBmpSz( aBrk.GetSizePixel() );
//	aBmpSz = PixelToLogic( aBmpSz );

	BreakPoint* pBrk = GetBreakPoints().First();
	while ( pBrk )
	{
		sal_uLong nLine = pBrk->nLine-1;
		long nY = nLine*nLineHeight;
		if ( ( nYPos > nY ) && ( nYPos < ( nY + nLineHeight ) ) )
			return pBrk;
		pBrk = GetBreakPoints().Next();
	}
	return 0;
}

void __EXPORT BreakPointWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
	if ( rMEvt.GetClicks() == 2 )
	{
		Point aMousePos( PixelToLogic( rMEvt.GetPosPixel() ) );
		long nLineHeight = GetTextHeight();
		long nYPos = aMousePos.Y() + nCurYOffset;
		long nLine = nYPos / nLineHeight + 1;
		pModulWindow->ToggleBreakPoint( (sal_uLong)nLine );
		// vielleicht mal etwas genauer...
		Invalidate();
	}
}



void __EXPORT BreakPointWindow::Command( const CommandEvent& rCEvt )
{
	if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
	{
		Point aPos( rCEvt.IsMouseEvent() ? rCEvt.GetMousePosPixel() : Point(1,1) );
		Point aEventPos( PixelToLogic( aPos ) );
		BreakPoint* pBrk = rCEvt.IsMouseEvent() ? FindBreakPoint( aEventPos ) : 0;
		if ( pBrk )
		{
			// prueffen, ob Brechpunkt enabled....
			PopupMenu aBrkPropMenu( IDEResId( RID_POPUP_BRKPROPS ) );
			aBrkPropMenu.CheckItem( RID_ACTIV, pBrk->bEnabled );
			switch ( aBrkPropMenu.Execute( this, aPos ) )
			{
				case RID_ACTIV:
				{
					pBrk->bEnabled = pBrk->bEnabled ? sal_False : sal_True;
					pModulWindow->UpdateBreakPoint( *pBrk );
					Invalidate();
				}
				break;
				case RID_BRKPROPS:
				{
					BreakPointDialog aBrkDlg( this, GetBreakPoints() );
					aBrkDlg.SetCurrentBreakPoint( pBrk );
					aBrkDlg.Execute();
					Invalidate();
				}
				break;
			}
		}
		else
		{
			PopupMenu aBrkListMenu( IDEResId( RID_POPUP_BRKDLG ) );
			switch ( aBrkListMenu.Execute( this, aPos ) )
			{
				case RID_BRKDLG:
				{
					BreakPointDialog aBrkDlg( this, GetBreakPoints() );
					aBrkDlg.Execute();
					Invalidate();
				}
				break;
			}
		}
	}
}

sal_Bool BreakPointWindow::SyncYOffset()
{
	TextView* pView = pModulWindow->GetEditView();
	if ( pView )
	{
		long nViewYOffset = pView->GetStartDocPos().Y();
		if ( nCurYOffset != nViewYOffset )
		{
			nCurYOffset = nViewYOffset;
			Invalidate();
			return sal_True;
		}
	}
	return sal_False;
}

// virtual
void BreakPointWindow::DataChanged(DataChangedEvent const & rDCEvt)
{
    Window::DataChanged(rDCEvt);
    if (rDCEvt.GetType() == DATACHANGED_SETTINGS
        && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
    {
        Color aColor(GetSettings().GetStyleSettings().GetFieldColor());
        if (aColor
            != rDCEvt.GetOldSettings()->GetStyleSettings().GetFieldColor())
        {
            setBackgroundColor(aColor);
            m_bHighContrastMode = GetSettings().GetStyleSettings().GetHighContrastMode();
            Invalidate();
        }
    }
}

void BreakPointWindow::setBackgroundColor(Color aColor)
{
	SetBackground(Wallpaper(aColor));
}


const sal_uInt16 ITEM_ID_VARIABLE = 1;
const sal_uInt16 ITEM_ID_VALUE = 2;
const sal_uInt16 ITEM_ID_TYPE = 3;

WatchWindow::WatchWindow( Window* pParent ) :
	BasicDockingWindow( pParent ),
	aWatchStr( IDEResId( RID_STR_REMOVEWATCH ) ),
	aXEdit( this, IDEResId( RID_EDT_WATCHEDIT ) ),
	aRemoveWatchButton( this, IDEResId( RID_IMGBTN_REMOVEWATCH ) ),
	aTreeListBox( this, WB_BORDER | WB_3DLOOK | WB_HASBUTTONS | WB_HASLINES | WB_HSCROLL | WB_TABSTOP
								  | WB_HASLINESATROOT | WB_HASBUTTONSATROOT ),
	aHeaderBar( this, WB_BUTTONSTYLE | WB_BORDER )
{
	aXEdit.SetAccessibleName(String(IDEResId( RID_STR_WATCHNAME)));
	aTreeListBox.SetAccessibleName(String(IDEResId(RID_STR_WATCHNAME)));		
	
	nVirtToolBoxHeight = aXEdit.GetSizePixel().Height() + 7;
	nHeaderBarHeight = 16;

    aTreeListBox.SetHelpId(HID_BASICIDE_WATCHWINDOW_LIST);
	aTreeListBox.EnableInplaceEditing( sal_True );
	aTreeListBox.SetSelectHdl( LINK( this, WatchWindow, TreeListHdl ) );
	aTreeListBox.SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight + nHeaderBarHeight ) );
	aTreeListBox.SetHighlightRange( 1, 5 );

	Point aPnt( DWBORDER, nVirtToolBoxHeight + 1 );
	aHeaderBar.SetPosPixel( aPnt );
	aHeaderBar.SetEndDragHdl( LINK( this, WatchWindow, implEndDragHdl ) );

	long nVarTabWidth = 220;
	long nValueTabWidth = 100;
	long nTypeTabWidth = 1250;
    aHeaderBar.InsertItem( ITEM_ID_VARIABLE, String( IDEResId( RID_STR_WATCHVARIABLE ) ), nVarTabWidth );
    aHeaderBar.InsertItem( ITEM_ID_VALUE, String( IDEResId( RID_STR_WATCHVALUE ) ), nValueTabWidth );
    aHeaderBar.InsertItem( ITEM_ID_TYPE, String( IDEResId( RID_STR_WATCHTYPE ) ), nTypeTabWidth );

    long tabs[ 4 ];
    tabs[ 0 ] = 3; // two tabs
    tabs[ 1 ] = 0;
    tabs[ 2 ] = nVarTabWidth;
    tabs[ 3 ] = nVarTabWidth + nValueTabWidth;
	aTreeListBox.SvHeaderTabListBox::SetTabs( tabs, MAP_PIXEL );
	aTreeListBox.InitHeaderBar( &aHeaderBar );

	aTreeListBox.SetNodeDefaultImages( );

	aHeaderBar.Show();

	aRemoveWatchButton.Disable();

	aTreeListBox.Show();

	long nTextLen = GetTextWidth( aWatchStr ) + DWBORDER;
	aXEdit.SetPosPixel( Point( nTextLen, 3 ) );
	aXEdit.SetAccHdl( LINK( this, WatchWindow, EditAccHdl ) );
	aXEdit.GetAccelerator().InsertItem( 1, KeyCode( KEY_RETURN ) );
	aXEdit.GetAccelerator().InsertItem( 2, KeyCode( KEY_ESCAPE ) );
	aXEdit.Show();

    aRemoveWatchButton.SetModeImage(Image(IDEResId(RID_IMG_REMOVEWATCH_HC)),
                                    BMP_COLOR_HIGHCONTRAST);
	aRemoveWatchButton.SetClickHdl( LINK( this, WatchWindow, ButtonHdl ) );
	aRemoveWatchButton.SetPosPixel( Point( nTextLen + aXEdit.GetSizePixel().Width() + 4, 2 ) );
	Size aSz( aRemoveWatchButton.GetModeImage().GetSizePixel() );
	aSz.Width() += 6;
	aSz.Height() += 6;
	aRemoveWatchButton.SetSizePixel( aSz );
	aRemoveWatchButton.Show();

	SetText( String( IDEResId( RID_STR_WATCHNAME ) ) );

	SetHelpId( HID_BASICIDE_WATCHWINDOW );

	// make watch window keyboard accessible
	GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
}



__EXPORT WatchWindow::~WatchWindow()
{
	GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
}



void __EXPORT WatchWindow::Paint( const Rectangle& )
{
	DrawText( Point( DWBORDER, 7 ), aWatchStr );
	lcl_DrawIDEWindowFrame( this );
}



void __EXPORT WatchWindow::Resize()
{
	Size aSz = GetOutputSizePixel();
	Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );

	if ( aBoxSz.Width() < 4 )	// < 4, weil noch Border...
		aBoxSz.Width() = 0;
	if ( aBoxSz.Height() < 4 )
		aBoxSz.Height() = 0;

	aBoxSz.Height() -= nHeaderBarHeight;
	aTreeListBox.SetSizePixel( aBoxSz );
    aTreeListBox.GetHScroll()->SetPageSize( aTreeListBox.GetHScroll()->GetVisibleSize() );

	aBoxSz.Height() = nHeaderBarHeight;
	aHeaderBar.SetSizePixel( aBoxSz );

	Invalidate();	//Wegen DrawLine im Paint...
}

struct MemberList
{
	String*			mpMemberNames;
	int				mnMemberCount;

	MemberList( void )
		: mpMemberNames( NULL )
		, mnMemberCount( 0 )
	{}
	~MemberList()
	{
		clear();
	}

	void clear( void );
	void allocList( int nCount );
};

void MemberList::clear( void )
{
	if( mnMemberCount )
	{
		delete[] mpMemberNames;
		mnMemberCount = 0;
	}
}

void MemberList::allocList( int nCount )
{
	clear();
	if( nCount > 0 )
	{
		mnMemberCount = nCount;
		mpMemberNames = new String[ mnMemberCount ];
	}
}

struct WatchItem
{
    String          maName;
    String          maDisplayName;
    SbxObjectRef    mpObject;
	MemberList		maMemberList;

    SbxDimArrayRef	mpArray;
	int				nDimLevel;	// 0 = Root
	int				nDimCount;
	short*			pIndices;

	WatchItem*		mpArrayParentItem;

    WatchItem( void )
		: nDimLevel( 0 )
		, nDimCount( 0 )
		, pIndices( NULL )
		, mpArrayParentItem( NULL )
    {}
    ~WatchItem()
		{ clearWatchItem(); }

	void clearWatchItem( bool bIncludeArrayData=true )
	{
		mpObject = NULL;
		maMemberList.clear();
		if( bIncludeArrayData )
		{
			mpArray = NULL;
			nDimLevel = 0;
			nDimCount = 0;
			delete[] pIndices;
			pIndices = NULL;
		}
	}

	WatchItem* GetRootItem( void );
	SbxDimArray* GetRootArray( void );
};

WatchItem* WatchItem::GetRootItem( void )
{
	WatchItem* pItem = mpArrayParentItem;
	while( pItem )
	{
		if( pItem->mpArray.Is() )
			break;
		pItem = pItem->mpArrayParentItem;
	}
	return pItem;
}

SbxDimArray* WatchItem::GetRootArray( void )
{
	WatchItem* pRootItem = GetRootItem();
	SbxDimArray* pRet = NULL;
	if( pRootItem )
		pRet = pRootItem->mpArray;
	return pRet;
}

void WatchWindow::AddWatch( const String& rVName )
{
	WatchItem* pWatchItem = new WatchItem;
	String aVar, aIndex;
	lcl_SeparateNameAndIndex( rVName, aVar, aIndex );
	pWatchItem->maName = aVar;

	String aWatchStr_( aVar );
	aWatchStr_ += String( RTL_CONSTASCII_USTRINGPARAM( "\t\t" ) );
	SvLBoxEntry* pNewEntry = aTreeListBox.InsertEntry( aWatchStr_, 0, sal_True, LIST_APPEND );
	pNewEntry->SetUserData( pWatchItem );

	aTreeListBox.Select( pNewEntry, sal_True );
	aTreeListBox.MakeVisible( pNewEntry );
	aRemoveWatchButton.Enable();
}

sal_Bool WatchWindow::RemoveSelectedWatch()
{
	SvLBoxEntry* pEntry = aTreeListBox.GetCurEntry();
	if ( pEntry )
	{
		aTreeListBox.GetModel()->Remove( pEntry );
		pEntry = aTreeListBox.GetCurEntry();
		if ( pEntry )
			aXEdit.SetText( ((WatchItem*)pEntry->GetUserData())->maName );
		else
			aXEdit.SetText( String() );
		if ( !aTreeListBox.GetEntryCount() )
			aRemoveWatchButton.Disable();
		return sal_True;
	}
	else
		return sal_False;
}


IMPL_LINK_INLINE_START( WatchWindow, ButtonHdl, ImageButton *, pButton )
{
	if ( pButton == &aRemoveWatchButton )
	{
        BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
        SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
	    SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
        if( pDispatcher )
		{
			pDispatcher->Execute( SID_BASICIDE_REMOVEWATCH );
		}
	}
	return 0;
}
IMPL_LINK_INLINE_END( WatchWindow, ButtonHdl, ImageButton *, pButton )



IMPL_LINK_INLINE_START( WatchWindow, TreeListHdl, SvTreeListBox *, EMPTYARG )
{
	SvLBoxEntry* pCurEntry = aTreeListBox.GetCurEntry();
	if ( pCurEntry && pCurEntry->GetUserData() )
		aXEdit.SetText( ((WatchItem*)pCurEntry->GetUserData())->maName );

	return 0;
}
IMPL_LINK_INLINE_END( WatchWindow, TreeListHdl, SvTreeListBox *, EMPTYARG )


IMPL_LINK_INLINE_START( WatchWindow, implEndDragHdl, HeaderBar *, pBar )
{
	(void)pBar;

    const sal_Int32 TAB_WIDTH_MIN = 10;
	sal_Int32 nMaxWidth =
        aHeaderBar.GetSizePixel().getWidth() - 2 * TAB_WIDTH_MIN;

    sal_Int32 nVariableWith = aHeaderBar.GetItemSize( ITEM_ID_VARIABLE );
    if( nVariableWith < TAB_WIDTH_MIN )
        aHeaderBar.SetItemSize( ITEM_ID_VARIABLE, TAB_WIDTH_MIN );
    else if( nVariableWith > nMaxWidth )
        aHeaderBar.SetItemSize( ITEM_ID_VARIABLE, nMaxWidth );

    sal_Int32 nValueWith = aHeaderBar.GetItemSize( ITEM_ID_VALUE );
    if( nValueWith < TAB_WIDTH_MIN )
        aHeaderBar.SetItemSize( ITEM_ID_VALUE, TAB_WIDTH_MIN );
    else if( nValueWith > nMaxWidth )
        aHeaderBar.SetItemSize( ITEM_ID_VALUE, nMaxWidth );

    if (aHeaderBar.GetItemSize( ITEM_ID_TYPE ) < TAB_WIDTH_MIN)
        aHeaderBar.SetItemSize( ITEM_ID_TYPE, TAB_WIDTH_MIN );

    sal_Int32 nPos = 0;
	sal_uInt16 nTabs = aHeaderBar.GetItemCount();
    // OSL_ASSERT( m_treelb->TabCount() == nTabs );
	for( sal_uInt16 i = 1 ; i < nTabs ; ++i )
	{
		nPos += aHeaderBar.GetItemSize( i );
		aTreeListBox.SetTab( i, nPos, MAP_PIXEL );
	}
	return 0;
}
IMPL_LINK_INLINE_END( WatchWindow, implEndDragHdl, HeaderBar *, pBar )


IMPL_LINK( WatchWindow, EditAccHdl, Accelerator *, pAcc )
{
	switch ( pAcc->GetCurKeyCode().GetCode() )
	{
		case KEY_RETURN:
		{
			String aCurText( aXEdit.GetText() );
			if ( aCurText.Len() )
			{
				AddWatch( aCurText );
				aXEdit.SetSelection( Selection( 0, 0xFFFF ) );
				UpdateWatches();
			}
			else
				Sound::Beep();
		}
		break;
		case KEY_ESCAPE:
		{
			aXEdit.SetText( String() );
		}
		break;
	}

	return 0;
}

void WatchWindow::UpdateWatches( bool bBasicStopped )
{
	aTreeListBox.UpdateWatches( bBasicStopped );
}


StackWindow::StackWindow( Window* pParent ) :
	BasicDockingWindow( pParent ),
	aTreeListBox( this, WB_BORDER | WB_3DLOOK | WB_HSCROLL | WB_TABSTOP ),
	aGotoCallButton( this, IDEResId( RID_IMGBTN_GOTOCALL ) ),
	aStackStr( IDEResId( RID_STR_STACK ) )
{
   	aTreeListBox.SetHelpId(HID_BASICIDE_STACKWINDOW_LIST);
	aTreeListBox.SetAccessibleName(String( IDEResId(RID_STR_STACKNAME)));		
	aTreeListBox.SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight ) );
	aTreeListBox.SetHighlightRange();
    aTreeListBox.SetSelectionMode( NO_SELECTION );
    aTreeListBox.InsertEntry( String(), 0, sal_False, LIST_APPEND );
	aTreeListBox.Show();

	SetText( String( IDEResId( RID_STR_STACKNAME ) ) );

	SetHelpId( HID_BASICIDE_STACKWINDOW );

	aGotoCallButton.SetClickHdl( LINK( this, StackWindow, ButtonHdl ) );
	aGotoCallButton.SetPosPixel( Point( DWBORDER, 2 ) );
	Size aSz( aGotoCallButton.GetModeImage().GetSizePixel() );
	aSz.Width() += 6;
	aSz.Height() += 6;
	aGotoCallButton.SetSizePixel( aSz );
//	aGotoCallButton.Show();	// wird vom Basic noch nicht unterstuetzt!
	aGotoCallButton.Hide();

	// make stack window keyboard accessible
	GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
}



__EXPORT StackWindow::~StackWindow()
{
	GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
}



void __EXPORT StackWindow::Paint( const Rectangle& )
{
	DrawText( Point( DWBORDER, 7 ), aStackStr );
	lcl_DrawIDEWindowFrame( this );
}



void __EXPORT StackWindow::Resize()
{
	Size aSz = GetOutputSizePixel();
	Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );

	if ( aBoxSz.Width() < 4 )	// < 4, weil noch Border...
		aBoxSz.Width() = 0;
	if ( aBoxSz.Height() < 4 )
		aBoxSz.Height() = 0;

	aTreeListBox.SetSizePixel( aBoxSz );

	Invalidate();	//Wegen DrawLine im Paint...
}



IMPL_LINK_INLINE_START( StackWindow, ButtonHdl, ImageButton *, pButton )
{
	if ( pButton == &aGotoCallButton )
	{
        BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
        SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
	    SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
        if( pDispatcher )
		{
			pDispatcher->Execute( SID_BASICIDE_GOTOCALL );
		}
	}
	return 0;
}
IMPL_LINK_INLINE_END( StackWindow, ButtonHdl, ImageButton *, pButton )



void __EXPORT StackWindow::UpdateCalls()
{
	aTreeListBox.SetUpdateMode( sal_False );
	aTreeListBox.Clear();

    if ( StarBASIC::IsRunning() )
    {
	    SbxError eOld = SbxBase::GetError();
        aTreeListBox.SetSelectionMode( SINGLE_SELECTION );

	    sal_uInt16 nScope = 0;
	    SbMethod* pMethod = StarBASIC::GetActiveMethod( nScope );
	    while ( pMethod )
	    {
		    String aEntry( String::CreateFromInt32(nScope ));
		    if ( aEntry.Len() < 2 )
			    aEntry.Insert( ' ', 0 );
		    aEntry += String( RTL_CONSTASCII_USTRINGPARAM( ": " ) );
		    aEntry += pMethod->GetName();
		    SbxArray* pParams = pMethod->GetParameters();
		    SbxInfo* pInfo = pMethod->GetInfo();
		    if ( pParams )
		    {
			    aEntry += '(';
			    // 0 ist der Name der Sub...
			    for ( sal_uInt16 nParam = 1; nParam < pParams->Count(); nParam++ )
			    {
				    SbxVariable* pVar = pParams->Get( nParam );
				    DBG_ASSERT( pVar, "Parameter?!" );
				    if ( pVar->GetName().Len() )
					    aEntry += pVar->GetName();
				    else if ( pInfo )
				    {
					    const SbxParamInfo* pParam = pInfo->GetParam( nParam );
					    if ( pParam )
						    aEntry += pParam->aName;
				    }
				    aEntry += '=';
					SbxDataType eType = pVar->GetType();
	    			if( eType & SbxARRAY )
					    aEntry += String( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
				    else if( eType != SbxOBJECT )
					    aEntry += pVar->GetString();
				    if ( nParam < ( pParams->Count() - 1 ) )
					    aEntry += String( RTL_CONSTASCII_USTRINGPARAM( ", " ) );
			    }
			    aEntry += ')';
		    }
		    aTreeListBox.InsertEntry( aEntry, 0, sal_False, LIST_APPEND );
		    nScope++;
		    pMethod = StarBASIC::GetActiveMethod( nScope );
	    }

	    SbxBase::ResetError();
	    if( eOld != SbxERR_OK )
		    SbxBase::SetError( eOld );
    }
    else
    {
        aTreeListBox.SetSelectionMode( NO_SELECTION );
        aTreeListBox.InsertEntry( String(), 0, sal_False, LIST_APPEND );
    }

	aTreeListBox.SetUpdateMode( sal_True );
}




ComplexEditorWindow::ComplexEditorWindow( ModulWindow* pParent ) :
	Window( pParent, WB_3DLOOK | WB_CLIPCHILDREN ),
	aBrkWindow( this ),
	aEdtWindow( this ),
	aEWVScrollBar( this, WB_VSCROLL | WB_DRAG )
{
	aEdtWindow.SetModulWindow( pParent );
	aBrkWindow.SetModulWindow( pParent );
	aEdtWindow.Show();
	aBrkWindow.Show();

	aEWVScrollBar.SetLineSize( SCROLL_LINE );
	aEWVScrollBar.SetPageSize( SCROLL_PAGE );
	aEWVScrollBar.SetScrollHdl( LINK( this, ComplexEditorWindow, ScrollHdl ) );
	aEWVScrollBar.Show();
}



void __EXPORT ComplexEditorWindow::Resize()
{
	Size aOutSz = GetOutputSizePixel();
	Size aSz( aOutSz );
	aSz.Width() -= 2*DWBORDER;
	aSz.Height() -= 2*DWBORDER;
	long nBrkWidth = 20;
	long nSBWidth = aEWVScrollBar.GetSizePixel().Width();

	Size aBrkSz( Size( nBrkWidth, aSz.Height() ) );
	aBrkWindow.SetPosSizePixel( Point( DWBORDER, DWBORDER ), aBrkSz );

    Size aEWSz( Size( aSz.Width() - nBrkWidth - nSBWidth + 2, aSz.Height() ) );
	aEdtWindow.SetPosSizePixel( Point( DWBORDER+aBrkSz.Width()-1, DWBORDER ), aEWSz );

	aEWVScrollBar.SetPosSizePixel( Point( aOutSz.Width()-DWBORDER-nSBWidth, DWBORDER ), Size( nSBWidth, aSz.Height() ) );

	// Macht das EditorWindow, ausserdem hier falsch, da Pixel
//	aEWVScrollBar.SetPageSize( aEWSz.Height() * 8 / 10 );
//	aEWVScrollBar.SetVisibleSize( aSz.Height() );
//	Invalidate();
}

IMPL_LINK( ComplexEditorWindow, ScrollHdl, ScrollBar *, pCurScrollBar )
{
	if ( aEdtWindow.GetEditView() )
	{
		DBG_ASSERT( pCurScrollBar == &aEWVScrollBar, "Wer scrollt hier ?" );
		long nDiff = aEdtWindow.GetEditView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
		aEdtWindow.GetEditView()->Scroll( 0, nDiff );
		aBrkWindow.DoScroll( 0, nDiff );
		aEdtWindow.GetEditView()->ShowCursor( sal_False, sal_True );
		pCurScrollBar->SetThumbPos( aEdtWindow.GetEditView()->GetStartDocPos().Y() );
	}

	return 0;
}

// virtual
void ComplexEditorWindow::DataChanged(DataChangedEvent const & rDCEvt)
{
    Window::DataChanged(rDCEvt);
    if (rDCEvt.GetType() == DATACHANGED_SETTINGS
        && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
    {
        Color aColor(GetSettings().GetStyleSettings().GetFaceColor());
        if (aColor
            != rDCEvt.GetOldSettings()->GetStyleSettings().GetFaceColor())
        {
            SetBackground(Wallpaper(aColor));
            Invalidate();
        }
    }
}

// virtual
uno::Reference< awt::XWindowPeer >
EditorWindow::GetComponentInterface(sal_Bool bCreate)
{
    uno::Reference< awt::XWindowPeer > xPeer(
        Window::GetComponentInterface(false));
    if (!xPeer.is() && bCreate)
    {
        // Make sure edit engine and view are available:
        if (!pEditEngine)
            CreateEditEngine();

        xPeer = new ::svt::TextWindowPeer(*GetEditView());
        SetComponentInterface(xPeer);
    }
    return xPeer;
}

WatchTreeListBox::WatchTreeListBox( Window* pParent, WinBits nWinBits )
	: SvHeaderTabListBox( pParent, nWinBits )
{}

WatchTreeListBox::~WatchTreeListBox()
{
	// User-Daten zerstoeren...
	SvLBoxEntry* pEntry = First();
	while ( pEntry )
	{
		delete (WatchItem*)pEntry->GetUserData();
		pEntry = Next( pEntry );
	}
}

void WatchTreeListBox::SetTabs()
{
	SvHeaderTabListBox::SetTabs();
	sal_uInt16 nTabCount_ = aTabs.Count();
	for( sal_uInt16 i = 0 ; i < nTabCount_ ; i++ )
	{
		SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(i);
		if( i == 2 )
			pTab->nFlags |= SV_LBOXTAB_EDITABLE;
		else
			pTab->nFlags &= ~SV_LBOXTAB_EDITABLE;
	}
}

void WatchTreeListBox::RequestingChilds( SvLBoxEntry * pParent )
{
	if( !StarBASIC::IsRunning() )
        return;

    if( GetChildCount( pParent ) > 0 )
        return;

	SvLBoxEntry * pEntry = pParent;
    WatchItem* pItem = (WatchItem*)pEntry->GetUserData();

	SbxDimArray* pArray = pItem->mpArray;
	SbxDimArray* pRootArray = pItem->GetRootArray();
	bool bArrayIsRootArray = false;
	if( !pArray && pRootArray )
	{
		pArray = pRootArray;
		bArrayIsRootArray = true;
	}

    SbxObject* pObj = pItem->mpObject;
    if( pObj )
    {
		createAllObjectProperties( pObj );
 	    SbxArray* pProps = pObj->GetProperties();
	    sal_uInt16 nPropCount = pProps->Count();
		pItem->maMemberList.allocList( nPropCount );

	    for( sal_uInt16 i = 0 ; i < nPropCount - 3 ; i++ )
	    {
		    SbxVariable* pVar = pProps->Get( i );

            String aName( pVar->GetName() );
			pItem->maMemberList.mpMemberNames[i] = aName;
            SvLBoxEntry* pChildEntry = SvTreeListBox::InsertEntry( aName, pEntry );
            WatchItem* pChildItem = new WatchItem();
			pChildItem->maName = aName;
	        pChildEntry->SetUserData( pChildItem );
	    }
		if( nPropCount > 0 )
		{
			UpdateWatches();
		}
    }
	else if( pArray )
	{
	    sal_uInt16 nElementCount = 0;

		// Loop through indices of current level
		int nParentLevel = bArrayIsRootArray ? pItem->nDimLevel : 0;
		int nThisLevel = nParentLevel + 1;
		sal_Int32 nMin, nMax;
		pArray->GetDim32( nThisLevel, nMin, nMax );
		for( sal_Int32 i = nMin ; i <= nMax ; i++ )
		{
            WatchItem* pChildItem = new WatchItem();

			// Copy data and create name
            String aBaseName( pItem->maName );
			pChildItem->maName = aBaseName;

			String aIndexStr = String( RTL_CONSTASCII_USTRINGPARAM( "(" ) );
			// pChildItem->mpArray = pItem->mpArray;
			pChildItem->mpArrayParentItem = pItem;
			pChildItem->nDimLevel = nThisLevel;
			pChildItem->nDimCount = pItem->nDimCount;
			pChildItem->pIndices = new short[ pChildItem->nDimCount ];
			sal_uInt16 j;
			for( j = 0 ; j < nParentLevel ; j++ )
			{
				short n = pChildItem->pIndices[j] = pItem->pIndices[j];
				aIndexStr += String::CreateFromInt32( n );
				aIndexStr += String( RTL_CONSTASCII_USTRINGPARAM( "," ) );
			}
			pChildItem->pIndices[ nParentLevel ] = sal::static_int_cast<short>( i );
			aIndexStr += String::CreateFromInt32( i );
			aIndexStr += String( RTL_CONSTASCII_USTRINGPARAM( ")" ) );

			String aDisplayName;
			WatchItem* pArrayRootItem = pChildItem->GetRootItem();
			if( pArrayRootItem && pArrayRootItem->mpArrayParentItem )
				aDisplayName = pItem->maDisplayName;
			else
				aDisplayName = aBaseName;
			aDisplayName += aIndexStr;
			pChildItem->maDisplayName = aDisplayName;

            SvLBoxEntry* pChildEntry = SvTreeListBox::InsertEntry( aDisplayName, pEntry );
			nElementCount++;
			pChildEntry->SetUserData( pChildItem );
		}
		if( nElementCount > 0 )
		{
			UpdateWatches();
		}
	}
}

SbxBase* WatchTreeListBox::ImplGetSBXForEntry( SvLBoxEntry* pEntry, bool& rbArrayElement )
{
	SbxBase* pSBX = NULL;
	rbArrayElement = false;

    WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
	String aVName( pItem->maName );

    SvLBoxEntry* pParentEntry = GetParent( pEntry );
	WatchItem* pParentItem = pParentEntry ? (WatchItem*)pParentEntry->GetUserData() : NULL;
    if( pParentItem )
    {
        SbxObject* pObj = pParentItem->mpObject;
        SbxDimArray* pArray;
        if( pObj )
		{
    		pSBX = pObj->Find( aVName, SbxCLASS_DONTCARE );

			SbxVariable* pVar;
			if ( pSBX && (pVar = dynamic_cast< SbxVariable* >( pSBX )) != NULL
						&& !dynamic_cast< SbxMethod* >(pSBX) )
			{
				// Force getting value
				SbxValues aRes;
				aRes.eType = SbxVOID;
				pVar->Get( aRes );
			}
		}
		// Array?
		else if( (pArray = pItem->GetRootArray()) != NULL )
		// else if( (pArray = pItem->mpArray) != NULL )
		{
			rbArrayElement = true;
			if( pParentItem->nDimLevel + 1 == pParentItem->nDimCount )
			// if( pItem->nDimLevel == pItem->nDimCount )
				pSBX = pArray->Get( pItem->pIndices );
			// else
				// pSBX = pArray;
		}
    }
	else
	{
		pSBX = StarBASIC::FindSBXInCurrentScope( aVName );
	}
	return pSBX;
}

sal_Bool __EXPORT WatchTreeListBox::EditingEntry( SvLBoxEntry* pEntry, Selection& )
{
    WatchItem* pItem = (WatchItem*)pEntry->GetUserData();

	sal_Bool bEdit = sal_False;
	if ( StarBASIC::IsRunning() && StarBASIC::GetActiveMethod() && !SbxBase::IsError() )
	{
		// No out of scope entries
		bool bArrayElement;
		SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
		if ( ( pSBX && dynamic_cast< SbxVariable* >(pSBX) && !dynamic_cast< SbxMethod* >(pSBX) ) || bArrayElement )
		{
			// Accept no objects and only end nodes of arrays for editing
			if( !pItem->mpObject && (pItem->mpArray == NULL || pItem->nDimLevel == pItem->nDimCount) )
			{
				aEditingRes = SvHeaderTabListBox::GetEntryText( pEntry, ITEM_ID_VALUE-1 );
				aEditingRes.EraseLeadingChars();
				aEditingRes.EraseTrailingChars();
				bEdit = sal_True;
			}
		}
	}

	if ( !bEdit )
		Sound::Beep();

	return bEdit;
}

sal_Bool __EXPORT WatchTreeListBox::EditedEntry( SvLBoxEntry* pEntry, const String& rNewText )
{
    WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
	String aVName( pItem->maName );

	String aResult = rNewText;
	aResult.EraseLeadingChars();
	aResult.EraseTrailingChars();

	sal_uInt16 nResultLen = aResult.Len();
	sal_Unicode cFirst = aResult.GetChar( 0 );
	sal_Unicode cLast  = aResult.GetChar( nResultLen - 1 );
	if( cFirst == '\"' && cLast == '\"' )
		aResult = aResult.Copy( 1, nResultLen - 2 );

	sal_Bool bResModified = ( aResult != aEditingRes ) ? sal_True : sal_False;
	sal_Bool bError = sal_False;
	if ( !aVName.Len() )
	{
		bError = sal_True;
	}

	sal_Bool bRet = sal_False;

	if ( bError )
	{
		Sound::Beep();
	}
	else if ( bResModified )
	{
		bRet = ImplBasicEntryEdited( pEntry, aResult );
	}

	return bRet;
}

sal_Bool WatchTreeListBox::ImplBasicEntryEdited( SvLBoxEntry* pEntry, const String& rResult )
{
    WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
	String aVName( pItem->maName );

	sal_Bool bError = sal_False;
	String aResult( rResult );
	String aIndex;
	bool bArrayElement;
	SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );

	SbxBase* pToBeChanged = NULL;
	if ( pSBX && dynamic_cast< SbxVariable* >(pSBX) && !dynamic_cast< SbxMethod* >(pSBX) )
	{
		SbxVariable* pVar = (SbxVariable*)pSBX;
		SbxDataType eType = pVar->GetType();
		if ( (sal_uInt8)eType == (sal_uInt8)SbxOBJECT )
			bError = sal_True;
		else if ( eType & SbxARRAY )
			bError = sal_True;
		else
			pToBeChanged = pSBX;
	}

	if ( pToBeChanged )
	{
		SbxVariable* pSbxVariable = dynamic_cast< SbxVariable* >(pToBeChanged);
		
		if ( pSbxVariable )
		{
			// Wenn der Typ variabel ist, macht die Konvertierung des SBX nichts,
			// bei festem Typ wird der String konvertiert.
			pSbxVariable->PutStringExt( aResult );
		}
		else
			bError = sal_True;
	}

	// Wenn jemand z.B. einen zu grossen Wert fuer ein Int eingegeben hat,
	// folgt beim naechsten Step() ein Runtime-Error.
	if ( SbxBase::IsError() )
	{
		bError = sal_True;
		SbxBase::ResetError();
	}

	if ( bError )
		Sound::Beep();

	UpdateWatches();

	// Der Text soll niemals 1-zu-1 uebernommen werden, weil dann das
	// UpdateWatches verlorengeht.
	return sal_False;
}


static void implCollapseModifiedObjectEntry( SvLBoxEntry* pParent, WatchTreeListBox* pThis )
{
	pThis->Collapse( pParent );

	SvLBoxTreeList*	pModel = pThis->GetModel();
	SvLBoxEntry* pDeleteEntry;
	while( (pDeleteEntry = pThis->SvTreeListBox::GetEntry( pParent, 0 )) != NULL )
	{
		implCollapseModifiedObjectEntry( pDeleteEntry, pThis );

        WatchItem* pItem = (WatchItem*)pDeleteEntry->GetUserData();
		delete pItem;
        pModel->Remove( pDeleteEntry );
	}
}

static String implCreateTypeStringForDimArray( WatchItem* pItem, SbxDataType eType )
{
	String aRetStr = getBasicTypeName( eType );

	SbxDimArray* pArray = pItem->mpArray;
	if( !pArray )
		pArray = pItem->GetRootArray();
	if( pArray )
	{
		int nDimLevel = pItem->nDimLevel;
		int nDims = pItem->nDimCount;
		if( nDimLevel < nDims )
		{
			aRetStr += '(';
			for( int i = nDimLevel ; i < nDims ; i++ )
			{
				short nMin, nMax;
				pArray->GetDim( sal::static_int_cast<short>( i+1 ), nMin, nMax );
				aRetStr += String::CreateFromInt32( nMin );
				aRetStr += String( RTL_CONSTASCII_USTRINGPARAM( " to " ) );
				aRetStr += String::CreateFromInt32( nMax );
				if( i < nDims - 1 )
					aRetStr += String( RTL_CONSTASCII_USTRINGPARAM( ", " ) );
			}
			aRetStr += ')';
		}
	}
	return aRetStr;
}


void implEnableChildren( SvLBoxEntry* pEntry, bool bEnable )
// inline void implEnableChildren( SvLBoxEntry* pEntry, bool bEnable )
{
	if( bEnable )
	{
		pEntry->SetFlags(
			(pEntry->GetFlags() &
			~(SV_ENTRYFLAG_NO_NODEBMP | SV_ENTRYFLAG_HAD_CHILDREN))
			| SV_ENTRYFLAG_CHILDS_ON_DEMAND );
	}
	else
	{
		pEntry->SetFlags(
			(pEntry->GetFlags() & ~(SV_ENTRYFLAG_CHILDS_ON_DEMAND)) );
	}
}

void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
{
	SbMethod* pCurMethod = StarBASIC::GetActiveMethod();

	SbxError eOld = SbxBase::GetError();
	setBasicWatchMode( true );

	SvLBoxEntry* pEntry = First();
	while ( pEntry )
	{
        WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
		String aVName( pItem->maName );
		DBG_ASSERT( aVName.Len(), "Var? - Darf nicht leer sein!" );
		String aWatchStr;
		String aTypeStr;
		if ( pCurMethod )
		{
			bool bArrayElement;
			SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );

			// Array? If no end node create type string
			if( bArrayElement && pItem->nDimLevel < pItem->nDimCount )
			{
				SbxDimArray* pRootArray = pItem->GetRootArray();
				SbxDataType eType = pRootArray->GetType();
				// SbxDataType eType = pItem->mpArray->GetType();
				aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
				implEnableChildren( pEntry, true );
			}

			bool bCollapse = false;
			if ( pSBX && dynamic_cast< SbxVariable* >(pSBX) && !dynamic_cast< SbxMethod* >(pSBX) )
			{
				SbxVariable* pVar = (SbxVariable*)pSBX;
				// Sonderbehandlung fuer Arrays:
				SbxDataType eType = pVar->GetType();
				if ( eType & SbxARRAY )
				{
					// Mehrdimensionale Arrays beruecksichtigen!
					SbxBase* pBase = pVar->GetObject();
					if ( pBase && dynamic_cast< SbxDimArray* >(pBase) )
					{
						SbxDimArray* pNewArray = (SbxDimArray*)pBase;
						SbxDimArray* pOldArray = pItem->mpArray;

						bool bArrayChanged = false;
						if( pNewArray != NULL && pOldArray != NULL )
						{
							// Compare Array dimensions to see if array has changed
							// Can be a copy, so comparing pointers does not work
							sal_uInt16 nOldDims = pOldArray->GetDims();
							sal_uInt16 nNewDims = pNewArray->GetDims();
							if( nOldDims != nNewDims )
							{
								bArrayChanged = true;
							}
							else
							{
								for( int i = 0 ; i < nOldDims ; i++ )
								{
									short nOldMin, nOldMax;
									short nNewMin, nNewMax;

									pOldArray->GetDim( sal::static_int_cast<short>( i+1 ), nOldMin, nOldMax );
									pNewArray->GetDim( sal::static_int_cast<short>( i+1 ), nNewMin, nNewMax );
									if( nOldMin != nNewMin || nOldMax != nNewMax )
									{
										bArrayChanged = true;
										break;
									}
								}
							}
						}
						else if( pNewArray == NULL || pOldArray == NULL )
							bArrayChanged = true;

						if( pNewArray )
							implEnableChildren( pEntry, true );

						// #i37227 Clear always and replace array
						if( pNewArray != pOldArray )
						{
							pItem->clearWatchItem( false );
							if( pNewArray )
							{
								implEnableChildren( pEntry, true );

								pItem->mpArray = pNewArray;
								sal_uInt16 nDims = pNewArray->GetDims();
								pItem->nDimLevel = 0;
								pItem->nDimCount = nDims;
							}
						}
						if( bArrayChanged && pOldArray != NULL )
							bCollapse = true;

						aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
					}
					else
						aWatchStr += String( RTL_CONSTASCII_USTRINGPARAM( "<?>" ) );
				}
				else if ( (sal_uInt8)eType == (sal_uInt8)SbxOBJECT )
				{
                    SbxObject* pObj = NULL;
			        SbxBase* pBase = pVar->GetObject();
			        if( pBase && dynamic_cast< SbxObject* >(pBase) )
                        pObj = (SbxObject*)pBase;

                    if( pObj )
                    {
						// Check if member list has changed
						bool bObjChanged = false;
						if( pItem->mpObject != NULL && pItem->maMemberList.mpMemberNames != NULL )
						{
							SbxArray* pProps = pObj->GetProperties();
							sal_uInt16 nPropCount = pProps->Count();
							for( sal_uInt16 i = 0 ; i < nPropCount - 3 ; i++ )
							{
								SbxVariable* pVar_ = pProps->Get( i );
								String aName( pVar_->GetName() );
								if( pItem->maMemberList.mpMemberNames[i] != aName )
								{
									bObjChanged = true;
									break;
								}
							}
							if( bObjChanged )
								bCollapse = true;
						}

						pItem->mpObject = pObj;
						implEnableChildren( pEntry, true );
						aTypeStr = getBasicObjectTypeName( pObj );
					}
					else
					{
						aWatchStr = String( RTL_CONSTASCII_USTRINGPARAM( "Null" ) );
						if( pItem->mpObject != NULL )
						{
							bCollapse = true;
							pItem->clearWatchItem( false );

							implEnableChildren( pEntry, false );
						}
					}
				}
				else
				{
					if( pItem->mpObject != NULL )
					{
						bCollapse = true;
						pItem->clearWatchItem( false );

						implEnableChildren( pEntry, false );
					}

					bool bString = ((sal_uInt8)eType == (sal_uInt8)SbxSTRING);
					String aStrStr( RTL_CONSTASCII_USTRINGPARAM( "\"" ) );
					if( bString )
						aWatchStr += aStrStr;
					aWatchStr += pVar->GetString();
					if( bString )
						aWatchStr += aStrStr;
				}
				if( !aTypeStr.Len() )
				{
					if( !pVar->IsFixed() )
						aTypeStr = String( RTL_CONSTASCII_USTRINGPARAM( "Variant/" ) );
					aTypeStr += getBasicTypeName( pVar->GetType() );
				}
			}
			else if( !bArrayElement )
				aWatchStr += String( RTL_CONSTASCII_USTRINGPARAM( "<Out of Scope>" ) );

			if( bCollapse )
				implCollapseModifiedObjectEntry( pEntry, this );

		}
		else if( bBasicStopped )
		{
            if( pItem->mpObject || pItem->mpArray )
			{
				implCollapseModifiedObjectEntry( pEntry, this );
				pItem->mpObject = NULL;
			}
		}

		SvHeaderTabListBox::SetEntryText( aWatchStr, pEntry, ITEM_ID_VALUE-1 );
		SvHeaderTabListBox::SetEntryText( aTypeStr, pEntry, ITEM_ID_TYPE-1 );

		pEntry = Next( pEntry );
	}

	// Force redraw
    Invalidate();

	SbxBase::ResetError();
	if( eOld != SbxERR_OK )
		SbxBase::SetError( eOld );
	setBasicWatchMode( false );
}

