Update ooo320-m1
[ooovba.git] / basctl / source / basicide / baside2b.cxx
blob59ce08ca41345648406d75252c7196a7d11d01ea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: baside2b.cxx,v $
10 * $Revision: 1.59 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basctl.hxx"
35 #include <svtools/svarray.hxx>
36 #define _BASIC_TEXTPORTIONS
37 #include <basic/sbdef.hxx>
38 #include <ide_pch.hxx>
41 #include <tools/urlobj.hxx>
42 #include <unotools/charclass.hxx>
43 #include <svtools/urihelper.hxx>
44 #include <basic/sbx.hxx>
45 #include <vcl/sound.hxx>
46 #include <svtools/xtextedt.hxx>
47 #include <svtools/txtattr.hxx>
48 #include <svtools/textwindowpeer.hxx>
49 #include <basic/sbuno.hxx>
51 #include <helpid.hrc>
52 #include <baside2.hrc>
53 #include <baside2.hxx>
54 #include <brkdlg.hxx>
55 #include <objdlg.hxx>
56 #include <basobj.hxx>
57 #include <iderdll.hxx>
58 #include <iderdll2.hxx>
59 #include <vcl/taskpanelist.hxx>
60 #include <vcl/help.hxx>
62 //#ifndef _SFX_HELP_HXX //autogen
63 //#include <sfx2/sfxhelp.hxx>
64 //#endif
65 #include <svtools/sourceviewconfig.hxx>
67 #ifndef _COM_SUN_STAR_SCRIPT_XLIBRYARYCONTAINER2_HPP_
68 #include <com/sun/star/script/XLibraryContainer2.hpp>
69 #endif
70 #include <comphelper/processfactory.hxx>
73 using namespace ::com::sun::star;
74 using namespace ::com::sun::star::uno;
77 long nVirtToolBoxHeight; // wird im WatchWindow init., im Stackwindow verw.
78 long nHeaderBarHeight;
80 #define SCROLL_LINE 12
81 #define SCROLL_PAGE 60
83 #define DWBORDER 3
85 static const char cSuffixes[] = "%&!#@$";
87 MapUnit eEditMapUnit = MAP_100TH_MM;
90 // #108672 Helper functions to get/set text in TextEngine
91 // using the stream interface (get/setText() only supports
92 // tools Strings limited to 64K).
93 ::rtl::OUString getTextEngineText( ExtTextEngine* pEngine )
95 SvMemoryStream aMemStream;
96 aMemStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
97 aMemStream.SetLineDelimiter( LINEEND_LF );
98 pEngine->Write( aMemStream );
99 ULONG nSize = aMemStream.Tell();
100 ::rtl::OUString aText( (const sal_Char*)aMemStream.GetData(),
101 nSize, RTL_TEXTENCODING_UTF8 );
102 return aText;
105 void setTextEngineText( ExtTextEngine* pEngine, const ::rtl::OUString aStr )
107 pEngine->SetText( String() );
108 ::rtl::OString aUTF8Str = ::rtl::OUStringToOString( aStr, RTL_TEXTENCODING_UTF8 );
109 SvMemoryStream aMemStream( (void*)aUTF8Str.getStr(), aUTF8Str.getLength(),
110 STREAM_READ | STREAM_SEEK_TO_BEGIN );
111 aMemStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
112 aMemStream.SetLineDelimiter( LINEEND_LF );
113 pEngine->Read( aMemStream );
116 void lcl_DrawIDEWindowFrame( DockingWindow* pWin )
118 // The result of using explicit colors here appears to be harmless when
119 // switching to high contrast mode:
120 if ( !pWin->IsFloatingMode() )
122 Size aSz = pWin->GetOutputSizePixel();
123 const Color aOldLineColor( pWin->GetLineColor() );
124 pWin->SetLineColor( Color( COL_WHITE ) );
125 // oben eine weisse..
126 pWin->DrawLine( Point( 0, 0 ), Point( aSz.Width(), 0 ) );
127 // unten eine schwarze...
128 pWin->SetLineColor( Color( COL_BLACK ) );
129 pWin->DrawLine( Point( 0, aSz.Height() - 1 ), Point( aSz.Width(), aSz.Height() - 1 ) );
130 pWin->SetLineColor( aOldLineColor );
134 void lcl_SeparateNameAndIndex( const String& rVName, String& rVar, String& rIndex )
136 rVar = rVName;
137 rIndex.Erase();
138 USHORT nIndexStart = rVar.Search( '(' );
139 if ( nIndexStart != STRING_NOTFOUND )
141 USHORT nIndexEnd = rVar.Search( ')', nIndexStart );
142 if ( nIndexStart != STRING_NOTFOUND )
144 rIndex = rVar.Copy( nIndexStart+1, nIndexEnd-nIndexStart-1 );
145 rVar.Erase( nIndexStart );
146 rVar.EraseTrailingChars();
147 rIndex.EraseLeadingChars();
148 rIndex.EraseTrailingChars();
152 if ( rVar.Len() )
154 USHORT nLastChar = rVar.Len()-1;
155 if ( strchr( cSuffixes, rVar.GetChar( nLastChar ) ) )
156 rVar.Erase( nLastChar, 1 );
158 if ( rIndex.Len() )
160 USHORT nLastChar = rIndex.Len()-1;
161 if ( strchr( cSuffixes, rIndex.GetChar( nLastChar ) ) )
162 rIndex.Erase( nLastChar, 1 );
167 EditorWindow::EditorWindow( Window* pParent ) :
168 Window( pParent, WB_BORDER )
170 bDoSyntaxHighlight = TRUE;
171 bDelayHighlight = TRUE;
172 pModulWindow = 0;
173 pEditView = 0;
174 pEditEngine = 0;
175 pSourceViewConfig = new svt::SourceViewConfig;
176 bHighlightning = FALSE;
177 pProgress = 0;
178 nCurTextWidth = 0;
179 SetBackground(
180 Wallpaper(GetSettings().GetStyleSettings().GetFieldColor()));
181 SetPointer( Pointer( POINTER_TEXT ) );
183 SetHelpId( HID_BASICIDE_EDITORWINDOW );
185 StartListening( *pSourceViewConfig );
190 __EXPORT EditorWindow::~EditorWindow()
192 EndListening( *pSourceViewConfig );
193 delete pSourceViewConfig;
195 aSyntaxIdleTimer.Stop();
197 if ( pEditEngine )
199 EndListening( *pEditEngine );
200 pEditEngine->RemoveView( pEditView );
201 // pEditEngine->SetViewWin( 0 );
202 delete pEditView;
203 delete pEditEngine;
207 String EditorWindow::GetWordAtCursor()
209 String aWord;
211 if ( pEditView )
213 TextEngine* pTextEngine = pEditView->GetTextEngine();
214 if ( pTextEngine )
216 // check first, if the cursor is at a help URL
217 const TextSelection& rSelection = pEditView->GetSelection();
218 const TextPaM& rSelStart = rSelection.GetStart();
219 const TextPaM& rSelEnd = rSelection.GetEnd();
220 String aText = pTextEngine->GetText( rSelEnd.GetPara() );
221 CharClass aClass( ::comphelper::getProcessServiceFactory() , Application::GetSettings().GetLocale() );
222 xub_StrLen nSelStart = static_cast< xub_StrLen >( rSelStart.GetIndex() );
223 xub_StrLen nSelEnd = static_cast< xub_StrLen >( rSelEnd.GetIndex() );
224 xub_StrLen nLength = static_cast< xub_StrLen >( aText.Len() );
225 xub_StrLen nStart = 0;
226 xub_StrLen nEnd = nLength;
227 while ( nStart < nLength )
229 String aURL( URIHelper::FindFirstURLInText( aText, nStart, nEnd, aClass ) );
230 INetURLObject aURLObj( aURL );
231 if ( aURLObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP
232 && nSelStart >= nStart && nSelStart <= nEnd && nSelEnd >= nStart && nSelEnd <= nEnd )
234 aWord = aURL;
235 break;
237 nStart = nEnd;
238 nEnd = nLength;
241 // Nicht den Selektierten Bereich, sondern an der CursorPosition,
242 // falls Teil eines Worts markiert.
243 if ( !aWord.Len() )
244 aWord = pTextEngine->GetWord( rSelEnd );
246 // Kann leer sein, wenn komplettes Word markiert, da Cursor dahinter.
247 if ( !aWord.Len() && pEditView->HasSelection() )
248 aWord = pTextEngine->GetWord( rSelStart );
252 return aWord;
255 void __EXPORT EditorWindow::RequestHelp( const HelpEvent& rHEvt )
257 BOOL bDone = FALSE;
259 // Sollte eigentlich mal aktiviert werden...
260 if ( pEditEngine )
262 if ( rHEvt.GetMode() & HELPMODE_CONTEXT )
264 String aKeyword = GetWordAtCursor();
265 Application::GetHelp()->Start( aKeyword, this );
266 bDone = TRUE;
268 else if ( rHEvt.GetMode() & HELPMODE_QUICK )
270 String aHelpText;
271 Point aTopLeft;
272 if ( StarBASIC::IsRunning() )
274 Point aWindowPos = rHEvt.GetMousePosPixel();
275 aWindowPos = ScreenToOutputPixel( aWindowPos );
276 Point aDocPos = GetEditView()->GetDocPos( aWindowPos );
277 TextPaM aCursor = GetEditView()->GetTextEngine()->GetPaM( aDocPos, FALSE );
278 TextPaM aStartOfWord;
279 String aWord = GetEditView()->GetTextEngine()->GetWord( aCursor, &aStartOfWord );
280 if ( aWord.Len() && !ByteString( aWord, RTL_TEXTENCODING_UTF8 ).IsNumericAscii() )
282 USHORT nLastChar =aWord.Len()-1;
283 if ( strchr( cSuffixes, aWord.GetChar( nLastChar ) ) )
284 aWord.Erase( nLastChar, 1 );
285 SbxBase* pSBX = StarBASIC::FindSBXInCurrentScope( aWord );
286 if ( pSBX && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
288 SbxVariable* pVar = (SbxVariable*)pSBX;
289 SbxDataType eType = pVar->GetType();
290 if ( (BYTE)eType == (BYTE)SbxOBJECT )
291 // Kann zu Absturz, z.B. bei Selections-Objekt fuehren
292 // Type == Object heisst nicht, dass pVar == Object!
293 ; // aHelpText = ((SbxObject*)pVar)->GetClassName();
294 else if ( eType & SbxARRAY )
295 ; // aHelpText = "{...}";
296 else if ( (BYTE)eType != (BYTE)SbxEMPTY )
298 aHelpText = pVar->GetName();
299 if ( !aHelpText.Len() ) // Bei Uebergabeparametern wird der Name nicht kopiert
300 aHelpText = aWord;
301 aHelpText += '=';
302 aHelpText += pVar->GetString();
305 if ( aHelpText.Len() )
307 aTopLeft = GetEditView()->GetTextEngine()->PaMtoEditCursor( aStartOfWord ).BottomLeft();
308 aTopLeft = GetEditView()->GetWindowPos( aTopLeft );
309 aTopLeft.X() += 5;
310 aTopLeft.Y() += 5;
311 aTopLeft = OutputToScreenPixel( aTopLeft );
315 Help::ShowQuickHelp( this, Rectangle( aTopLeft, Size( 1, 1 ) ), aHelpText, QUICKHELP_TOP|QUICKHELP_LEFT);
316 bDone = TRUE;
320 if ( !bDone )
321 Window::RequestHelp( rHEvt );
325 void __EXPORT EditorWindow::Resize()
327 // ScrollBars, etc. passiert in Adjust...
328 if ( pEditView )
330 long nVisY = pEditView->GetStartDocPos().Y();
331 // pEditView->SetOutputArea( Rectangle( Point( 0, 0 ), GetOutputSize() ) );
332 pEditView->ShowCursor();
333 Size aOutSz( GetOutputSizePixel() );
334 long nMaxVisAreaStart = pEditView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
335 if ( nMaxVisAreaStart < 0 )
336 nMaxVisAreaStart = 0;
337 if ( pEditView->GetStartDocPos().Y() > nMaxVisAreaStart )
339 Point aStartDocPos( pEditView->GetStartDocPos() );
340 aStartDocPos.Y() = nMaxVisAreaStart;
341 pEditView->SetStartDocPos( aStartDocPos );
342 pEditView->ShowCursor();
343 pModulWindow->GetBreakPointWindow().GetCurYOffset() = aStartDocPos.Y();
345 InitScrollBars();
346 if ( nVisY != pEditView->GetStartDocPos().Y() )
347 Invalidate();
353 void __EXPORT EditorWindow::MouseMove( const MouseEvent &rEvt )
355 if ( pEditView )
356 pEditView->MouseMove( rEvt );
361 void __EXPORT EditorWindow::MouseButtonUp( const MouseEvent &rEvt )
363 if ( pEditView )
365 pEditView->MouseButtonUp( rEvt );
366 SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
367 if ( pBindings )
368 pBindings->Invalidate( SID_BASICIDE_STAT_POS );
372 void __EXPORT EditorWindow::MouseButtonDown( const MouseEvent &rEvt )
374 GrabFocus();
375 if ( pEditView )
377 pEditView->MouseButtonDown( rEvt );
381 void __EXPORT EditorWindow::Command( const CommandEvent& rCEvt )
383 if ( pEditView )
385 pEditView->Command( rCEvt );
386 if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
387 ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
388 ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
390 HandleScrollCommand( rCEvt, pModulWindow->GetHScrollBar(), &pModulWindow->GetEditVScrollBar() );
395 BOOL EditorWindow::ImpCanModify()
397 BOOL bCanModify = TRUE;
398 if ( StarBASIC::IsRunning() )
400 // Wenn im Trace-Mode, entweder Trace abbrechen oder
401 // Eingabe verweigern
402 // Im Notify bei Basic::Stoped die Markierungen in den Modulen
403 // entfernen!
404 if ( QueryBox( 0, WB_OK_CANCEL, String( IDEResId( RID_STR_WILLSTOPPRG ) ) ).Execute() == RET_OK )
406 pModulWindow->GetBasicStatus().bIsRunning = FALSE;
407 BasicIDE::StopBasic();
409 else
410 bCanModify = FALSE;
412 return bCanModify;
415 void __EXPORT EditorWindow::KeyInput( const KeyEvent& rKEvt )
417 if ( !pEditView ) // Passiert unter W95 bei letzte Version, Ctrl-Tab
418 return;
420 #if OSL_DEBUG_LEVEL > 1
421 Range aRange = pModulWindow->GetHScrollBar()->GetRange(); (void)aRange;
422 long nVisSz = pModulWindow->GetHScrollBar()->GetVisibleSize(); (void)nVisSz;
423 long nPapSz = pModulWindow->GetHScrollBar()->GetPageSize(); (void)nPapSz;
424 long nLinSz = pModulWindow->GetHScrollBar()->GetLineSize(); (void)nLinSz;
425 long nThumb = pModulWindow->GetHScrollBar()->GetThumbPos(); (void)nThumb;
426 #endif
427 BOOL bDone = FALSE;
428 BOOL bWasModified = pEditEngine->IsModified();
429 if ( !TextEngine::DoesKeyChangeText( rKEvt ) || ImpCanModify() )
431 if ( ( rKEvt.GetKeyCode().GetCode() == KEY_A) && rKEvt.GetKeyCode().IsMod1() )
432 pEditView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
433 else if ( ( rKEvt.GetKeyCode().GetCode() == KEY_Y ) && rKEvt.GetKeyCode().IsMod1() )
434 bDone = TRUE; // CTRL-Y schlucken, damit kein Vorlagenkatalog
435 else
437 if ( ( rKEvt.GetKeyCode().GetCode() == KEY_TAB ) && !rKEvt.GetKeyCode().IsMod1() &&
438 !rKEvt.GetKeyCode().IsMod2() && !GetEditView()->IsReadOnly() )
440 TextSelection aSel( pEditView->GetSelection() );
441 if ( aSel.GetStart().GetPara() != aSel.GetEnd().GetPara() )
443 bDelayHighlight = FALSE;
444 if ( !rKEvt.GetKeyCode().IsShift() )
445 pEditView->IndentBlock();
446 else
447 pEditView->UnindentBlock();
448 bDelayHighlight = TRUE;
449 bDone = TRUE;
452 if ( !bDone )
453 bDone = pEditView->KeyInput( rKEvt );
456 if ( !bDone )
458 if ( !SfxViewShell::Current()->KeyInput( rKEvt ) )
459 Window::KeyInput( rKEvt );
461 else
463 SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
464 if ( pBindings )
466 pBindings->Invalidate( SID_BASICIDE_STAT_POS );
467 if ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_CURSOR )
468 pBindings->Update( SID_BASICIDE_STAT_POS );
469 if ( !bWasModified && pEditEngine->IsModified() )
471 pBindings->Invalidate( SID_SAVEDOC );
472 pBindings->Invalidate( SID_DOC_MODIFIED );
474 if ( rKEvt.GetKeyCode().GetCode() == KEY_INSERT )
475 pBindings->Invalidate( SID_ATTR_INSERT );
480 void __EXPORT EditorWindow::Paint( const Rectangle& rRect )
482 if ( !pEditEngine ) // spaetestens jetzt brauche ich sie...
483 CreateEditEngine();
485 pEditView->Paint( rRect );
488 void __EXPORT EditorWindow::LoseFocus()
490 SetSourceInBasic();
491 Window::LoseFocus();
494 BOOL EditorWindow::SetSourceInBasic( BOOL bQuiet )
496 (void)bQuiet;
498 BOOL bChanged = FALSE;
499 if ( pEditEngine && pEditEngine->IsModified()
500 && !GetEditView()->IsReadOnly() ) // Added because of #i60626, otherwise
501 // any read only bug in the text engine could lead to a crash later
503 if ( !StarBASIC::IsRunning() ) // Nicht zur Laufzeit!
505 ::rtl::OUString aModule = getTextEngineText( pEditEngine );
507 // update module in basic
508 #ifdef DBG_UTIL
509 SbModule* pModule = pModulWindow->GetSbModule();
510 #endif
511 DBG_ASSERT(pModule, "EditorWindow::SetSourceInBasic: No Module found!");
513 // update module in module window
514 pModulWindow->SetModule( aModule );
516 // update module in library
517 ScriptDocument aDocument( pModulWindow->GetDocument() );
518 String aLibName = pModulWindow->GetLibName();
519 String aName = pModulWindow->GetName();
520 OSL_VERIFY( aDocument.updateModule( aLibName, aName, aModule ) );
522 pEditEngine->SetModified( FALSE );
523 BasicIDE::MarkDocumentModified( aDocument );
524 bChanged = TRUE;
527 return bChanged;
531 // Returns the position of the last character of any of the following
532 // EOL char combinations: CR, CR/LF, LF, return -1 if no EOL is found
533 sal_Int32 searchEOL( const ::rtl::OUString& rStr, sal_Int32 fromIndex )
535 sal_Int32 iRetPos = -1;
537 sal_Int32 iLF = rStr.indexOf( LINE_SEP, fromIndex );
538 if( iLF != -1 )
540 iRetPos = iLF;
542 else
544 iRetPos = rStr.indexOf( LINE_SEP_CR, fromIndex );
546 return iRetPos;
550 void EditorWindow::CreateEditEngine()
552 if ( pEditEngine )
553 return;
555 pEditEngine = new ExtTextEngine;
556 pEditView = new ExtTextView( pEditEngine, this );
557 pEditView->SetAutoIndentMode( TRUE );
558 pEditEngine->SetUpdateMode( FALSE );
559 pEditEngine->InsertView( pEditView );
561 ImplSetFont();
563 aSyntaxIdleTimer.SetTimeout( 200 );
564 aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, EditorWindow, SyntaxTimerHdl ) );
566 aHighlighter.initialize( HIGHLIGHT_BASIC );
568 BOOL bWasDoSyntaxHighlight = bDoSyntaxHighlight;
569 bDoSyntaxHighlight = FALSE; // Bei grossen Texten zu langsam...
570 ::rtl::OUString aOUSource( pModulWindow->GetModule() );
571 sal_Int32 nLines = 0;
572 sal_Int32 nIndex = -1;
575 nLines++;
576 nIndex = searchEOL( aOUSource, nIndex+1 );
578 while ( nIndex >= 0 );
580 // nLines*4: SetText+Formatting+DoHighlight+Formatting
581 // 1 Formatting koennte eingespart werden, aber dann wartet man
582 // bei einem langen Sourcecode noch laenger auf den Text...
583 pProgress = new ProgressInfo( IDE_DLL()->GetShell()->GetViewFrame()->GetObjectShell(), String( IDEResId( RID_STR_GENERATESOURCE ) ), nLines*4 );
584 setTextEngineText( pEditEngine, aOUSource );
586 pEditView->SetStartDocPos( Point( 0, 0 ) );
587 pEditView->SetSelection( TextSelection() );
588 pModulWindow->GetBreakPointWindow().GetCurYOffset() = 0;
589 pEditEngine->SetUpdateMode( TRUE );
590 Update(); // Es wurde bei UpdateMode = TRUE nur Invalidiert
592 // Die anderen Fenster auch, damit keine halben Sachen auf dem Bildschirm!
593 pModulWindow->GetLayout()->GetWatchWindow().Update();
594 pModulWindow->GetLayout()->GetStackWindow().Update();
595 pModulWindow->GetBreakPointWindow().Update();
597 pEditView->ShowCursor( TRUE, TRUE );
599 StartListening( *pEditEngine );
601 // Das Syntax-Highlightning legt ein rel. groesse VDev an.
602 aSyntaxIdleTimer.Stop();
603 bDoSyntaxHighlight = bWasDoSyntaxHighlight;
606 for ( USHORT nLine = 0; nLine < nLines; nLine++ )
607 aSyntaxLineTable.Insert( nLine, (void*)(USHORT)1 );
608 ForceSyntaxTimeout();
610 DELETEZ( pProgress );
612 pEditView->EraseVirtualDevice();
613 pEditEngine->SetModified( FALSE );
614 pEditEngine->EnableUndo( TRUE );
616 InitScrollBars();
618 SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
619 if ( pBindings )
620 pBindings->Invalidate( SID_BASICIDE_STAT_POS );
622 DBG_ASSERT( pModulWindow->GetBreakPointWindow().GetCurYOffset() == 0, "CreateEditEngine: Brechpunkte verschoben?" );
624 // set readonly mode for readonly libraries
625 ScriptDocument aDocument( pModulWindow->GetDocument() );
626 ::rtl::OUString aOULibName( pModulWindow->GetLibName() );
627 Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
628 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && xModLibContainer->isLibraryReadOnly( aOULibName ) )
630 pModulWindow->SetReadOnly( TRUE );
633 if ( aDocument.isDocument() && aDocument.isReadOnly() )
634 pModulWindow->SetReadOnly( TRUE );
637 // virtual
638 void EditorWindow::DataChanged(DataChangedEvent const & rDCEvt)
640 Window::DataChanged(rDCEvt);
641 if (rDCEvt.GetType() == DATACHANGED_SETTINGS
642 && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
644 Color aColor(GetSettings().GetStyleSettings().GetFieldColor());
645 if (aColor
646 != rDCEvt.GetOldSettings()->GetStyleSettings().GetFieldColor())
648 SetBackground(Wallpaper(aColor));
649 Invalidate();
651 if (pEditEngine != 0)
653 aColor = GetSettings().GetStyleSettings().GetFieldTextColor();
654 if (aColor != rDCEvt.GetOldSettings()->
655 GetStyleSettings().GetFieldTextColor())
657 Font aFont(pEditEngine->GetFont());
658 aFont.SetColor(aColor);
659 pEditEngine->SetFont(aFont);
665 void EditorWindow::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
667 if ( rHint.ISA( TextHint ) )
669 const TextHint& rTextHint = (const TextHint&)rHint;
670 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
672 if ( pModulWindow->GetHScrollBar() )
673 pModulWindow->GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
674 pModulWindow->GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
675 pModulWindow->GetBreakPointWindow().DoScroll
676 ( 0, pModulWindow->GetBreakPointWindow().GetCurYOffset() - pEditView->GetStartDocPos().Y() );
678 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
680 if ( pEditView->GetStartDocPos().Y() )
682 long nOutHeight = GetOutputSizePixel().Height();
683 long nTextHeight = pEditEngine->GetTextHeight();
684 if ( nTextHeight < nOutHeight )
685 pEditView->Scroll( 0, pEditView->GetStartDocPos().Y() );
688 SetScrollBarRanges();
690 else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
692 if ( pModulWindow->GetHScrollBar() )
694 ULONG nWidth = pEditEngine->CalcTextWidth();
695 if ( (long)nWidth != nCurTextWidth )
697 nCurTextWidth = nWidth;
698 pModulWindow->GetHScrollBar()->SetRange( Range( 0, (long)nCurTextWidth-1) );
699 pModulWindow->GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
702 long nPrevTextWidth = nCurTextWidth;
703 nCurTextWidth = pEditEngine->CalcTextWidth();
704 if ( nCurTextWidth != nPrevTextWidth )
705 SetScrollBarRanges();
707 else if( rTextHint.GetId() == TEXT_HINT_PARAINSERTED )
709 ParagraphInsertedDeleted( rTextHint.GetValue(), TRUE );
710 DoDelayedSyntaxHighlight( rTextHint.GetValue() );
712 else if( rTextHint.GetId() == TEXT_HINT_PARAREMOVED )
714 ParagraphInsertedDeleted( rTextHint.GetValue(), FALSE );
716 else if( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED )
718 DoDelayedSyntaxHighlight( rTextHint.GetValue() );
721 else if ( &rBC == pSourceViewConfig )
723 ImplSetFont();
727 void EditorWindow::SetScrollBarRanges()
729 // Extra-Methode, nicht InitScrollBars, da auch fuer EditEngine-Events.
730 if ( !pEditEngine )
731 return;
733 if ( pModulWindow->GetHScrollBar() )
734 pModulWindow->GetHScrollBar()->SetRange( Range( 0, nCurTextWidth-1 ) );
736 pModulWindow->GetEditVScrollBar().SetRange( Range( 0, pEditEngine->GetTextHeight()-1 ) );
739 void EditorWindow::InitScrollBars()
741 if ( !pEditEngine )
742 return;
744 SetScrollBarRanges();
745 Size aOutSz( GetOutputSizePixel() );
746 pModulWindow->GetEditVScrollBar().SetVisibleSize( aOutSz.Height() );
747 pModulWindow->GetEditVScrollBar().SetPageSize( aOutSz.Height() * 8 / 10 );
748 pModulWindow->GetEditVScrollBar().SetLineSize( GetTextHeight() );
749 pModulWindow->GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
750 pModulWindow->GetEditVScrollBar().Show();
752 if ( pModulWindow->GetHScrollBar() )
754 pModulWindow->GetHScrollBar()->SetVisibleSize( aOutSz.Width() );
755 pModulWindow->GetHScrollBar()->SetPageSize( aOutSz.Width() * 8 / 10 );
756 pModulWindow->GetHScrollBar()->SetLineSize( GetTextWidth( 'x' ) );
757 pModulWindow->GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
758 pModulWindow->GetHScrollBar()->Show();
762 void EditorWindow::ImpDoHighlight( ULONG nLine )
764 if ( bDoSyntaxHighlight )
766 String aLine( pEditEngine->GetText( nLine ) );
767 Range aChanges = aHighlighter.notifyChange( nLine, 0, &aLine, 1 );
768 if ( aChanges.Len() )
770 for ( long n = aChanges.Min() + 1; n <= aChanges.Max(); n++ )
771 aSyntaxLineTable.Insert( n, (void*)(ULONG)1 );
772 aSyntaxIdleTimer.Start();
775 BOOL bWasModified = pEditEngine->IsModified();
776 pEditEngine->RemoveAttribs( nLine, TRUE );
777 HighlightPortions aPortions;
778 aHighlighter.getHighlightPortions( nLine, aLine, aPortions );
779 USHORT nCount = aPortions.Count();
780 for ( USHORT i = 0; i < nCount; i++ )
782 HighlightPortion& r = aPortions[i];
783 const Color& rColor = ((ModulWindowLayout*)pModulWindow->GetLayoutWindow())->getSyntaxColor(r.tokenType);
784 pEditEngine->SetAttrib( TextAttribFontColor( rColor ), nLine, r.nBegin, r.nEnd, TRUE );
787 // Das Highlighten soll kein Modify setzen
788 pEditEngine->SetModified( bWasModified );
792 void EditorWindow::ImplSetFont()
794 if ( pSourceViewConfig )
796 String sFontName = pSourceViewConfig->GetFontName();
797 if ( !sFontName.Len() )
799 Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, Application::GetSettings().GetUILanguage(), 0 , this ) );
800 sFontName = aTmpFont.GetName();
802 Size aFontSize( 0, pSourceViewConfig->GetFontHeight() );
803 Font aFont( sFontName, aFontSize );
804 aFont.SetColor( GetSettings().GetStyleSettings().GetFieldTextColor() );
805 SetPointFont( aFont );
806 aFont = GetFont();
808 if ( pModulWindow )
809 pModulWindow->GetBreakPointWindow().SetFont( aFont );
811 if ( pEditEngine )
813 BOOL bModified = pEditEngine->IsModified();
814 pEditEngine->SetFont( aFont );
815 pEditEngine->SetModified( bModified );
820 void EditorWindow::DoSyntaxHighlight( ULONG nPara )
822 // Durch das DelayedSyntaxHighlight kann es passieren,
823 // dass die Zeile nicht mehr existiert!
824 if ( nPara < pEditEngine->GetParagraphCount() )
826 // leider weis ich nicht, ob genau diese Zeile Modified() ...
827 if ( pProgress )
828 pProgress->StepProgress();
829 ImpDoHighlight( nPara );
833 void EditorWindow::DoDelayedSyntaxHighlight( ULONG nPara )
835 // Zeile wird nur in 'Liste' aufgenommen, im TimerHdl abgearbeitet.
836 // => Nicht Absaetze manipulieren, waehrend EditEngine formatiert.
837 if ( pProgress )
838 pProgress->StepProgress();
840 if ( !bHighlightning && bDoSyntaxHighlight )
842 if ( bDelayHighlight )
844 aSyntaxLineTable.Insert( nPara, (void*)(ULONG)1 );
845 aSyntaxIdleTimer.Start();
847 else
848 DoSyntaxHighlight( nPara );
852 IMPL_LINK( EditorWindow, SyntaxTimerHdl, Timer *, EMPTYARG )
854 DBG_ASSERT( pEditView, "Noch keine View, aber Syntax-Highlight ?!" );
856 BOOL bWasModified = pEditEngine->IsModified();
857 // pEditEngine->SetUpdateMode( FALSE );
859 bHighlightning = TRUE;
860 USHORT nLine;
861 void* p = aSyntaxLineTable.First();
862 while ( p )
864 nLine = (USHORT)aSyntaxLineTable.GetCurKey();
865 DoSyntaxHighlight( nLine );
866 p = aSyntaxLineTable.Next();
869 // MT: Removed, because of idle format now when set/remove attribs...
870 // pEditView->SetAutoScroll( FALSE ); // #101043# Don't scroll because of syntax highlight
871 // pEditEngine->SetUpdateMode( TRUE );
872 // pEditView->ShowCursor( FALSE, TRUE );
873 // pEditView->SetAutoScroll( TRUE );
875 // #i45572#
876 if ( pEditView )
877 pEditView->ShowCursor( FALSE, TRUE );
879 pEditEngine->SetModified( bWasModified );
881 aSyntaxLineTable.Clear();
882 bHighlightning = FALSE;
884 return 0;
887 void EditorWindow::ParagraphInsertedDeleted( ULONG nPara, BOOL bInserted )
889 if ( pProgress )
890 pProgress->StepProgress();
892 if ( !bInserted && ( nPara == TEXT_PARA_ALL ) )
894 pModulWindow->GetBreakPoints().reset();
895 pModulWindow->GetBreakPointWindow().Invalidate();
896 aHighlighter.initialize( HIGHLIGHT_BASIC );
898 else
900 // Brechpunkte Aktualisieren...
901 // keine Sonderbehandlung fuer EditEngine-CTOR ( Erste-Zeile-Problem ),
902 // da in diesem Moment noch keine BreakPoints.
903 // +1: Basic-Zeilen beginnen bei 1!
904 pModulWindow->GetBreakPoints().AdjustBreakPoints( (USHORT)nPara+1, bInserted );
906 // Im BreakPointWindow invalidieren...
907 long nLineHeight = GetTextHeight();
908 Size aSz = pModulWindow->GetBreakPointWindow().GetOutputSize();
909 Rectangle aInvRec( Point( 0, 0 ), aSz );
910 long nY = nPara*nLineHeight - pModulWindow->GetBreakPointWindow().GetCurYOffset();
911 aInvRec.Top() = nY;
912 pModulWindow->GetBreakPointWindow().Invalidate( aInvRec );
914 if ( bDoSyntaxHighlight )
916 String aDummy;
917 aHighlighter.notifyChange( nPara, bInserted ? 1 : (-1), &aDummy, 1 );
922 void EditorWindow::CreateProgress( const String& rText, ULONG nRange )
924 DBG_ASSERT( !pProgress, "ProgressInfo existiert schon" );
925 pProgress = new ProgressInfo( IDE_DLL()->GetShell()->GetViewFrame()->GetObjectShell(), rText, nRange );
928 void EditorWindow::DestroyProgress()
930 DELETEZ( pProgress );
933 void EditorWindow::ForceSyntaxTimeout()
935 aSyntaxIdleTimer.Stop();
936 ((Link&)aSyntaxIdleTimer.GetTimeoutHdl()).Call( &aSyntaxIdleTimer );
941 BreakPointWindow::BreakPointWindow( Window* pParent ) :
942 Window( pParent, WB_BORDER )
944 pModulWindow = 0;
945 nCurYOffset = 0;
946 setBackgroundColor(GetSettings().GetStyleSettings().GetFieldColor());
947 nMarkerPos = MARKER_NOMARKER;
949 // nCurYOffset merken und nicht von EditEngine holen.
950 // Falls in EditEngine autom. gescrollt wurde, wuesste ich sonst nicht,
951 // wo ich gerade stehe.
953 SetHelpId( HID_BASICIDE_BREAKPOINTWINDOW );
958 __EXPORT BreakPointWindow::~BreakPointWindow()
964 void __EXPORT BreakPointWindow::Resize()
966 /// Invalidate();
971 void __EXPORT BreakPointWindow::Paint( const Rectangle& )
973 if ( SyncYOffset() )
974 return;
976 Size aOutSz( GetOutputSize() );
977 long nLineHeight = GetTextHeight();
979 Image aBrk1(((ModulWindowLayout *) pModulWindow->GetLayoutWindow())->
980 getImage(IMGID_BRKENABLED, m_bHighContrastMode));
981 Image aBrk0(((ModulWindowLayout *) pModulWindow->GetLayoutWindow())->
982 getImage(IMGID_BRKDISABLED, m_bHighContrastMode));
983 Size aBmpSz( aBrk1.GetSizePixel() );
984 aBmpSz = PixelToLogic( aBmpSz );
985 Point aBmpOff( 0, 0 );
986 aBmpOff.X() = ( aOutSz.Width() - aBmpSz.Width() ) / 2;
987 aBmpOff.Y() = ( nLineHeight - aBmpSz.Height() ) / 2;
989 BreakPoint* pBrk = GetBreakPoints().First();
990 while ( pBrk )
992 ULONG nLine = pBrk->nLine-1;
993 ULONG nY = nLine*nLineHeight - nCurYOffset;
994 DrawImage( Point( 0, nY ) + aBmpOff, pBrk->bEnabled ? aBrk1 : aBrk0 );
995 pBrk = GetBreakPoints().Next();
997 ShowMarker( TRUE );
1002 void BreakPointWindow::DoScroll( long nHorzScroll, long nVertScroll )
1004 nCurYOffset -= nVertScroll;
1005 Window::Scroll( nHorzScroll, nVertScroll );
1010 void BreakPointWindow::SetMarkerPos( USHORT nLine, BOOL bError )
1012 if ( SyncYOffset() )
1013 Update();
1015 ShowMarker( FALSE ); // Alten wegzeichen...
1016 nMarkerPos = nLine;
1017 bErrorMarker = bError;
1018 ShowMarker( TRUE ); // Neuen zeichnen...
1021 void BreakPointWindow::ShowMarker( BOOL bShow )
1023 if ( nMarkerPos == MARKER_NOMARKER )
1024 return;
1026 Size aOutSz( GetOutputSize() );
1027 long nLineHeight = GetTextHeight();
1029 Image aMarker(((ModulWindowLayout*)pModulWindow->GetLayoutWindow())->
1030 getImage(bErrorMarker
1031 ? IMGID_ERRORMARKER : IMGID_STEPMARKER,
1032 m_bHighContrastMode));
1034 Size aMarkerSz( aMarker.GetSizePixel() );
1035 aMarkerSz = PixelToLogic( aMarkerSz );
1036 Point aMarkerOff( 0, 0 );
1037 aMarkerOff.X() = ( aOutSz.Width() - aMarkerSz.Width() ) / 2;
1038 aMarkerOff.Y() = ( nLineHeight - aMarkerSz.Height() ) / 2;
1040 ULONG nY = nMarkerPos*nLineHeight - nCurYOffset;
1041 Point aPos( 0, nY );
1042 aPos += aMarkerOff;
1043 if ( bShow )
1044 DrawImage( aPos, aMarker );
1045 else
1046 Invalidate( Rectangle( aPos, aMarkerSz ) );
1052 BreakPoint* BreakPointWindow::FindBreakPoint( const Point& rMousePos )
1054 long nLineHeight = GetTextHeight();
1055 long nYPos = rMousePos.Y() + nCurYOffset;
1056 // Image aBrk( ((ModulWindowLayout*)pModulWindow->GetLayoutWindow())->GetImage( IMGID_BRKENABLED ) );
1057 // Size aBmpSz( aBrk.GetSizePixel() );
1058 // aBmpSz = PixelToLogic( aBmpSz );
1060 BreakPoint* pBrk = GetBreakPoints().First();
1061 while ( pBrk )
1063 ULONG nLine = pBrk->nLine-1;
1064 long nY = nLine*nLineHeight;
1065 if ( ( nYPos > nY ) && ( nYPos < ( nY + nLineHeight ) ) )
1066 return pBrk;
1067 pBrk = GetBreakPoints().Next();
1069 return 0;
1072 void __EXPORT BreakPointWindow::MouseButtonDown( const MouseEvent& rMEvt )
1074 if ( rMEvt.GetClicks() == 2 )
1076 Point aMousePos( PixelToLogic( rMEvt.GetPosPixel() ) );
1077 long nLineHeight = GetTextHeight();
1078 long nYPos = aMousePos.Y() + nCurYOffset;
1079 long nLine = nYPos / nLineHeight + 1;
1080 pModulWindow->ToggleBreakPoint( (ULONG)nLine );
1081 // vielleicht mal etwas genauer...
1082 Invalidate();
1088 void __EXPORT BreakPointWindow::Command( const CommandEvent& rCEvt )
1090 if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
1092 Point aPos( rCEvt.IsMouseEvent() ? rCEvt.GetMousePosPixel() : Point(1,1) );
1093 Point aEventPos( PixelToLogic( aPos ) );
1094 BreakPoint* pBrk = rCEvt.IsMouseEvent() ? FindBreakPoint( aEventPos ) : 0;
1095 if ( pBrk )
1097 // prueffen, ob Brechpunkt enabled....
1098 PopupMenu aBrkPropMenu( IDEResId( RID_POPUP_BRKPROPS ) );
1099 aBrkPropMenu.CheckItem( RID_ACTIV, pBrk->bEnabled );
1100 switch ( aBrkPropMenu.Execute( this, aPos ) )
1102 case RID_ACTIV:
1104 pBrk->bEnabled = pBrk->bEnabled ? FALSE : TRUE;
1105 pModulWindow->UpdateBreakPoint( *pBrk );
1106 Invalidate();
1108 break;
1109 case RID_BRKPROPS:
1111 BreakPointDialog aBrkDlg( this, GetBreakPoints() );
1112 aBrkDlg.SetCurrentBreakPoint( pBrk );
1113 aBrkDlg.Execute();
1114 Invalidate();
1116 break;
1119 else
1121 PopupMenu aBrkListMenu( IDEResId( RID_POPUP_BRKDLG ) );
1122 switch ( aBrkListMenu.Execute( this, aPos ) )
1124 case RID_BRKDLG:
1126 BreakPointDialog aBrkDlg( this, GetBreakPoints() );
1127 aBrkDlg.Execute();
1128 Invalidate();
1130 break;
1136 BOOL BreakPointWindow::SyncYOffset()
1138 TextView* pView = pModulWindow->GetEditView();
1139 if ( pView )
1141 long nViewYOffset = pView->GetStartDocPos().Y();
1142 if ( nCurYOffset != nViewYOffset )
1144 nCurYOffset = nViewYOffset;
1145 Invalidate();
1146 return TRUE;
1149 return FALSE;
1152 // virtual
1153 void BreakPointWindow::DataChanged(DataChangedEvent const & rDCEvt)
1155 Window::DataChanged(rDCEvt);
1156 if (rDCEvt.GetType() == DATACHANGED_SETTINGS
1157 && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
1159 Color aColor(GetSettings().GetStyleSettings().GetFieldColor());
1160 if (aColor
1161 != rDCEvt.GetOldSettings()->GetStyleSettings().GetFieldColor())
1163 setBackgroundColor(aColor);
1164 Invalidate();
1169 void BreakPointWindow::setBackgroundColor(Color aColor)
1171 SetBackground(Wallpaper(aColor));
1172 m_bHighContrastMode = aColor.IsDark();
1176 const USHORT ITEM_ID_VARIABLE = 1;
1177 const USHORT ITEM_ID_VALUE = 2;
1178 const USHORT ITEM_ID_TYPE = 3;
1180 WatchWindow::WatchWindow( Window* pParent ) :
1181 BasicDockingWindow( pParent ),
1182 aWatchStr( IDEResId( RID_STR_REMOVEWATCH ) ),
1183 aXEdit( this, IDEResId( RID_EDT_WATCHEDIT ) ),
1184 aRemoveWatchButton( this, IDEResId( RID_IMGBTN_REMOVEWATCH ) ),
1185 aTreeListBox( this, WB_BORDER | WB_3DLOOK | WB_HASBUTTONS | WB_HASLINES | WB_HSCROLL | WB_TABSTOP
1186 | WB_HASLINESATROOT | WB_HASBUTTONSATROOT ),
1187 aHeaderBar( this, WB_BUTTONSTYLE | WB_BORDER )
1189 nVirtToolBoxHeight = aXEdit.GetSizePixel().Height() + 7;
1190 nHeaderBarHeight = 16;
1192 aTreeListBox.SetHelpId(HID_BASICIDE_WATCHWINDOW_LIST);
1193 aTreeListBox.EnableInplaceEditing( TRUE );
1194 aTreeListBox.SetSelectHdl( LINK( this, WatchWindow, TreeListHdl ) );
1195 aTreeListBox.SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight + nHeaderBarHeight ) );
1196 aTreeListBox.SetHighlightRange( 1, 5 );
1198 Point aPnt( DWBORDER, nVirtToolBoxHeight + 1 );
1199 aHeaderBar.SetPosPixel( aPnt );
1200 aHeaderBar.SetEndDragHdl( LINK( this, WatchWindow, implEndDragHdl ) );
1202 long nVarTabWidth = 220;
1203 long nValueTabWidth = 100;
1204 long nTypeTabWidth = 1250;
1205 aHeaderBar.InsertItem( ITEM_ID_VARIABLE, String( IDEResId( RID_STR_WATCHVARIABLE ) ), nVarTabWidth );
1206 aHeaderBar.InsertItem( ITEM_ID_VALUE, String( IDEResId( RID_STR_WATCHVALUE ) ), nValueTabWidth );
1207 aHeaderBar.InsertItem( ITEM_ID_TYPE, String( IDEResId( RID_STR_WATCHTYPE ) ), nTypeTabWidth );
1209 long tabs[ 4 ];
1210 tabs[ 0 ] = 3; // two tabs
1211 tabs[ 1 ] = 0;
1212 tabs[ 2 ] = nVarTabWidth;
1213 tabs[ 3 ] = nVarTabWidth + nValueTabWidth;
1214 aTreeListBox.SvHeaderTabListBox::SetTabs( tabs, MAP_PIXEL );
1215 aTreeListBox.InitHeaderBar( &aHeaderBar );
1217 aTreeListBox.SetNodeDefaultImages( );
1219 aHeaderBar.Show();
1221 aRemoveWatchButton.Disable();
1223 aTreeListBox.Show();
1225 long nTextLen = GetTextWidth( aWatchStr ) + DWBORDER;
1226 aXEdit.SetPosPixel( Point( nTextLen, 3 ) );
1227 aXEdit.SetAccHdl( LINK( this, WatchWindow, EditAccHdl ) );
1228 aXEdit.GetAccelerator().InsertItem( 1, KeyCode( KEY_RETURN ) );
1229 aXEdit.GetAccelerator().InsertItem( 2, KeyCode( KEY_ESCAPE ) );
1230 aXEdit.Show();
1232 aRemoveWatchButton.SetModeImage(Image(IDEResId(RID_IMG_REMOVEWATCH_HC)),
1233 BMP_COLOR_HIGHCONTRAST);
1234 aRemoveWatchButton.SetClickHdl( LINK( this, WatchWindow, ButtonHdl ) );
1235 aRemoveWatchButton.SetPosPixel( Point( nTextLen + aXEdit.GetSizePixel().Width() + 4, 2 ) );
1236 Size aSz( aRemoveWatchButton.GetModeImage().GetSizePixel() );
1237 aSz.Width() += 6;
1238 aSz.Height() += 6;
1239 aRemoveWatchButton.SetSizePixel( aSz );
1240 aRemoveWatchButton.Show();
1242 SetText( String( IDEResId( RID_STR_WATCHNAME ) ) );
1244 SetHelpId( HID_BASICIDE_WATCHWINDOW );
1246 // make watch window keyboard accessible
1247 GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
1252 __EXPORT WatchWindow::~WatchWindow()
1254 GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
1259 void __EXPORT WatchWindow::Paint( const Rectangle& )
1261 DrawText( Point( DWBORDER, 7 ), aWatchStr );
1262 lcl_DrawIDEWindowFrame( this );
1267 void __EXPORT WatchWindow::Resize()
1269 Size aSz = GetOutputSizePixel();
1270 Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );
1272 if ( aBoxSz.Width() < 4 ) // < 4, weil noch Border...
1273 aBoxSz.Width() = 0;
1274 if ( aBoxSz.Height() < 4 )
1275 aBoxSz.Height() = 0;
1277 aBoxSz.Height() -= nHeaderBarHeight;
1278 aTreeListBox.SetSizePixel( aBoxSz );
1279 aTreeListBox.GetHScroll()->SetPageSize( aTreeListBox.GetHScroll()->GetVisibleSize() );
1281 aBoxSz.Height() = nHeaderBarHeight;
1282 aHeaderBar.SetSizePixel( aBoxSz );
1284 Invalidate(); //Wegen DrawLine im Paint...
1287 struct MemberList
1289 String* mpMemberNames;
1290 int mnMemberCount;
1292 MemberList( void )
1293 : mpMemberNames( NULL )
1294 , mnMemberCount( 0 )
1296 ~MemberList()
1298 clear();
1301 void clear( void );
1302 void allocList( int nCount );
1305 void MemberList::clear( void )
1307 if( mnMemberCount )
1309 delete[] mpMemberNames;
1310 mnMemberCount = 0;
1314 void MemberList::allocList( int nCount )
1316 clear();
1317 if( nCount > 0 )
1319 mnMemberCount = nCount;
1320 mpMemberNames = new String[ mnMemberCount ];
1324 struct WatchItem
1326 String maName;
1327 String maDisplayName;
1328 SbxObjectRef mpObject;
1329 MemberList maMemberList;
1331 SbxDimArrayRef mpArray;
1332 int nDimLevel; // 0 = Root
1333 int nDimCount;
1334 short* pIndices;
1336 WatchItem* mpArrayParentItem;
1338 WatchItem( void )
1339 : nDimLevel( 0 )
1340 , nDimCount( 0 )
1341 , pIndices( NULL )
1342 , mpArrayParentItem( NULL )
1344 ~WatchItem()
1345 { clearWatchItem(); }
1347 void clearWatchItem( bool bIncludeArrayData=true )
1349 mpObject = NULL;
1350 maMemberList.clear();
1351 if( bIncludeArrayData )
1353 mpArray = NULL;
1354 nDimLevel = 0;
1355 nDimCount = 0;
1356 delete[] pIndices;
1357 pIndices = NULL;
1361 WatchItem* GetRootItem( void );
1362 SbxDimArray* GetRootArray( void );
1365 WatchItem* WatchItem::GetRootItem( void )
1367 WatchItem* pItem = mpArrayParentItem;
1368 while( pItem )
1370 if( pItem->mpArray.Is() )
1371 break;
1372 pItem = pItem->mpArrayParentItem;
1374 return pItem;
1377 SbxDimArray* WatchItem::GetRootArray( void )
1379 WatchItem* pRootItem = GetRootItem();
1380 SbxDimArray* pRet = NULL;
1381 if( pRootItem )
1382 pRet = pRootItem->mpArray;
1383 return pRet;
1386 void WatchWindow::AddWatch( const String& rVName )
1388 WatchItem* pWatchItem = new WatchItem;
1389 String aVar, aIndex;
1390 lcl_SeparateNameAndIndex( rVName, aVar, aIndex );
1391 pWatchItem->maName = aVar;
1393 String aWatchStr_( aVar );
1394 aWatchStr_ += String( RTL_CONSTASCII_USTRINGPARAM( "\t\t" ) );
1395 SvLBoxEntry* pNewEntry = aTreeListBox.InsertEntry( aWatchStr_, 0, TRUE, LIST_APPEND );
1396 pNewEntry->SetUserData( pWatchItem );
1398 aTreeListBox.Select( pNewEntry, TRUE );
1399 aTreeListBox.MakeVisible( pNewEntry );
1400 aRemoveWatchButton.Enable();
1403 BOOL WatchWindow::RemoveSelectedWatch()
1405 SvLBoxEntry* pEntry = aTreeListBox.GetCurEntry();
1406 if ( pEntry )
1408 aTreeListBox.GetModel()->Remove( pEntry );
1409 pEntry = aTreeListBox.GetCurEntry();
1410 if ( pEntry )
1411 aXEdit.SetText( ((WatchItem*)pEntry->GetUserData())->maName );
1412 else
1413 aXEdit.SetText( String() );
1414 if ( !aTreeListBox.GetEntryCount() )
1415 aRemoveWatchButton.Disable();
1416 return TRUE;
1418 else
1419 return FALSE;
1423 IMPL_LINK_INLINE_START( WatchWindow, ButtonHdl, ImageButton *, pButton )
1425 if ( pButton == &aRemoveWatchButton )
1427 BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
1428 SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
1429 SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
1430 if( pDispatcher )
1432 pDispatcher->Execute( SID_BASICIDE_REMOVEWATCH );
1435 return 0;
1437 IMPL_LINK_INLINE_END( WatchWindow, ButtonHdl, ImageButton *, pButton )
1441 IMPL_LINK_INLINE_START( WatchWindow, TreeListHdl, SvTreeListBox *, EMPTYARG )
1443 SvLBoxEntry* pCurEntry = aTreeListBox.GetCurEntry();
1444 if ( pCurEntry && pCurEntry->GetUserData() )
1445 aXEdit.SetText( ((WatchItem*)pCurEntry->GetUserData())->maName );
1447 return 0;
1449 IMPL_LINK_INLINE_END( WatchWindow, TreeListHdl, SvTreeListBox *, EMPTYARG )
1452 IMPL_LINK_INLINE_START( WatchWindow, implEndDragHdl, HeaderBar *, pBar )
1454 (void)pBar;
1456 const sal_Int32 TAB_WIDTH_MIN = 10;
1457 sal_Int32 nMaxWidth =
1458 aHeaderBar.GetSizePixel().getWidth() - 2 * TAB_WIDTH_MIN;
1460 sal_Int32 nVariableWith = aHeaderBar.GetItemSize( ITEM_ID_VARIABLE );
1461 if( nVariableWith < TAB_WIDTH_MIN )
1462 aHeaderBar.SetItemSize( ITEM_ID_VARIABLE, TAB_WIDTH_MIN );
1463 else if( nVariableWith > nMaxWidth )
1464 aHeaderBar.SetItemSize( ITEM_ID_VARIABLE, nMaxWidth );
1466 sal_Int32 nValueWith = aHeaderBar.GetItemSize( ITEM_ID_VALUE );
1467 if( nValueWith < TAB_WIDTH_MIN )
1468 aHeaderBar.SetItemSize( ITEM_ID_VALUE, TAB_WIDTH_MIN );
1469 else if( nValueWith > nMaxWidth )
1470 aHeaderBar.SetItemSize( ITEM_ID_VALUE, nMaxWidth );
1472 if (aHeaderBar.GetItemSize( ITEM_ID_TYPE ) < TAB_WIDTH_MIN)
1473 aHeaderBar.SetItemSize( ITEM_ID_TYPE, TAB_WIDTH_MIN );
1475 sal_Int32 nPos = 0;
1476 USHORT nTabs = aHeaderBar.GetItemCount();
1477 // OSL_ASSERT( m_treelb->TabCount() == nTabs );
1478 for( USHORT i = 1 ; i < nTabs ; ++i )
1480 nPos += aHeaderBar.GetItemSize( i );
1481 aTreeListBox.SetTab( i, nPos, MAP_PIXEL );
1483 return 0;
1485 IMPL_LINK_INLINE_END( WatchWindow, implEndDragHdl, HeaderBar *, pBar )
1488 IMPL_LINK( WatchWindow, EditAccHdl, Accelerator *, pAcc )
1490 switch ( pAcc->GetCurKeyCode().GetCode() )
1492 case KEY_RETURN:
1494 String aCurText( aXEdit.GetText() );
1495 if ( aCurText.Len() )
1497 AddWatch( aCurText );
1498 aXEdit.SetSelection( Selection( 0, 0xFFFF ) );
1499 UpdateWatches();
1501 else
1502 Sound::Beep();
1504 break;
1505 case KEY_ESCAPE:
1507 aXEdit.SetText( String() );
1509 break;
1512 return 0;
1515 void WatchWindow::UpdateWatches( bool bBasicStopped )
1517 aTreeListBox.UpdateWatches( bBasicStopped );
1521 StackWindow::StackWindow( Window* pParent ) :
1522 BasicDockingWindow( pParent ),
1523 aTreeListBox( this, WB_BORDER | WB_3DLOOK | WB_HSCROLL | WB_TABSTOP ),
1524 aGotoCallButton( this, IDEResId( RID_IMGBTN_GOTOCALL ) ),
1525 aStackStr( IDEResId( RID_STR_STACK ) )
1527 aTreeListBox.SetHelpId(HID_BASICIDE_STACKWINDOW_LIST);
1528 aTreeListBox.SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight ) );
1529 aTreeListBox.SetHighlightRange();
1530 aTreeListBox.SetSelectionMode( NO_SELECTION );
1531 aTreeListBox.InsertEntry( String(), 0, FALSE, LIST_APPEND );
1532 aTreeListBox.Show();
1534 SetText( String( IDEResId( RID_STR_STACKNAME ) ) );
1536 SetHelpId( HID_BASICIDE_STACKWINDOW );
1538 aGotoCallButton.SetClickHdl( LINK( this, StackWindow, ButtonHdl ) );
1539 aGotoCallButton.SetPosPixel( Point( DWBORDER, 2 ) );
1540 Size aSz( aGotoCallButton.GetModeImage().GetSizePixel() );
1541 aSz.Width() += 6;
1542 aSz.Height() += 6;
1543 aGotoCallButton.SetSizePixel( aSz );
1544 // aGotoCallButton.Show(); // wird vom Basic noch nicht unterstuetzt!
1545 aGotoCallButton.Hide();
1547 // make stack window keyboard accessible
1548 GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
1553 __EXPORT StackWindow::~StackWindow()
1555 GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
1560 void __EXPORT StackWindow::Paint( const Rectangle& )
1562 DrawText( Point( DWBORDER, 7 ), aStackStr );
1563 lcl_DrawIDEWindowFrame( this );
1568 void __EXPORT StackWindow::Resize()
1570 Size aSz = GetOutputSizePixel();
1571 Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );
1573 if ( aBoxSz.Width() < 4 ) // < 4, weil noch Border...
1574 aBoxSz.Width() = 0;
1575 if ( aBoxSz.Height() < 4 )
1576 aBoxSz.Height() = 0;
1578 aTreeListBox.SetSizePixel( aBoxSz );
1580 Invalidate(); //Wegen DrawLine im Paint...
1585 IMPL_LINK_INLINE_START( StackWindow, ButtonHdl, ImageButton *, pButton )
1587 if ( pButton == &aGotoCallButton )
1589 BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
1590 SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
1591 SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
1592 if( pDispatcher )
1594 pDispatcher->Execute( SID_BASICIDE_GOTOCALL );
1597 return 0;
1599 IMPL_LINK_INLINE_END( StackWindow, ButtonHdl, ImageButton *, pButton )
1603 void __EXPORT StackWindow::UpdateCalls()
1605 aTreeListBox.SetUpdateMode( FALSE );
1606 aTreeListBox.Clear();
1608 if ( StarBASIC::IsRunning() )
1610 SbxError eOld = SbxBase::GetError();
1611 aTreeListBox.SetSelectionMode( SINGLE_SELECTION );
1613 USHORT nScope = 0;
1614 SbMethod* pMethod = StarBASIC::GetActiveMethod( nScope );
1615 while ( pMethod )
1617 String aEntry( String::CreateFromInt32(nScope ));
1618 if ( aEntry.Len() < 2 )
1619 aEntry.Insert( ' ', 0 );
1620 aEntry += String( RTL_CONSTASCII_USTRINGPARAM( ": " ) );
1621 aEntry += pMethod->GetName();
1622 SbxArray* pParams = pMethod->GetParameters();
1623 SbxInfo* pInfo = pMethod->GetInfo();
1624 if ( pParams )
1626 aEntry += '(';
1627 // 0 ist der Name der Sub...
1628 for ( USHORT nParam = 1; nParam < pParams->Count(); nParam++ )
1630 SbxVariable* pVar = pParams->Get( nParam );
1631 DBG_ASSERT( pVar, "Parameter?!" );
1632 if ( pVar->GetName().Len() )
1633 aEntry += pVar->GetName();
1634 else if ( pInfo )
1636 const SbxParamInfo* pParam = pInfo->GetParam( nParam );
1637 if ( pParam )
1638 aEntry += pParam->aName;
1640 aEntry += '=';
1641 if( pVar->GetType() & SbxARRAY )
1642 aEntry += String( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
1643 else
1644 aEntry += pVar->GetString();
1645 if ( nParam < ( pParams->Count() - 1 ) )
1646 aEntry += String( RTL_CONSTASCII_USTRINGPARAM( ", " ) );
1648 aEntry += ')';
1650 aTreeListBox.InsertEntry( aEntry, 0, FALSE, LIST_APPEND );
1651 nScope++;
1652 pMethod = StarBASIC::GetActiveMethod( nScope );
1655 SbxBase::ResetError();
1656 if( eOld != SbxERR_OK )
1657 SbxBase::SetError( eOld );
1659 else
1661 aTreeListBox.SetSelectionMode( NO_SELECTION );
1662 aTreeListBox.InsertEntry( String(), 0, FALSE, LIST_APPEND );
1665 aTreeListBox.SetUpdateMode( TRUE );
1671 ComplexEditorWindow::ComplexEditorWindow( ModulWindow* pParent ) :
1672 Window( pParent, WB_3DLOOK | WB_CLIPCHILDREN ),
1673 aBrkWindow( this ),
1674 aEdtWindow( this ),
1675 aEWVScrollBar( this, WB_VSCROLL | WB_DRAG )
1677 aEdtWindow.SetModulWindow( pParent );
1678 aBrkWindow.SetModulWindow( pParent );
1679 aEdtWindow.Show();
1680 aBrkWindow.Show();
1682 aEWVScrollBar.SetLineSize( SCROLL_LINE );
1683 aEWVScrollBar.SetPageSize( SCROLL_PAGE );
1684 aEWVScrollBar.SetScrollHdl( LINK( this, ComplexEditorWindow, ScrollHdl ) );
1685 aEWVScrollBar.Show();
1690 void __EXPORT ComplexEditorWindow::Resize()
1692 Size aOutSz = GetOutputSizePixel();
1693 Size aSz( aOutSz );
1694 aSz.Width() -= 2*DWBORDER;
1695 aSz.Height() -= 2*DWBORDER;
1696 long nBrkWidth = 20;
1697 long nSBWidth = aEWVScrollBar.GetSizePixel().Width();
1699 Size aBrkSz( Size( nBrkWidth, aSz.Height() ) );
1700 aBrkWindow.SetPosSizePixel( Point( DWBORDER, DWBORDER ), aBrkSz );
1702 Size aEWSz( Size( aSz.Width() - nBrkWidth - nSBWidth + 2, aSz.Height() ) );
1703 aEdtWindow.SetPosSizePixel( Point( DWBORDER+aBrkSz.Width()-1, DWBORDER ), aEWSz );
1705 aEWVScrollBar.SetPosSizePixel( Point( aOutSz.Width()-DWBORDER-nSBWidth, DWBORDER ), Size( nSBWidth, aSz.Height() ) );
1707 // Macht das EditorWindow, ausserdem hier falsch, da Pixel
1708 // aEWVScrollBar.SetPageSize( aEWSz.Height() * 8 / 10 );
1709 // aEWVScrollBar.SetVisibleSize( aSz.Height() );
1710 // Invalidate();
1713 IMPL_LINK( ComplexEditorWindow, ScrollHdl, ScrollBar *, pCurScrollBar )
1715 if ( aEdtWindow.GetEditView() )
1717 DBG_ASSERT( pCurScrollBar == &aEWVScrollBar, "Wer scrollt hier ?" );
1718 long nDiff = aEdtWindow.GetEditView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
1719 aEdtWindow.GetEditView()->Scroll( 0, nDiff );
1720 aBrkWindow.DoScroll( 0, nDiff );
1721 aEdtWindow.GetEditView()->ShowCursor( FALSE, TRUE );
1722 pCurScrollBar->SetThumbPos( aEdtWindow.GetEditView()->GetStartDocPos().Y() );
1725 return 0;
1728 // virtual
1729 void ComplexEditorWindow::DataChanged(DataChangedEvent const & rDCEvt)
1731 Window::DataChanged(rDCEvt);
1732 if (rDCEvt.GetType() == DATACHANGED_SETTINGS
1733 && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
1735 Color aColor(GetSettings().GetStyleSettings().GetFaceColor());
1736 if (aColor
1737 != rDCEvt.GetOldSettings()->GetStyleSettings().GetFaceColor())
1739 SetBackground(Wallpaper(aColor));
1740 Invalidate();
1745 // virtual
1746 uno::Reference< awt::XWindowPeer >
1747 EditorWindow::GetComponentInterface(BOOL bCreate)
1749 uno::Reference< awt::XWindowPeer > xPeer(
1750 Window::GetComponentInterface(false));
1751 if (!xPeer.is() && bCreate)
1753 // Make sure edit engine and view are available:
1754 if (!pEditEngine)
1755 CreateEditEngine();
1757 xPeer = new ::svt::TextWindowPeer(*GetEditView());
1758 SetComponentInterface(xPeer);
1760 return xPeer;
1763 WatchTreeListBox::WatchTreeListBox( Window* pParent, WinBits nWinBits )
1764 : SvHeaderTabListBox( pParent, nWinBits )
1767 WatchTreeListBox::~WatchTreeListBox()
1769 // User-Daten zerstoeren...
1770 SvLBoxEntry* pEntry = First();
1771 while ( pEntry )
1773 delete (WatchItem*)pEntry->GetUserData();
1774 pEntry = Next( pEntry );
1778 void WatchTreeListBox::SetTabs()
1780 SvHeaderTabListBox::SetTabs();
1781 USHORT nTabCount_ = aTabs.Count();
1782 for( USHORT i = 0 ; i < nTabCount_ ; i++ )
1784 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(i);
1785 if( i == 2 )
1786 pTab->nFlags |= SV_LBOXTAB_EDITABLE;
1787 else
1788 pTab->nFlags &= ~SV_LBOXTAB_EDITABLE;
1792 void WatchTreeListBox::RequestingChilds( SvLBoxEntry * pParent )
1794 if( !StarBASIC::IsRunning() )
1795 return;
1797 if( GetChildCount( pParent ) > 0 )
1798 return;
1800 SvLBoxEntry * pEntry = pParent;
1801 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1803 SbxDimArray* pArray = pItem->mpArray;
1804 SbxDimArray* pRootArray = pItem->GetRootArray();
1805 bool bArrayIsRootArray = false;
1806 if( !pArray && pRootArray )
1808 pArray = pRootArray;
1809 bArrayIsRootArray = true;
1812 SbxObject* pObj = pItem->mpObject;
1813 if( pObj )
1815 createAllObjectProperties( pObj );
1816 SbxArray* pProps = pObj->GetProperties();
1817 USHORT nPropCount = pProps->Count();
1818 pItem->maMemberList.allocList( nPropCount );
1820 for( USHORT i = 0 ; i < nPropCount - 3 ; i++ )
1822 SbxVariable* pVar = pProps->Get( i );
1824 String aName( pVar->GetName() );
1825 pItem->maMemberList.mpMemberNames[i] = aName;
1826 SvLBoxEntry* pChildEntry = SvTreeListBox::InsertEntry( aName, pEntry );
1827 WatchItem* pChildItem = new WatchItem();
1828 pChildItem->maName = aName;
1829 pChildEntry->SetUserData( pChildItem );
1831 if( nPropCount > 0 )
1833 UpdateWatches();
1836 else if( pArray )
1838 USHORT nElementCount = 0;
1840 // Loop through indices of current level
1841 int nParentLevel = bArrayIsRootArray ? pItem->nDimLevel : 0;
1842 int nThisLevel = nParentLevel + 1;
1843 INT32 nMin, nMax;
1844 pArray->GetDim32( nThisLevel, nMin, nMax );
1845 for( INT32 i = nMin ; i <= nMax ; i++ )
1847 WatchItem* pChildItem = new WatchItem();
1849 // Copy data and create name
1850 String aBaseName( pItem->maName );
1851 pChildItem->maName = aBaseName;
1853 String aIndexStr = String( RTL_CONSTASCII_USTRINGPARAM( "(" ) );
1854 // pChildItem->mpArray = pItem->mpArray;
1855 pChildItem->mpArrayParentItem = pItem;
1856 pChildItem->nDimLevel = nThisLevel;
1857 pChildItem->nDimCount = pItem->nDimCount;
1858 pChildItem->pIndices = new short[ pChildItem->nDimCount ];
1859 USHORT j;
1860 for( j = 0 ; j < nParentLevel ; j++ )
1862 short n = pChildItem->pIndices[j] = pItem->pIndices[j];
1863 aIndexStr += String::CreateFromInt32( n );
1864 aIndexStr += String( RTL_CONSTASCII_USTRINGPARAM( "," ) );
1866 pChildItem->pIndices[ nParentLevel ] = sal::static_int_cast<short>( i );
1867 aIndexStr += String::CreateFromInt32( i );
1868 aIndexStr += String( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
1870 String aDisplayName;
1871 WatchItem* pArrayRootItem = pChildItem->GetRootItem();
1872 if( pArrayRootItem && pArrayRootItem->mpArrayParentItem )
1873 aDisplayName = pItem->maDisplayName;
1874 else
1875 aDisplayName = aBaseName;
1876 aDisplayName += aIndexStr;
1877 pChildItem->maDisplayName = aDisplayName;
1879 SvLBoxEntry* pChildEntry = SvTreeListBox::InsertEntry( aDisplayName, pEntry );
1880 nElementCount++;
1881 pChildEntry->SetUserData( pChildItem );
1883 if( nElementCount > 0 )
1885 UpdateWatches();
1890 SbxBase* WatchTreeListBox::ImplGetSBXForEntry( SvLBoxEntry* pEntry, bool& rbArrayElement )
1892 SbxBase* pSBX = NULL;
1893 rbArrayElement = false;
1895 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1896 String aVName( pItem->maName );
1898 SvLBoxEntry* pParentEntry = GetParent( pEntry );
1899 WatchItem* pParentItem = pParentEntry ? (WatchItem*)pParentEntry->GetUserData() : NULL;
1900 if( pParentItem )
1902 SbxObject* pObj = pParentItem->mpObject;
1903 SbxDimArray* pArray;
1904 if( pObj )
1906 pSBX = pObj->Find( aVName, SbxCLASS_DONTCARE );
1908 SbxVariable* pVar;
1909 if ( pSBX && (pVar = PTR_CAST( SbxVariable, pSBX )) != NULL
1910 && !pSBX->ISA( SbxMethod ) )
1912 // Force getting value
1913 SbxValues aRes;
1914 aRes.eType = SbxVOID;
1915 pVar->Get( aRes );
1918 // Array?
1919 else if( (pArray = pItem->GetRootArray()) != NULL )
1920 // else if( (pArray = pItem->mpArray) != NULL )
1922 rbArrayElement = true;
1923 if( pParentItem->nDimLevel + 1 == pParentItem->nDimCount )
1924 // if( pItem->nDimLevel == pItem->nDimCount )
1925 pSBX = pArray->Get( pItem->pIndices );
1926 // else
1927 // pSBX = pArray;
1930 else
1932 pSBX = StarBASIC::FindSBXInCurrentScope( aVName );
1934 return pSBX;
1937 BOOL __EXPORT WatchTreeListBox::EditingEntry( SvLBoxEntry* pEntry, Selection& )
1939 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1941 BOOL bEdit = FALSE;
1942 if ( StarBASIC::IsRunning() && StarBASIC::GetActiveMethod() && !SbxBase::IsError() )
1944 // No out of scope entries
1945 bool bArrayElement;
1946 SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
1947 if ( ( pSBX && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) ) || bArrayElement )
1949 // Accept no objects and only end nodes of arrays for editing
1950 if( !pItem->mpObject && (pItem->mpArray == NULL || pItem->nDimLevel == pItem->nDimCount) )
1952 aEditingRes = SvHeaderTabListBox::GetEntryText( pEntry, ITEM_ID_VALUE-1 );
1953 aEditingRes.EraseLeadingChars();
1954 aEditingRes.EraseTrailingChars();
1955 bEdit = TRUE;
1960 if ( !bEdit )
1961 Sound::Beep();
1963 return bEdit;
1966 BOOL __EXPORT WatchTreeListBox::EditedEntry( SvLBoxEntry* pEntry, const String& rNewText )
1968 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1969 String aVName( pItem->maName );
1971 String aResult = rNewText;
1972 aResult.EraseLeadingChars();
1973 aResult.EraseTrailingChars();
1975 USHORT nResultLen = aResult.Len();
1976 sal_Unicode cFirst = aResult.GetChar( 0 );
1977 sal_Unicode cLast = aResult.GetChar( nResultLen - 1 );
1978 if( cFirst == '\"' && cLast == '\"' )
1979 aResult = aResult.Copy( 1, nResultLen - 2 );
1981 BOOL bResModified = ( aResult != aEditingRes ) ? TRUE : FALSE;
1982 BOOL bError = FALSE;
1983 if ( !aVName.Len() )
1985 bError = TRUE;
1988 BOOL bRet = FALSE;
1990 if ( bError )
1992 Sound::Beep();
1994 else if ( bResModified )
1996 bRet = ImplBasicEntryEdited( pEntry, aResult );
1999 return bRet;
2002 BOOL WatchTreeListBox::ImplBasicEntryEdited( SvLBoxEntry* pEntry, const String& rResult )
2004 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
2005 String aVName( pItem->maName );
2007 BOOL bError = FALSE;
2008 String aResult( rResult );
2009 String aIndex;
2010 bool bArrayElement;
2011 SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
2013 SbxBase* pToBeChanged = NULL;
2014 if ( pSBX && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
2016 SbxVariable* pVar = (SbxVariable*)pSBX;
2017 SbxDataType eType = pVar->GetType();
2018 if ( (BYTE)eType == (BYTE)SbxOBJECT )
2019 bError = TRUE;
2020 else if ( eType & SbxARRAY )
2021 bError = TRUE;
2022 else
2023 pToBeChanged = pSBX;
2026 if ( pToBeChanged )
2028 if ( pToBeChanged->ISA( SbxVariable ) )
2030 // Wenn der Typ variabel ist, macht die Konvertierung des SBX nichts,
2031 // bei festem Typ wird der String konvertiert.
2032 ((SbxVariable*)pToBeChanged)->PutStringExt( aResult );
2034 else
2035 bError = TRUE;
2038 // Wenn jemand z.B. einen zu grossen Wert fuer ein Int eingegeben hat,
2039 // folgt beim naechsten Step() ein Runtime-Error.
2040 if ( SbxBase::IsError() )
2042 bError = TRUE;
2043 SbxBase::ResetError();
2046 if ( bError )
2047 Sound::Beep();
2049 UpdateWatches();
2051 // Der Text soll niemals 1-zu-1 uebernommen werden, weil dann das
2052 // UpdateWatches verlorengeht.
2053 return FALSE;
2057 static void implCollapseModifiedObjectEntry( SvLBoxEntry* pParent, WatchTreeListBox* pThis )
2059 pThis->Collapse( pParent );
2061 SvLBoxTreeList* pModel = pThis->GetModel();
2062 SvLBoxEntry* pDeleteEntry;
2063 while( (pDeleteEntry = pThis->SvTreeListBox::GetEntry( pParent, 0 )) != NULL )
2065 implCollapseModifiedObjectEntry( pDeleteEntry, pThis );
2067 WatchItem* pItem = (WatchItem*)pDeleteEntry->GetUserData();
2068 delete pItem;
2069 pModel->Remove( pDeleteEntry );
2073 static String implCreateTypeStringForDimArray( WatchItem* pItem, SbxDataType eType )
2075 String aRetStr = getBasicTypeName( eType );
2077 SbxDimArray* pArray = pItem->mpArray;
2078 if( !pArray )
2079 pArray = pItem->GetRootArray();
2080 if( pArray )
2082 int nDimLevel = pItem->nDimLevel;
2083 int nDims = pItem->nDimCount;
2084 if( nDimLevel < nDims )
2086 aRetStr += '(';
2087 for( int i = nDimLevel ; i < nDims ; i++ )
2089 short nMin, nMax;
2090 pArray->GetDim( sal::static_int_cast<short>( i+1 ), nMin, nMax );
2091 aRetStr += String::CreateFromInt32( nMin );
2092 aRetStr += String( RTL_CONSTASCII_USTRINGPARAM( " to " ) );
2093 aRetStr += String::CreateFromInt32( nMax );
2094 if( i < nDims - 1 )
2095 aRetStr += String( RTL_CONSTASCII_USTRINGPARAM( ", " ) );
2097 aRetStr += ')';
2100 return aRetStr;
2104 void implEnableChildren( SvLBoxEntry* pEntry, bool bEnable )
2105 // inline void implEnableChildren( SvLBoxEntry* pEntry, bool bEnable )
2107 if( bEnable )
2109 pEntry->SetFlags(
2110 (pEntry->GetFlags() &
2111 ~(SV_ENTRYFLAG_NO_NODEBMP | SV_ENTRYFLAG_HAD_CHILDREN))
2112 | SV_ENTRYFLAG_CHILDS_ON_DEMAND );
2114 else
2116 pEntry->SetFlags(
2117 (pEntry->GetFlags() & ~(SV_ENTRYFLAG_CHILDS_ON_DEMAND)) );
2121 void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
2123 SbMethod* pCurMethod = StarBASIC::GetActiveMethod();
2125 SbxError eOld = SbxBase::GetError();
2126 setBasicWatchMode( true );
2128 SvLBoxEntry* pEntry = First();
2129 while ( pEntry )
2131 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
2132 String aVName( pItem->maName );
2133 DBG_ASSERT( aVName.Len(), "Var? - Darf nicht leer sein!" );
2134 String aWatchStr;
2135 String aTypeStr;
2136 if ( pCurMethod )
2138 bool bArrayElement;
2139 SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
2141 // Array? If no end node create type string
2142 if( bArrayElement && pItem->nDimLevel < pItem->nDimCount )
2144 SbxDimArray* pRootArray = pItem->GetRootArray();
2145 SbxDataType eType = pRootArray->GetType();
2146 // SbxDataType eType = pItem->mpArray->GetType();
2147 aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
2148 implEnableChildren( pEntry, true );
2151 bool bCollapse = false;
2152 if ( pSBX && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
2154 SbxVariable* pVar = (SbxVariable*)pSBX;
2155 // Sonderbehandlung fuer Arrays:
2156 SbxDataType eType = pVar->GetType();
2157 if ( eType & SbxARRAY )
2159 // Mehrdimensionale Arrays beruecksichtigen!
2160 SbxBase* pBase = pVar->GetObject();
2161 if ( pBase && pBase->ISA( SbxDimArray ) )
2163 SbxDimArray* pNewArray = (SbxDimArray*)pBase;
2164 SbxDimArray* pOldArray = pItem->mpArray;
2166 bool bArrayChanged = false;
2167 if( pNewArray != NULL && pOldArray != NULL )
2169 // Compare Array dimensions to see if array has changed
2170 // Can be a copy, so comparing pointers does not work
2171 USHORT nOldDims = pOldArray->GetDims();
2172 USHORT nNewDims = pNewArray->GetDims();
2173 if( nOldDims != nNewDims )
2175 bArrayChanged = true;
2177 else
2179 for( int i = 0 ; i < nOldDims ; i++ )
2181 short nOldMin, nOldMax;
2182 short nNewMin, nNewMax;
2184 pOldArray->GetDim( sal::static_int_cast<short>( i+1 ), nOldMin, nOldMax );
2185 pNewArray->GetDim( sal::static_int_cast<short>( i+1 ), nNewMin, nNewMax );
2186 if( nOldMin != nNewMin || nOldMax != nNewMax )
2188 bArrayChanged = true;
2189 break;
2194 else if( pNewArray == NULL || pOldArray == NULL )
2195 bArrayChanged = true;
2197 if( pNewArray )
2198 implEnableChildren( pEntry, true );
2200 // #i37227 Clear always and replace array
2201 if( pNewArray != pOldArray )
2203 pItem->clearWatchItem( false );
2204 if( pNewArray )
2206 implEnableChildren( pEntry, true );
2208 pItem->mpArray = pNewArray;
2209 USHORT nDims = pNewArray->GetDims();
2210 pItem->nDimLevel = 0;
2211 pItem->nDimCount = nDims;
2214 if( bArrayChanged && pOldArray != NULL )
2215 bCollapse = true;
2217 aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
2219 else
2220 aWatchStr += String( RTL_CONSTASCII_USTRINGPARAM( "<?>" ) );
2222 else if ( (BYTE)eType == (BYTE)SbxOBJECT )
2224 SbxObject* pObj = NULL;
2225 SbxBase* pBase = pVar->GetObject();
2226 if( pBase && pBase->ISA( SbxObject ) )
2227 pObj = (SbxObject*)pBase;
2229 if( pObj )
2231 // Check if member list has changed
2232 bool bObjChanged = false;
2233 if( pItem->mpObject != NULL && pItem->maMemberList.mpMemberNames != NULL )
2235 SbxArray* pProps = pObj->GetProperties();
2236 USHORT nPropCount = pProps->Count();
2237 for( USHORT i = 0 ; i < nPropCount - 3 ; i++ )
2239 SbxVariable* pVar_ = pProps->Get( i );
2240 String aName( pVar_->GetName() );
2241 if( pItem->maMemberList.mpMemberNames[i] != aName )
2243 bObjChanged = true;
2244 break;
2247 if( bObjChanged )
2248 bCollapse = true;
2251 pItem->mpObject = pObj;
2252 implEnableChildren( pEntry, true );
2253 aTypeStr = getBasicObjectTypeName( pObj );
2255 else
2257 aWatchStr = String( RTL_CONSTASCII_USTRINGPARAM( "Null" ) );
2258 if( pItem->mpObject != NULL )
2260 bCollapse = true;
2261 pItem->clearWatchItem( false );
2263 implEnableChildren( pEntry, false );
2267 else
2269 if( pItem->mpObject != NULL )
2271 bCollapse = true;
2272 pItem->clearWatchItem( false );
2274 implEnableChildren( pEntry, false );
2277 bool bString = ((BYTE)eType == (BYTE)SbxSTRING);
2278 String aStrStr( RTL_CONSTASCII_USTRINGPARAM( "\"" ) );
2279 if( bString )
2280 aWatchStr += aStrStr;
2281 aWatchStr += pVar->GetString();
2282 if( bString )
2283 aWatchStr += aStrStr;
2285 if( !aTypeStr.Len() )
2287 if( !pVar->IsFixed() )
2288 aTypeStr = String( RTL_CONSTASCII_USTRINGPARAM( "Variant/" ) );
2289 aTypeStr += getBasicTypeName( pVar->GetType() );
2292 else if( !bArrayElement )
2293 aWatchStr += String( RTL_CONSTASCII_USTRINGPARAM( "<Out of Scope>" ) );
2295 if( bCollapse )
2296 implCollapseModifiedObjectEntry( pEntry, this );
2299 else if( bBasicStopped )
2301 if( pItem->mpObject || pItem->mpArray )
2303 implCollapseModifiedObjectEntry( pEntry, this );
2304 pItem->mpObject = NULL;
2308 SvHeaderTabListBox::SetEntryText( aWatchStr, pEntry, ITEM_ID_VALUE-1 );
2309 SvHeaderTabListBox::SetEntryText( aTypeStr, pEntry, ITEM_ID_TYPE-1 );
2311 pEntry = Next( pEntry );
2314 // Force redraw
2315 Invalidate();
2317 SbxBase::ResetError();
2318 if( eOld != SbxERR_OK )
2319 SbxBase::SetError( eOld );
2320 setBasicWatchMode( false );