/**************************************************************
 * 
 * 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 && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
					{
						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 )
{
	if ( rHint.ISA( TextHint ) )
	{
		const TextHint& rTextHint = (const TextHint&)rHint;
		if( rTextHint.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( rTextHint.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( rTextHint.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( rTextHint.GetId() == TEXT_HINT_PARAINSERTED )
		{
			ParagraphInsertedDeleted( rTextHint.GetValue(), sal_True );
			DoDelayedSyntaxHighlight( rTextHint.GetValue() );
		}
		else if( rTextHint.GetId() == TEXT_HINT_PARAREMOVED )
		{
			ParagraphInsertedDeleted( rTextHint.GetValue(), sal_False );
		}
		else if( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED )
		{
			DoDelayedSyntaxHighlight( rTextHint.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 = PTR_CAST( SbxVariable, pSBX )) != NULL
						&& !pSBX->ISA( SbxMethod ) )
			{
				// 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 && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) ) || 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 && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
	{
		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 )
	{
		if ( pToBeChanged->ISA( SbxVariable ) )
		{
			// Wenn der Typ variabel ist, macht die Konvertierung des SBX nichts,
			// bei festem Typ wird der String konvertiert.
			((SbxVariable*)pToBeChanged)->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 && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
			{
				SbxVariable* pVar = (SbxVariable*)pSBX;
				// Sonderbehandlung fuer Arrays:
				SbxDataType eType = pVar->GetType();
				if ( eType & SbxARRAY )
				{
					// Mehrdimensionale Arrays beruecksichtigen!
					SbxBase* pBase = pVar->GetObject();
					if ( pBase && pBase->ISA( SbxDimArray ) )
					{
						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 && pBase->ISA( SbxObject ) )
                        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 );
}

