bump product version to 4.1.6.2
[LibreOffice.git] / basctl / source / basicide / baside2b.cxx
blob7b7e3c7396dd25d1436bec2d61a9e834296aa623
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "helpid.hrc"
21 #include "baside2.hrc"
23 #include "baside2.hxx"
24 #include "brkdlg.hxx"
25 #include "iderdll.hxx"
26 #include "iderdll2.hxx"
27 #include "objdlg.hxx"
29 #include <basic/sbmeth.hxx>
30 #include <basic/sbuno.hxx>
31 #include <com/sun/star/script/XLibraryContainer2.hpp>
32 #include <com/sun/star/beans/XMultiPropertySet.hpp>
33 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/string.hxx>
36 #include <officecfg/Office/Common.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <sfx2/viewfrm.hxx>
39 #include <vcl/msgbox.hxx>
40 #include <svl/urihelper.hxx>
41 #include <vcl/xtextedt.hxx>
42 #include <vcl/txtattr.hxx>
43 #include <svtools/textwindowpeer.hxx>
44 #include <tools/stream.hxx>
45 #include <comphelper/syntaxhighlight.hxx>
46 #include "svtools/treelistentry.hxx"
47 #include <vcl/taskpanelist.hxx>
48 #include <vcl/help.hxx>
50 #include <vector>
52 namespace basctl
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
58 namespace
61 sal_uInt16 const NoMarker = 0xFFFF;
63 long nVirtToolBoxHeight; // inited in WatchWindow, used in Stackwindow
64 long nHeaderBarHeight;
66 // Returns pBase converted to SbxVariable if valid and is not an SbxMethod.
67 SbxVariable* IsSbxVariable (SbxBase* pBase)
69 if (SbxVariable* pVar = dynamic_cast<SbxVariable*>(pBase))
70 if (!dynamic_cast<SbxMethod*>(pVar))
71 return pVar;
72 return 0;
75 Image GetImage (unsigned nId)
77 static ImageList const aImagesNormal(IDEResId(RID_IMGLST_LAYOUT));
78 return aImagesNormal.GetImage(nId);
81 int const nScrollLine = 12;
82 int const nScrollPage = 60;
83 int const DWBORDER = 3;
85 char const cSuffixes[] = "%&!#@$";
87 } // namespace
90 /**
91 * Helper functions to get/set text in TextEngine using
92 * the stream interface.
94 * get/setText() only supports tools Strings limited to 64K).
96 OUString getTextEngineText (ExtTextEngine& rEngine)
98 SvMemoryStream aMemStream;
99 aMemStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
100 aMemStream.SetLineDelimiter( LINEEND_LF );
101 rEngine.Write( aMemStream );
102 sal_uLong nSize = aMemStream.Tell();
103 OUString aText( (const sal_Char*)aMemStream.GetData(),
104 nSize, RTL_TEXTENCODING_UTF8 );
105 return aText;
108 void setTextEngineText (ExtTextEngine& rEngine, OUString const& aStr)
110 rEngine.SetText(OUString());
111 OString aUTF8Str = OUStringToOString( aStr, RTL_TEXTENCODING_UTF8 );
112 SvMemoryStream aMemStream( (void*)aUTF8Str.getStr(), aUTF8Str.getLength(),
113 STREAM_READ | STREAM_SEEK_TO_BEGIN );
114 aMemStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
115 aMemStream.SetLineDelimiter( LINEEND_LF );
116 rEngine.Read(aMemStream);
119 namespace
122 void lcl_DrawIDEWindowFrame( DockingWindow* pWin )
124 if ( pWin->IsFloatingMode() )
125 return;
127 Size aSz = pWin->GetOutputSizePixel();
128 const Color aOldLineColor( pWin->GetLineColor() );
129 pWin->SetLineColor( Color( COL_WHITE ) );
130 // White line on top
131 pWin->DrawLine( Point( 0, 0 ), Point( aSz.Width(), 0 ) );
132 // Black line at bottom
133 pWin->SetLineColor( Color( COL_BLACK ) );
134 pWin->DrawLine( Point( 0, aSz.Height() - 1 ),
135 Point( aSz.Width(), aSz.Height() - 1 ) );
136 pWin->SetLineColor( aOldLineColor );
139 void lcl_SeparateNameAndIndex( const String& rVName, String& rVar, String& rIndex )
141 rVar = rVName;
142 rIndex.Erase();
143 sal_uInt16 nIndexStart = rVar.Search( '(' );
144 if ( nIndexStart != STRING_NOTFOUND )
146 sal_uInt16 nIndexEnd = rVar.Search( ')', nIndexStart );
147 if ( nIndexStart != STRING_NOTFOUND )
149 rIndex = rVar.Copy( nIndexStart+1, nIndexEnd-nIndexStart-1 );
150 rVar.Erase( nIndexStart );
151 rVar = comphelper::string::stripEnd(rVar, ' ');
152 rIndex = comphelper::string::strip(rIndex, ' ');
156 if ( rVar.Len() )
158 sal_uInt16 nLastChar = rVar.Len()-1;
159 if ( strchr( cSuffixes, rVar.GetChar( nLastChar ) ) )
160 rVar.Erase( nLastChar, 1 );
162 if ( rIndex.Len() )
164 sal_uInt16 nLastChar = rIndex.Len()-1;
165 if ( strchr( cSuffixes, rIndex.GetChar( nLastChar ) ) )
166 rIndex.Erase( nLastChar, 1 );
170 } // namespace
174 // EditorWindow
175 // ============
178 class EditorWindow::ChangesListener:
179 public cppu::WeakImplHelper1< beans::XPropertiesChangeListener >
181 public:
182 ChangesListener(EditorWindow & editor): editor_(editor) {}
184 private:
185 virtual ~ChangesListener() {}
187 virtual void SAL_CALL disposing(lang::EventObject const &) throw (RuntimeException)
189 osl::MutexGuard g(editor_.mutex_);
190 editor_.notifier_.clear();
193 virtual void SAL_CALL propertiesChange(
194 Sequence< beans::PropertyChangeEvent > const &) throw (RuntimeException)
196 SolarMutexGuard g;
197 editor_.ImplSetFont();
200 EditorWindow & editor_;
203 class EditorWindow::ProgressInfo : public SfxProgress
205 public:
206 ProgressInfo (SfxObjectShell* pObjSh, String const& rText, sal_uLong nRange) :
207 SfxProgress(pObjSh, rText, nRange),
208 nCurState(0)
211 void StepProgress ()
213 SetState(++nCurState);
216 private:
217 sal_uLong nCurState;
220 EditorWindow::EditorWindow (Window* pParent, ModulWindow* pModulWindow) :
221 Window(pParent, WB_BORDER),
222 pEditView(0),
223 pEditEngine(0),
224 rModulWindow(*pModulWindow),
225 nCurTextWidth(0),
226 bHighlightning(false),
227 bDoSyntaxHighlight(true),
228 bDelayHighlight(true)
230 SetBackground(Wallpaper(GetSettings().GetStyleSettings().GetFieldColor()));
231 SetPointer( Pointer( POINTER_TEXT ) );
232 SetHelpId( HID_BASICIDE_EDITORWINDOW );
234 listener_ = new ChangesListener(*this);
235 Reference< beans::XMultiPropertySet > n(
236 officecfg::Office::Common::Font::SourceViewFont::get(),
237 UNO_QUERY_THROW);
239 osl::MutexGuard g(mutex_);
240 notifier_ = n;
242 Sequence< OUString > s(2);
243 s[0] = OUString( "FontHeight" );
244 s[1] = OUString( "FontName" );
245 n->addPropertiesChangeListener(s, listener_.get());
249 EditorWindow::~EditorWindow()
251 Reference< beans::XMultiPropertySet > n;
253 osl::MutexGuard g(mutex_);
254 n = notifier_;
256 if (n.is()) {
257 n->removePropertiesChangeListener(listener_.get());
260 aSyntaxIdleTimer.Stop();
262 if ( pEditEngine )
264 EndListening( *pEditEngine );
265 pEditEngine->RemoveView(pEditView.get());
269 OUString EditorWindow::GetWordAtCursor()
271 String aWord;
273 if ( pEditView )
275 TextEngine* pTextEngine = pEditView->GetTextEngine();
276 if ( pTextEngine )
278 // check first, if the cursor is at a help URL
279 const TextSelection& rSelection = pEditView->GetSelection();
280 const TextPaM& rSelStart = rSelection.GetStart();
281 const TextPaM& rSelEnd = rSelection.GetEnd();
282 OUString aText = pTextEngine->GetText( rSelEnd.GetPara() );
283 CharClass aClass( ::comphelper::getProcessComponentContext() , Application::GetSettings().GetLanguageTag() );
284 sal_Int32 nSelStart = rSelStart.GetIndex();
285 sal_Int32 nSelEnd = rSelEnd.GetIndex();
286 sal_Int32 nLength = aText.getLength();
287 sal_Int32 nStart = 0;
288 sal_Int32 nEnd = nLength;
289 while ( nStart < nLength )
291 OUString aURL( URIHelper::FindFirstURLInText( aText, nStart, nEnd, aClass ) );
292 INetURLObject aURLObj( aURL );
293 if ( aURLObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP
294 && nSelStart >= nStart && nSelStart <= nEnd && nSelEnd >= nStart && nSelEnd <= nEnd )
296 aWord = aURL;
297 break;
299 nStart = nEnd;
300 nEnd = nLength;
303 // Not the selected range, but at the CursorPosition,
304 // if a word is partially selected.
305 if ( !aWord.Len() )
306 aWord = pTextEngine->GetWord( rSelEnd );
308 // Can be empty when full word selected, as Cursor behing it
309 if ( !aWord.Len() && pEditView->HasSelection() )
310 aWord = pTextEngine->GetWord( rSelStart );
314 return aWord;
317 void EditorWindow::RequestHelp( const HelpEvent& rHEvt )
319 bool bDone = false;
321 // Should have been activated at some point
322 if ( pEditEngine )
324 if ( rHEvt.GetMode() & HELPMODE_CONTEXT )
326 String aKeyword = GetWordAtCursor();
327 Application::GetHelp()->SearchKeyword( aKeyword );
328 bDone = true;
330 else if ( rHEvt.GetMode() & HELPMODE_QUICK )
332 String aHelpText;
333 Point aTopLeft;
334 if ( StarBASIC::IsRunning() )
336 Point aWindowPos = rHEvt.GetMousePosPixel();
337 aWindowPos = ScreenToOutputPixel( aWindowPos );
338 Point aDocPos = GetEditView()->GetDocPos( aWindowPos );
339 TextPaM aCursor = GetEditView()->GetTextEngine()->GetPaM(aDocPos, false);
340 TextPaM aStartOfWord;
341 String aWord = GetEditView()->GetTextEngine()->GetWord( aCursor, &aStartOfWord );
342 if ( aWord.Len() && !comphelper::string::isdigitAsciiString(aWord) )
344 sal_uInt16 nLastChar =aWord.Len()-1;
345 if ( strchr( cSuffixes, aWord.GetChar( nLastChar ) ) )
346 aWord.Erase( nLastChar, 1 );
347 SbxBase* pSBX = StarBASIC::FindSBXInCurrentScope( aWord );
348 if (SbxVariable const* pVar = IsSbxVariable(pSBX))
350 SbxDataType eType = pVar->GetType();
351 if ( (sal_uInt8)eType == (sal_uInt8)SbxOBJECT )
352 // might cause a crash e. g. at the selections-object
353 // Type == Object does not mean pVar == Object!
354 ; // aHelpText = ((SbxObject*)pVar)->GetClassName();
355 else if ( eType & SbxARRAY )
356 ; // aHelpText = "{...}";
357 else if ( (sal_uInt8)eType != (sal_uInt8)SbxEMPTY )
359 aHelpText = pVar->GetName();
360 if ( !aHelpText.Len() ) // name is not copied with the passed parameters
361 aHelpText = aWord;
362 aHelpText += '=';
363 aHelpText += pVar->GetOUString();
366 if ( aHelpText.Len() )
368 aTopLeft = GetEditView()->GetTextEngine()->PaMtoEditCursor( aStartOfWord ).BottomLeft();
369 aTopLeft = GetEditView()->GetWindowPos( aTopLeft );
370 aTopLeft.X() += 5;
371 aTopLeft.Y() += 5;
372 aTopLeft = OutputToScreenPixel( aTopLeft );
376 Help::ShowQuickHelp( this, Rectangle( aTopLeft, Size( 1, 1 ) ), aHelpText, QUICKHELP_TOP|QUICKHELP_LEFT);
377 bDone = true;
381 if ( !bDone )
382 Window::RequestHelp( rHEvt );
386 void EditorWindow::Resize()
388 // ScrollBars, etc. happens in Adjust...
389 if ( pEditView )
391 long nVisY = pEditView->GetStartDocPos().Y();
393 pEditView->ShowCursor();
394 Size aOutSz( GetOutputSizePixel() );
395 long nMaxVisAreaStart = pEditView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
396 if ( nMaxVisAreaStart < 0 )
397 nMaxVisAreaStart = 0;
398 if ( pEditView->GetStartDocPos().Y() > nMaxVisAreaStart )
400 Point aStartDocPos( pEditView->GetStartDocPos() );
401 aStartDocPos.Y() = nMaxVisAreaStart;
402 pEditView->SetStartDocPos( aStartDocPos );
403 pEditView->ShowCursor();
404 rModulWindow.GetBreakPointWindow().GetCurYOffset() = aStartDocPos.Y();
405 rModulWindow.GetLineNumberWindow().GetCurYOffset() = aStartDocPos.Y();
407 InitScrollBars();
408 if ( nVisY != pEditView->GetStartDocPos().Y() )
409 Invalidate();
414 void EditorWindow::MouseMove( const MouseEvent &rEvt )
416 if ( pEditView )
417 pEditView->MouseMove( rEvt );
421 void EditorWindow::MouseButtonUp( const MouseEvent &rEvt )
423 if ( pEditView )
425 pEditView->MouseButtonUp( rEvt );
426 if (SfxBindings* pBindings = GetBindingsPtr())
427 pBindings->Invalidate( SID_BASICIDE_STAT_POS );
431 void EditorWindow::MouseButtonDown( const MouseEvent &rEvt )
433 GrabFocus();
434 if ( pEditView )
435 pEditView->MouseButtonDown( rEvt );
438 void EditorWindow::Command( const CommandEvent& rCEvt )
440 if ( pEditView )
442 pEditView->Command( rCEvt );
443 if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
444 ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
445 ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
447 HandleScrollCommand( rCEvt, rModulWindow.GetHScrollBar(), &rModulWindow.GetEditVScrollBar() );
452 bool EditorWindow::ImpCanModify()
454 bool bCanModify = true;
455 if ( StarBASIC::IsRunning() )
457 // If in Trace-mode, abort the trace or refuse input
458 // Remove markers in the modules in Notify at Basic::Stoped
459 if ( QueryBox( 0, WB_OK_CANCEL, String( IDEResId( RID_STR_WILLSTOPPRG ) ) ).Execute() == RET_OK )
461 rModulWindow.GetBasicStatus().bIsRunning = false;
462 StopBasic();
464 else
465 bCanModify = false;
467 return bCanModify;
470 void EditorWindow::KeyInput( const KeyEvent& rKEvt )
472 if ( !pEditView ) // Happens in Win95
473 return;
475 #if OSL_DEBUG_LEVEL > 1
476 Range aRange = rModulWindow.GetHScrollBar()->GetRange(); (void)aRange;
477 long nVisSz = rModulWindow.GetHScrollBar()->GetVisibleSize(); (void)nVisSz;
478 long nPapSz = rModulWindow.GetHScrollBar()->GetPageSize(); (void)nPapSz;
479 long nLinSz = rModulWindow.GetHScrollBar()->GetLineSize(); (void)nLinSz;
480 long nThumb = rModulWindow.GetHScrollBar()->GetThumbPos(); (void)nThumb;
481 #endif
482 bool const bWasModified = pEditEngine->IsModified();
483 // see if there is an accelerator to be processed first
484 bool bDone = SfxViewShell::Current()->KeyInput( rKEvt );
486 if ( !bDone && ( !TextEngine::DoesKeyChangeText( rKEvt ) || ImpCanModify() ) )
488 if ( ( rKEvt.GetKeyCode().GetCode() == KEY_TAB ) && !rKEvt.GetKeyCode().IsMod1() &&
489 !rKEvt.GetKeyCode().IsMod2() && !GetEditView()->IsReadOnly() )
491 TextSelection aSel( pEditView->GetSelection() );
492 if ( aSel.GetStart().GetPara() != aSel.GetEnd().GetPara() )
494 bDelayHighlight = false;
495 if ( !rKEvt.GetKeyCode().IsShift() )
496 pEditView->IndentBlock();
497 else
498 pEditView->UnindentBlock();
499 bDelayHighlight = true;
500 bDone = true;
503 if ( !bDone )
504 bDone = pEditView->KeyInput( rKEvt );
506 if ( !bDone )
508 Window::KeyInput( rKEvt );
510 else
512 if (SfxBindings* pBindings = GetBindingsPtr())
514 pBindings->Invalidate( SID_BASICIDE_STAT_POS );
515 if ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_CURSOR )
516 pBindings->Update( SID_BASICIDE_STAT_POS );
517 if ( !bWasModified && pEditEngine->IsModified() )
519 pBindings->Invalidate( SID_SAVEDOC );
520 pBindings->Invalidate( SID_DOC_MODIFIED );
521 pBindings->Invalidate( SID_UNDO );
523 if ( rKEvt.GetKeyCode().GetCode() == KEY_INSERT )
524 pBindings->Invalidate( SID_ATTR_INSERT );
529 void EditorWindow::Paint( const Rectangle& rRect )
531 if ( !pEditEngine ) // We need it now at latest
532 CreateEditEngine();
534 pEditView->Paint( rRect );
537 void EditorWindow::LoseFocus()
539 SetSourceInBasic();
540 Window::LoseFocus();
543 bool EditorWindow::SetSourceInBasic()
545 bool bChanged = false;
546 if ( pEditEngine && pEditEngine->IsModified()
547 && !GetEditView()->IsReadOnly() ) // Added for #i60626, otherwise
548 // any read only bug in the text engine could lead to a crash later
550 if ( !StarBASIC::IsRunning() ) // Not at runtime!
552 rModulWindow.UpdateModule();
553 bChanged = true;
556 return bChanged;
559 // Returns the position of the last character of any of the following
560 // EOL char combinations: CR, CR/LF, LF, return -1 if no EOL is found
561 sal_Int32 searchEOL( const OUString& rStr, sal_Int32 fromIndex )
563 sal_Int32 iRetPos = -1;
565 sal_Int32 iLF = rStr.indexOf( LINE_SEP, fromIndex );
566 if( iLF != -1 )
568 iRetPos = iLF;
570 else
572 iRetPos = rStr.indexOf( LINE_SEP_CR, fromIndex );
574 return iRetPos;
577 void EditorWindow::CreateEditEngine()
579 if ( pEditEngine )
580 return;
582 pEditEngine.reset(new ExtTextEngine);
583 pEditView.reset(new ExtTextView(pEditEngine.get(), this));
584 pEditView->SetAutoIndentMode(true);
585 pEditEngine->SetUpdateMode(false);
586 pEditEngine->InsertView(pEditView.get());
588 ImplSetFont();
590 aSyntaxIdleTimer.SetTimeout( 200 );
591 aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, EditorWindow, SyntaxTimerHdl ) );
593 aHighlighter.initialize( HIGHLIGHT_BASIC );
595 bool bWasDoSyntaxHighlight = bDoSyntaxHighlight;
596 bDoSyntaxHighlight = false; // too slow for large texts...
597 OUString aOUSource(rModulWindow.GetModule());
598 sal_Int32 nLines = 0;
599 sal_Int32 nIndex = -1;
602 nLines++;
603 nIndex = searchEOL( aOUSource, nIndex+1 );
605 while ( nIndex >= 0 );
607 // nLines*4: SetText+Formatting+DoHighlight+Formatting
608 // it could be cut down on one formatting but you would wait even longer
609 // for the text then if the source code is long...
610 pProgress.reset(new ProgressInfo(
611 GetShell()->GetViewFrame()->GetObjectShell(),
612 String(IDEResId(RID_STR_GENERATESOURCE)),
613 nLines*4
615 setTextEngineText(*pEditEngine, aOUSource);
617 pEditView->SetStartDocPos( Point( 0, 0 ) );
618 pEditView->SetSelection( TextSelection() );
619 rModulWindow.GetBreakPointWindow().GetCurYOffset() = 0;
620 rModulWindow.GetLineNumberWindow().GetCurYOffset() = 0;
621 pEditEngine->SetUpdateMode(true);
622 rModulWindow.Update(); // has only been invalidated at UpdateMode = true
624 pEditView->ShowCursor( true, true );
626 StartListening( *pEditEngine );
628 aSyntaxIdleTimer.Stop();
629 bDoSyntaxHighlight = bWasDoSyntaxHighlight;
632 for ( sal_uInt16 nLine = 0; nLine < nLines; nLine++ )
633 aSyntaxLineTable.insert( nLine );
634 ForceSyntaxTimeout();
636 pProgress.reset();
638 pEditView->EraseVirtualDevice();
639 pEditEngine->SetModified( false );
640 pEditEngine->EnableUndo( true );
642 InitScrollBars();
644 if (SfxBindings* pBindings = GetBindingsPtr())
645 pBindings->Invalidate( SID_BASICIDE_STAT_POS );
647 DBG_ASSERT( rModulWindow.GetBreakPointWindow().GetCurYOffset() == 0, "CreateEditEngine: Brechpunkte verschoben?" );
649 // set readonly mode for readonly libraries
650 ScriptDocument aDocument(rModulWindow.GetDocument());
651 OUString aOULibName(rModulWindow.GetLibName());
652 Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
653 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && xModLibContainer->isLibraryReadOnly( aOULibName ) )
655 rModulWindow.SetReadOnly(true);
658 if ( aDocument.isDocument() && aDocument.isReadOnly() )
659 rModulWindow.SetReadOnly(true);
662 // virtual
663 void EditorWindow::DataChanged(DataChangedEvent const & rDCEvt)
665 Window::DataChanged(rDCEvt);
666 if (rDCEvt.GetType() == DATACHANGED_SETTINGS
667 && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
669 Color aColor(GetSettings().GetStyleSettings().GetFieldColor());
670 const AllSettings* pOldSettings = rDCEvt.GetOldSettings();
671 if (!pOldSettings || aColor != pOldSettings->GetStyleSettings().GetFieldColor())
673 SetBackground(Wallpaper(aColor));
674 Invalidate();
676 if (pEditEngine != 0)
678 aColor = GetSettings().GetStyleSettings().GetFieldTextColor();
679 if (!pOldSettings || aColor !=
680 pOldSettings-> GetStyleSettings().GetFieldTextColor())
682 Font aFont(pEditEngine->GetFont());
683 aFont.SetColor(aColor);
684 pEditEngine->SetFont(aFont);
690 void EditorWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
692 if (TextHint const* pTextHint = dynamic_cast<TextHint const*>(&rHint))
694 TextHint const& rTextHint = *pTextHint;
695 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
697 if ( rModulWindow.GetHScrollBar() )
698 rModulWindow.GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
699 rModulWindow.GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
700 rModulWindow.GetBreakPointWindow().DoScroll
701 ( 0, rModulWindow.GetBreakPointWindow().GetCurYOffset() - pEditView->GetStartDocPos().Y() );
702 rModulWindow.GetLineNumberWindow().DoScroll
703 ( 0, rModulWindow.GetLineNumberWindow().GetCurYOffset() - pEditView->GetStartDocPos().Y() );
705 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
707 if ( pEditView->GetStartDocPos().Y() )
709 long nOutHeight = GetOutputSizePixel().Height();
710 long nTextHeight = pEditEngine->GetTextHeight();
711 if ( nTextHeight < nOutHeight )
712 pEditView->Scroll( 0, pEditView->GetStartDocPos().Y() );
714 rModulWindow.GetLineNumberWindow().Invalidate();
717 SetScrollBarRanges();
719 else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
721 if ( rModulWindow.GetHScrollBar() )
723 sal_uLong nWidth = pEditEngine->CalcTextWidth();
724 if ( (long)nWidth != nCurTextWidth )
726 nCurTextWidth = nWidth;
727 rModulWindow.GetHScrollBar()->SetRange( Range( 0, (long)nCurTextWidth-1) );
728 rModulWindow.GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
731 long nPrevTextWidth = nCurTextWidth;
732 nCurTextWidth = pEditEngine->CalcTextWidth();
733 if ( nCurTextWidth != nPrevTextWidth )
734 SetScrollBarRanges();
736 else if( rTextHint.GetId() == TEXT_HINT_PARAINSERTED )
738 ParagraphInsertedDeleted( rTextHint.GetValue(), true );
739 DoDelayedSyntaxHighlight( rTextHint.GetValue() );
741 else if( rTextHint.GetId() == TEXT_HINT_PARAREMOVED )
743 ParagraphInsertedDeleted( rTextHint.GetValue(), false );
745 else if( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED )
747 DoDelayedSyntaxHighlight( rTextHint.GetValue() );
749 else if( rTextHint.GetId() == TEXT_HINT_VIEWSELECTIONCHANGED )
751 if (SfxBindings* pBindings = GetBindingsPtr())
753 pBindings->Invalidate( SID_CUT );
754 pBindings->Invalidate( SID_COPY );
760 void EditorWindow::SetScrollBarRanges()
762 // extra method, not InitScrollBars, because for EditEngine events too
763 if ( !pEditEngine )
764 return;
766 if ( rModulWindow.GetHScrollBar() )
767 rModulWindow.GetHScrollBar()->SetRange( Range( 0, nCurTextWidth-1 ) );
769 rModulWindow.GetEditVScrollBar().SetRange( Range( 0, pEditEngine->GetTextHeight()-1 ) );
772 void EditorWindow::InitScrollBars()
774 if ( !pEditEngine )
775 return;
777 SetScrollBarRanges();
778 Size aOutSz( GetOutputSizePixel() );
779 rModulWindow.GetEditVScrollBar().SetVisibleSize( aOutSz.Height() );
780 rModulWindow.GetEditVScrollBar().SetPageSize( aOutSz.Height() * 8 / 10 );
781 rModulWindow.GetEditVScrollBar().SetLineSize( GetTextHeight() );
782 rModulWindow.GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
783 rModulWindow.GetEditVScrollBar().Show();
785 if ( rModulWindow.GetHScrollBar() )
787 rModulWindow.GetHScrollBar()->SetVisibleSize( aOutSz.Width() );
788 rModulWindow.GetHScrollBar()->SetPageSize( aOutSz.Width() * 8 / 10 );
789 rModulWindow.GetHScrollBar()->SetLineSize( GetTextWidth( "x" ) );
790 rModulWindow.GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
791 rModulWindow.GetHScrollBar()->Show();
795 void EditorWindow::ImpDoHighlight( sal_uLong nLine )
797 if ( bDoSyntaxHighlight )
799 OUString aLine( pEditEngine->GetText( nLine ) );
800 aHighlighter.notifyChange( nLine, 0, &aLine, 1 );
802 bool const bWasModified = pEditEngine->IsModified();
803 pEditEngine->RemoveAttribs( nLine, true );
804 HighlightPortions aPortions;
805 aHighlighter.getHighlightPortions( nLine, aLine, aPortions );
807 for ( size_t i = 0; i < aPortions.size(); i++ )
809 HighlightPortion& r = aPortions[i];
810 Color const aColor = rModulWindow.GetLayout().GetSyntaxColor(r.tokenType);
811 pEditEngine->SetAttrib( TextAttribFontColor(aColor), nLine, r.nBegin, r.nEnd, true );
814 pEditEngine->SetModified( bWasModified );
818 void EditorWindow::UpdateSyntaxHighlighting ()
820 unsigned nCount = pEditEngine->GetParagraphCount();
821 for (unsigned i = 0; i < nCount; ++i)
822 DoDelayedSyntaxHighlight(i);
825 void EditorWindow::ImplSetFont()
827 OUString sFontName(
828 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
829 get_value_or( OUString() ) );
830 if ( sFontName.isEmpty() )
832 Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, Application::GetSettings().GetUILanguageTag().getLanguageType(), 0 , this ) );
833 sFontName = aTmpFont.GetName();
835 Size aFontSize(0, officecfg::Office::Common::Font::SourceViewFont::FontHeight::get());
836 Font aFont( sFontName, aFontSize );
837 aFont.SetColor( GetSettings().GetStyleSettings().GetFieldTextColor() );
838 SetPointFont( aFont );
839 aFont = GetFont();
841 rModulWindow.GetBreakPointWindow().SetFont( aFont );
842 rModulWindow.GetLineNumberWindow().SetFont( aFont );
844 if ( pEditEngine )
846 bool const bModified = pEditEngine->IsModified();
847 pEditEngine->SetFont( aFont );
848 pEditEngine->SetModified( bModified );
852 void EditorWindow::DoSyntaxHighlight( sal_uLong nPara )
854 // because of the DelayedSyntaxHighlight it's possible
855 // that this line does not exist anymore!
856 if ( nPara < pEditEngine->GetParagraphCount() )
858 // unfortunately I'm not sure that excactly this line does Modified() ...
859 if ( pProgress )
860 pProgress->StepProgress();
861 ImpDoHighlight( nPara );
865 void EditorWindow::DoDelayedSyntaxHighlight( sal_uLong nPara )
867 // line is only added to 'Liste' (list), processed in TimerHdl
868 // => don't manipulate breaks while EditEngine is formatting
869 if ( pProgress )
870 pProgress->StepProgress();
872 if ( !bHighlightning && bDoSyntaxHighlight )
874 if ( bDelayHighlight )
876 aSyntaxLineTable.insert( nPara );
877 aSyntaxIdleTimer.Start();
879 else
880 DoSyntaxHighlight( nPara );
884 IMPL_LINK_NOARG(EditorWindow, SyntaxTimerHdl)
886 DBG_ASSERT( pEditView, "Noch keine View, aber Syntax-Highlight ?!" );
888 bool const bWasModified = pEditEngine->IsModified();
889 //pEditEngine->SetUpdateMode(false);
891 bHighlightning = true;
892 for ( SyntaxLineSet::const_iterator it = aSyntaxLineTable.begin();
893 it != aSyntaxLineTable.end(); ++it )
895 sal_uInt16 nLine = *it;
896 DoSyntaxHighlight( nLine );
899 // #i45572#
900 if ( pEditView )
901 pEditView->ShowCursor( false, true );
903 pEditEngine->SetModified( bWasModified );
905 aSyntaxLineTable.clear();
906 bHighlightning = false;
908 return 0;
911 void EditorWindow::ParagraphInsertedDeleted( sal_uLong nPara, bool bInserted )
913 if ( pProgress )
914 pProgress->StepProgress();
916 if ( !bInserted && ( nPara == TEXT_PARA_ALL ) )
918 rModulWindow.GetBreakPoints().reset();
919 rModulWindow.GetBreakPointWindow().Invalidate();
920 rModulWindow.GetLineNumberWindow().Invalidate();
921 aHighlighter.initialize( HIGHLIGHT_BASIC );
923 else
925 rModulWindow.GetBreakPoints().AdjustBreakPoints( (sal_uInt16)nPara+1, bInserted );
927 long nLineHeight = GetTextHeight();
928 Size aSz = rModulWindow.GetBreakPointWindow().GetOutputSize();
929 Rectangle aInvRect( Point( 0, 0 ), aSz );
930 long nY = nPara*nLineHeight - rModulWindow.GetBreakPointWindow().GetCurYOffset();
931 aInvRect.Top() = nY;
932 rModulWindow.GetBreakPointWindow().Invalidate( aInvRect );
934 Size aLnSz(rModulWindow.GetLineNumberWindow().GetWidth(),
935 GetOutputSizePixel().Height() - 2 * DWBORDER);
936 rModulWindow.GetLineNumberWindow().SetPosSizePixel(Point(DWBORDER + 19, DWBORDER), aLnSz);
937 rModulWindow.GetLineNumberWindow().Invalidate();
939 if ( bDoSyntaxHighlight )
941 OUString aDummy;
942 aHighlighter.notifyChange( nPara, bInserted ? 1 : (-1), &aDummy, 1 );
947 void EditorWindow::CreateProgress( const OUString& rText, sal_uLong nRange )
949 DBG_ASSERT( !pProgress, "ProgressInfo existiert schon" );
950 pProgress.reset(new ProgressInfo(
951 GetShell()->GetViewFrame()->GetObjectShell(),
952 rText,
953 nRange
957 void EditorWindow::DestroyProgress()
959 pProgress.reset();
962 void EditorWindow::ForceSyntaxTimeout()
964 aSyntaxIdleTimer.Stop();
965 aSyntaxIdleTimer.GetTimeoutHdl().Call(&aSyntaxIdleTimer);
970 // BreakPointWindow
971 // ================
974 BreakPointWindow::BreakPointWindow (Window* pParent, ModulWindow* pModulWindow) :
975 Window(pParent, WB_BORDER),
976 rModulWindow(*pModulWindow),
977 nCurYOffset(0), // memorize nCurYOffset and not take it from EditEngine
978 nMarkerPos(NoMarker)
980 setBackgroundColor(GetSettings().GetStyleSettings().GetFieldColor());
981 SetHelpId(HID_BASICIDE_BREAKPOINTWINDOW);
984 BreakPointWindow::~BreakPointWindow()
990 void BreakPointWindow::Paint( const Rectangle& )
992 if ( SyncYOffset() )
993 return;
995 Size const aOutSz = GetOutputSize();
996 long const nLineHeight = GetTextHeight();
998 Image const aBrk[2] = { GetImage(IMGID_BRKDISABLED), GetImage(IMGID_BRKENABLED) };
999 Size const aBmpSz = PixelToLogic(aBrk[1].GetSizePixel());
1000 Point const aBmpOff(
1001 (aOutSz.Width() - aBmpSz.Width()) / 2,
1002 (nLineHeight - aBmpSz.Height()) / 2
1005 for (size_t i = 0, n = GetBreakPoints().size(); i < n; ++i)
1007 BreakPoint& rBrk = *GetBreakPoints().at(i);
1008 size_t const nLine = rBrk.nLine - 1;
1009 size_t const nY = nLine*nLineHeight - nCurYOffset;
1010 DrawImage(Point(0, nY) + aBmpOff, aBrk[rBrk.bEnabled]);
1012 ShowMarker(true);
1017 void BreakPointWindow::DoScroll( long nHorzScroll, long nVertScroll )
1019 nCurYOffset -= nVertScroll;
1020 Window::Scroll( nHorzScroll, nVertScroll );
1025 void BreakPointWindow::SetMarkerPos( sal_uInt16 nLine, bool bError )
1027 if ( SyncYOffset() )
1028 Update();
1030 ShowMarker( false );
1031 nMarkerPos = nLine;
1032 bErrorMarker = bError;
1033 ShowMarker( true );
1036 void BreakPointWindow::SetNoMarker ()
1038 SetMarkerPos(NoMarker);
1041 void BreakPointWindow::ShowMarker( bool bShow )
1043 if ( nMarkerPos == NoMarker )
1044 return;
1046 Size const aOutSz = GetOutputSize();
1047 long const nLineHeight = GetTextHeight();
1049 Image aMarker = GetImage(bErrorMarker ? IMGID_ERRORMARKER : IMGID_STEPMARKER);
1051 Size aMarkerSz( aMarker.GetSizePixel() );
1052 aMarkerSz = PixelToLogic( aMarkerSz );
1053 Point aMarkerOff( 0, 0 );
1054 aMarkerOff.X() = ( aOutSz.Width() - aMarkerSz.Width() ) / 2;
1055 aMarkerOff.Y() = ( nLineHeight - aMarkerSz.Height() ) / 2;
1057 sal_uLong nY = nMarkerPos*nLineHeight - nCurYOffset;
1058 Point aPos( 0, nY );
1059 aPos += aMarkerOff;
1060 if ( bShow )
1061 DrawImage( aPos, aMarker );
1062 else
1063 Invalidate( Rectangle( aPos, aMarkerSz ) );
1069 BreakPoint* BreakPointWindow::FindBreakPoint( const Point& rMousePos )
1071 size_t nLineHeight = GetTextHeight();
1072 size_t nYPos = rMousePos.Y() + nCurYOffset;
1074 for ( size_t i = 0, n = GetBreakPoints().size(); i < n ; ++i )
1076 BreakPoint* pBrk = GetBreakPoints().at( i );
1077 size_t nLine = pBrk->nLine-1;
1078 size_t nY = nLine*nLineHeight;
1079 if ( ( nYPos > nY ) && ( nYPos < ( nY + nLineHeight ) ) )
1080 return pBrk;
1082 return 0;
1085 void BreakPointWindow::MouseButtonDown( const MouseEvent& rMEvt )
1087 if ( rMEvt.GetClicks() == 2 )
1089 Point aMousePos( PixelToLogic( rMEvt.GetPosPixel() ) );
1090 long nLineHeight = GetTextHeight();
1091 long nYPos = aMousePos.Y() + nCurYOffset;
1092 long nLine = nYPos / nLineHeight + 1;
1093 rModulWindow.ToggleBreakPoint( (sal_uLong)nLine );
1094 Invalidate();
1100 void BreakPointWindow::Command( const CommandEvent& rCEvt )
1102 if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
1104 Point aPos( rCEvt.IsMouseEvent() ? rCEvt.GetMousePosPixel() : Point(1,1) );
1105 Point aEventPos( PixelToLogic( aPos ) );
1106 BreakPoint* pBrk = rCEvt.IsMouseEvent() ? FindBreakPoint( aEventPos ) : 0;
1107 if ( pBrk )
1109 // test if break point is enabled...
1110 PopupMenu aBrkPropMenu( IDEResId( RID_POPUP_BRKPROPS ) );
1111 aBrkPropMenu.CheckItem( RID_ACTIV, pBrk->bEnabled );
1112 switch ( aBrkPropMenu.Execute( this, aPos ) )
1114 case RID_ACTIV:
1116 pBrk->bEnabled = !pBrk->bEnabled;
1117 rModulWindow.UpdateBreakPoint( *pBrk );
1118 Invalidate();
1120 break;
1121 case RID_BRKPROPS:
1123 BreakPointDialog aBrkDlg( this, GetBreakPoints() );
1124 aBrkDlg.SetCurrentBreakPoint( pBrk );
1125 aBrkDlg.Execute();
1126 Invalidate();
1128 break;
1131 else
1133 PopupMenu aBrkListMenu( IDEResId( RID_POPUP_BRKDLG ) );
1134 switch ( aBrkListMenu.Execute( this, aPos ) )
1136 case RID_BRKDLG:
1138 BreakPointDialog aBrkDlg( this, GetBreakPoints() );
1139 aBrkDlg.Execute();
1140 Invalidate();
1142 break;
1148 bool BreakPointWindow::SyncYOffset()
1150 TextView* pView = rModulWindow.GetEditView();
1151 if ( pView )
1153 long nViewYOffset = pView->GetStartDocPos().Y();
1154 if ( nCurYOffset != nViewYOffset )
1156 nCurYOffset = nViewYOffset;
1157 Invalidate();
1158 return true;
1161 return false;
1164 // virtual
1165 void BreakPointWindow::DataChanged(DataChangedEvent const & rDCEvt)
1167 Window::DataChanged(rDCEvt);
1168 if (rDCEvt.GetType() == DATACHANGED_SETTINGS
1169 && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
1171 Color aColor(GetSettings().GetStyleSettings().GetFieldColor());
1172 const AllSettings* pOldSettings = rDCEvt.GetOldSettings();
1173 if (!pOldSettings || aColor != pOldSettings->GetStyleSettings().GetFieldColor())
1175 setBackgroundColor(aColor);
1176 Invalidate();
1181 void BreakPointWindow::setBackgroundColor(Color aColor)
1183 SetBackground(Wallpaper(aColor));
1188 // WatchWindow
1189 // ===========
1192 namespace
1194 const sal_uInt16 ITEM_ID_VARIABLE = 1;
1195 const sal_uInt16 ITEM_ID_VALUE = 2;
1196 const sal_uInt16 ITEM_ID_TYPE = 3;
1199 WatchWindow::WatchWindow (Layout* pParent) :
1200 DockingWindow(pParent),
1201 aWatchStr( IDEResId( RID_STR_REMOVEWATCH ) ),
1202 aXEdit( this, IDEResId( RID_EDT_WATCHEDIT ) ),
1203 aRemoveWatchButton( this, IDEResId( RID_IMGBTN_REMOVEWATCH ) ),
1204 aTreeListBox( this, WB_BORDER | WB_3DLOOK | WB_HASBUTTONS | WB_HASLINES | WB_HSCROLL | WB_TABSTOP
1205 | WB_HASLINESATROOT | WB_HASBUTTONSATROOT ),
1206 aHeaderBar( this, WB_BUTTONSTYLE | WB_BORDER )
1208 aXEdit.SetAccessibleName(String(IDEResId( RID_STR_WATCHNAME)));
1209 aTreeListBox.SetAccessibleName(String(IDEResId(RID_STR_WATCHNAME)));
1211 long nTextLen = GetTextWidth( aWatchStr ) + DWBORDER + 3;
1212 aXEdit.SetPosPixel( Point( nTextLen, 3 ) );
1213 aXEdit.SetAccHdl( LINK( this, WatchWindow, EditAccHdl ) );
1214 aXEdit.GetAccelerator().InsertItem( 1, KeyCode( KEY_RETURN ) );
1215 aXEdit.GetAccelerator().InsertItem( 2, KeyCode( KEY_ESCAPE ) );
1216 aXEdit.Show();
1218 aRemoveWatchButton.Disable();
1219 aRemoveWatchButton.SetClickHdl( LINK( this, WatchWindow, ButtonHdl ) );
1220 aRemoveWatchButton.SetPosPixel( Point( nTextLen + aXEdit.GetSizePixel().Width() + 4, 2 ) );
1221 Size aSz( aRemoveWatchButton.GetModeImage().GetSizePixel() );
1222 aSz.Width() += 6;
1223 aSz.Height() += 6;
1224 aRemoveWatchButton.SetSizePixel( aSz );
1225 aRemoveWatchButton.Show();
1227 long nRWBtnSize = aRemoveWatchButton.GetModeImage().GetSizePixel().Height() + 10;
1228 nVirtToolBoxHeight = aXEdit.GetSizePixel().Height() + 7;
1230 if ( nRWBtnSize > nVirtToolBoxHeight )
1231 nVirtToolBoxHeight = nRWBtnSize;
1233 nHeaderBarHeight = 16;
1235 aTreeListBox.SetHelpId(HID_BASICIDE_WATCHWINDOW_LIST);
1236 aTreeListBox.EnableInplaceEditing(true);
1237 aTreeListBox.SetSelectHdl( LINK( this, WatchWindow, TreeListHdl ) );
1238 aTreeListBox.SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight + nHeaderBarHeight ) );
1239 aTreeListBox.SetHighlightRange( 1, 5 );
1241 Point aPnt( DWBORDER, nVirtToolBoxHeight + 1 );
1242 aHeaderBar.SetPosPixel( aPnt );
1243 aHeaderBar.SetEndDragHdl( LINK( this, WatchWindow, implEndDragHdl ) );
1245 long nVarTabWidth = 220;
1246 long nValueTabWidth = 100;
1247 long nTypeTabWidth = 1250;
1248 aHeaderBar.InsertItem( ITEM_ID_VARIABLE, String( IDEResId( RID_STR_WATCHVARIABLE ) ), nVarTabWidth );
1249 aHeaderBar.InsertItem( ITEM_ID_VALUE, String( IDEResId( RID_STR_WATCHVALUE ) ), nValueTabWidth );
1250 aHeaderBar.InsertItem( ITEM_ID_TYPE, String( IDEResId( RID_STR_WATCHTYPE ) ), nTypeTabWidth );
1252 long tabs[ 4 ];
1253 tabs[ 0 ] = 3; // two tabs
1254 tabs[ 1 ] = 0;
1255 tabs[ 2 ] = nVarTabWidth;
1256 tabs[ 3 ] = nVarTabWidth + nValueTabWidth;
1257 aTreeListBox.SvHeaderTabListBox::SetTabs( tabs, MAP_PIXEL );
1258 aTreeListBox.InitHeaderBar( &aHeaderBar );
1260 aTreeListBox.SetNodeDefaultImages( );
1262 aHeaderBar.Show();
1264 aTreeListBox.Show();
1266 SetText( String( IDEResId( RID_STR_WATCHNAME ) ) );
1268 SetHelpId( HID_BASICIDE_WATCHWINDOW );
1270 // make watch window keyboard accessible
1271 GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
1276 WatchWindow::~WatchWindow()
1278 GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
1283 void WatchWindow::Paint( const Rectangle& )
1285 DrawText( Point( DWBORDER, 7 ), aWatchStr );
1286 lcl_DrawIDEWindowFrame( this );
1291 void WatchWindow::Resize()
1293 Size aSz = GetOutputSizePixel();
1294 Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );
1296 if ( aBoxSz.Width() < 4 )
1297 aBoxSz.Width() = 0;
1298 if ( aBoxSz.Height() < 4 )
1299 aBoxSz.Height() = 0;
1301 aBoxSz.Height() -= nHeaderBarHeight;
1302 aTreeListBox.SetSizePixel( aBoxSz );
1303 aTreeListBox.GetHScroll()->SetPageSize( aTreeListBox.GetHScroll()->GetVisibleSize() );
1305 aBoxSz.Height() = nHeaderBarHeight;
1306 aHeaderBar.SetSizePixel( aBoxSz );
1308 Invalidate();
1311 struct WatchItem
1313 String maName;
1314 String maDisplayName;
1315 SbxObjectRef mpObject;
1316 std::vector<String> maMemberList;
1318 SbxDimArrayRef mpArray;
1319 int nDimLevel; // 0 = Root
1320 int nDimCount;
1321 std::vector<short> vIndices;
1323 WatchItem* mpArrayParentItem;
1325 WatchItem (String const& rName):
1326 maName(rName),
1327 nDimLevel(0),
1328 nDimCount(0),
1329 mpArrayParentItem(0)
1332 void clearWatchItem ()
1334 maMemberList.clear();
1337 WatchItem* GetRootItem( void );
1338 SbxDimArray* GetRootArray( void );
1341 WatchItem* WatchItem::GetRootItem( void )
1343 WatchItem* pItem = mpArrayParentItem;
1344 while( pItem )
1346 if( pItem->mpArray.Is() )
1347 break;
1348 pItem = pItem->mpArrayParentItem;
1350 return pItem;
1353 SbxDimArray* WatchItem::GetRootArray( void )
1355 WatchItem* pRootItem = GetRootItem();
1356 SbxDimArray* pRet = NULL;
1357 if( pRootItem )
1358 pRet = pRootItem->mpArray;
1359 return pRet;
1362 void WatchWindow::AddWatch( const OUString& rVName )
1364 String aVar, aIndex;
1365 lcl_SeparateNameAndIndex( rVName, aVar, aIndex );
1366 WatchItem* pWatchItem = new WatchItem(aVar);
1368 OUString aWatchStr_( aVar );
1369 aWatchStr_ += "\t\t";
1370 SvTreeListEntry* pNewEntry = aTreeListBox.InsertEntry( aWatchStr_, 0, true, LIST_APPEND );
1371 pNewEntry->SetUserData( pWatchItem );
1373 aTreeListBox.Select(pNewEntry, true);
1374 aTreeListBox.MakeVisible(pNewEntry);
1375 aRemoveWatchButton.Enable();
1377 UpdateWatches();
1380 bool WatchWindow::RemoveSelectedWatch()
1382 SvTreeListEntry* pEntry = aTreeListBox.GetCurEntry();
1383 if ( pEntry )
1385 aTreeListBox.GetModel()->Remove( pEntry );
1386 pEntry = aTreeListBox.GetCurEntry();
1387 if ( pEntry )
1388 aXEdit.SetText( ((WatchItem*)pEntry->GetUserData())->maName );
1389 else
1390 aXEdit.SetText( String() );
1391 if ( !aTreeListBox.GetEntryCount() )
1392 aRemoveWatchButton.Disable();
1393 return true;
1395 else
1396 return false;
1400 IMPL_LINK_INLINE_START( WatchWindow, ButtonHdl, ImageButton *, pButton )
1402 if (pButton == &aRemoveWatchButton)
1403 if (SfxDispatcher* pDispatcher = GetDispatcher())
1404 pDispatcher->Execute(SID_BASICIDE_REMOVEWATCH);
1405 return 0;
1407 IMPL_LINK_INLINE_END( WatchWindow, ButtonHdl, ImageButton *, pButton )
1411 IMPL_LINK_NOARG_INLINE_START(WatchWindow, TreeListHdl)
1413 SvTreeListEntry* pCurEntry = aTreeListBox.GetCurEntry();
1414 if ( pCurEntry && pCurEntry->GetUserData() )
1415 aXEdit.SetText( ((WatchItem*)pCurEntry->GetUserData())->maName );
1417 return 0;
1419 IMPL_LINK_NOARG_INLINE_END(WatchWindow, TreeListHdl)
1422 IMPL_LINK_INLINE_START( WatchWindow, implEndDragHdl, HeaderBar *, pBar )
1424 (void)pBar;
1426 const sal_Int32 TAB_WIDTH_MIN = 10;
1427 sal_Int32 nMaxWidth =
1428 aHeaderBar.GetSizePixel().getWidth() - 2 * TAB_WIDTH_MIN;
1430 sal_Int32 nVariableWith = aHeaderBar.GetItemSize( ITEM_ID_VARIABLE );
1431 if( nVariableWith < TAB_WIDTH_MIN )
1432 aHeaderBar.SetItemSize( ITEM_ID_VARIABLE, TAB_WIDTH_MIN );
1433 else if( nVariableWith > nMaxWidth )
1434 aHeaderBar.SetItemSize( ITEM_ID_VARIABLE, nMaxWidth );
1436 sal_Int32 nValueWith = aHeaderBar.GetItemSize( ITEM_ID_VALUE );
1437 if( nValueWith < TAB_WIDTH_MIN )
1438 aHeaderBar.SetItemSize( ITEM_ID_VALUE, TAB_WIDTH_MIN );
1439 else if( nValueWith > nMaxWidth )
1440 aHeaderBar.SetItemSize( ITEM_ID_VALUE, nMaxWidth );
1442 if (aHeaderBar.GetItemSize( ITEM_ID_TYPE ) < TAB_WIDTH_MIN)
1443 aHeaderBar.SetItemSize( ITEM_ID_TYPE, TAB_WIDTH_MIN );
1445 sal_Int32 nPos = 0;
1446 sal_uInt16 nTabs = aHeaderBar.GetItemCount();
1447 for( sal_uInt16 i = 1 ; i < nTabs ; ++i )
1449 nPos += aHeaderBar.GetItemSize( i );
1450 aTreeListBox.SetTab( i, nPos, MAP_PIXEL );
1452 return 0;
1454 IMPL_LINK_INLINE_END( WatchWindow, implEndDragHdl, HeaderBar *, pBar )
1457 IMPL_LINK( WatchWindow, EditAccHdl, Accelerator *, pAcc )
1459 switch ( pAcc->GetCurKeyCode().GetCode() )
1461 case KEY_RETURN:
1463 String aCurText( aXEdit.GetText() );
1464 if ( aCurText.Len() )
1466 AddWatch( aCurText );
1467 aXEdit.SetSelection( Selection( 0, 0xFFFF ) );
1470 break;
1471 case KEY_ESCAPE:
1473 aXEdit.SetText( String() );
1475 break;
1478 return 0;
1481 void WatchWindow::UpdateWatches( bool bBasicStopped )
1483 aTreeListBox.UpdateWatches( bBasicStopped );
1488 // StackWindow
1489 // ===========
1492 StackWindow::StackWindow (Layout* pParent) :
1493 DockingWindow(pParent),
1494 aTreeListBox( this, WB_BORDER | WB_3DLOOK | WB_HSCROLL | WB_TABSTOP ),
1495 aStackStr( IDEResId( RID_STR_STACK ) )
1497 aTreeListBox.SetHelpId(HID_BASICIDE_STACKWINDOW_LIST);
1498 aTreeListBox.SetAccessibleName(String( IDEResId(RID_STR_STACKNAME)));
1499 aTreeListBox.SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight ) );
1500 aTreeListBox.SetHighlightRange();
1501 aTreeListBox.SetSelectionMode( NO_SELECTION );
1502 aTreeListBox.InsertEntry( String(), 0, false, LIST_APPEND );
1503 aTreeListBox.Show();
1505 SetText( String( IDEResId( RID_STR_STACKNAME ) ) );
1507 SetHelpId( HID_BASICIDE_STACKWINDOW );
1509 // make stack window keyboard accessible
1510 GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
1515 StackWindow::~StackWindow()
1517 GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
1522 void StackWindow::Paint( const Rectangle& )
1524 DrawText( Point( DWBORDER, 7 ), aStackStr );
1525 lcl_DrawIDEWindowFrame( this );
1530 void StackWindow::Resize()
1532 Size aSz = GetOutputSizePixel();
1533 Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );
1535 if ( aBoxSz.Width() < 4 )
1536 aBoxSz.Width() = 0;
1537 if ( aBoxSz.Height() < 4 )
1538 aBoxSz.Height() = 0;
1540 aTreeListBox.SetSizePixel( aBoxSz );
1542 Invalidate();
1545 void StackWindow::UpdateCalls()
1547 aTreeListBox.SetUpdateMode(false);
1548 aTreeListBox.Clear();
1550 if ( StarBASIC::IsRunning() )
1552 SbxError eOld = SbxBase::GetError();
1553 aTreeListBox.SetSelectionMode( SINGLE_SELECTION );
1555 sal_Int32 nScope = 0;
1556 SbMethod* pMethod = StarBASIC::GetActiveMethod( nScope );
1557 while ( pMethod )
1559 OUString aEntry( OUString::number(nScope ));
1560 if ( aEntry.getLength() < 2 )
1561 aEntry = " " + aEntry;
1562 aEntry += ": " + pMethod->GetName();
1563 SbxArray* pParams = pMethod->GetParameters();
1564 SbxInfo* pInfo = pMethod->GetInfo();
1565 if ( pParams )
1567 aEntry += "(";
1568 // 0 is the sub's name...
1569 for ( sal_uInt16 nParam = 1; nParam < pParams->Count(); nParam++ )
1571 SbxVariable* pVar = pParams->Get( nParam );
1572 DBG_ASSERT( pVar, "Parameter?!" );
1573 if ( !pVar->GetName().isEmpty() )
1575 aEntry += pVar->GetName();
1577 else if ( pInfo )
1579 const SbxParamInfo* pParam = pInfo->GetParam( nParam );
1580 if ( pParam )
1582 aEntry += pParam->aName;
1585 aEntry += "=";
1586 SbxDataType eType = pVar->GetType();
1587 if( eType & SbxARRAY )
1589 aEntry += "..." ;
1591 else if( eType != SbxOBJECT )
1593 aEntry += pVar->GetOUString();
1595 if ( nParam < ( pParams->Count() - 1 ) )
1597 aEntry += ", ";
1600 aEntry += ")";
1602 aTreeListBox.InsertEntry( aEntry, 0, false, LIST_APPEND );
1603 nScope++;
1604 pMethod = StarBASIC::GetActiveMethod( nScope );
1607 SbxBase::ResetError();
1608 if( eOld != SbxERR_OK )
1609 SbxBase::SetError( eOld );
1611 else
1613 aTreeListBox.SetSelectionMode( NO_SELECTION );
1614 aTreeListBox.InsertEntry( String(), 0, false, LIST_APPEND );
1617 aTreeListBox.SetUpdateMode(true);
1622 // ComplexEditorWindow
1623 // ===================
1626 ComplexEditorWindow::ComplexEditorWindow( ModulWindow* pParent ) :
1627 Window( pParent, WB_3DLOOK | WB_CLIPCHILDREN ),
1628 aBrkWindow(this, pParent),
1629 aLineNumberWindow(this, pParent),
1630 aEdtWindow(this, pParent),
1631 aEWVScrollBar( this, WB_VSCROLL | WB_DRAG )
1633 aEdtWindow.Show();
1634 aBrkWindow.Show();
1636 aEWVScrollBar.SetLineSize(nScrollLine);
1637 aEWVScrollBar.SetPageSize(nScrollPage);
1638 aEWVScrollBar.SetScrollHdl( LINK( this, ComplexEditorWindow, ScrollHdl ) );
1639 aEWVScrollBar.Show();
1642 void ComplexEditorWindow::Resize()
1644 Size aOutSz = GetOutputSizePixel();
1645 Size aSz( aOutSz );
1646 aSz.Width() -= 2*DWBORDER;
1647 aSz.Height() -= 2*DWBORDER;
1648 long nBrkWidth = 20;
1649 long nSBWidth = aEWVScrollBar.GetSizePixel().Width();
1651 Size aBrkSz(nBrkWidth, aSz.Height());
1653 Size aLnSz(aLineNumberWindow.GetWidth(), aSz.Height());
1655 if (aLineNumberWindow.IsVisible())
1657 aBrkWindow.SetPosSizePixel( Point( DWBORDER, DWBORDER ), aBrkSz );
1658 aLineNumberWindow.SetPosSizePixel(Point(DWBORDER + aBrkSz.Width() - 1, DWBORDER), aLnSz);
1659 Size aEWSz(aSz.Width() - nBrkWidth - aLineNumberWindow.GetWidth() - nSBWidth + 2, aSz.Height());
1660 aEdtWindow.SetPosSizePixel( Point( DWBORDER + aBrkSz.Width() + aLnSz.Width() - 1, DWBORDER ), aEWSz );
1662 else
1664 aBrkWindow.SetPosSizePixel( Point( DWBORDER, DWBORDER ), aBrkSz );
1665 Size aEWSz(aSz.Width() - nBrkWidth - nSBWidth + 2, aSz.Height());
1666 aEdtWindow.SetPosSizePixel(Point(DWBORDER + aBrkSz.Width() - 1, DWBORDER), aEWSz);
1669 aEWVScrollBar.SetPosSizePixel( Point( aOutSz.Width() - DWBORDER - nSBWidth, DWBORDER ), Size( nSBWidth, aSz.Height() ) );
1672 IMPL_LINK( ComplexEditorWindow, ScrollHdl, ScrollBar *, pCurScrollBar )
1674 if ( aEdtWindow.GetEditView() )
1676 DBG_ASSERT( pCurScrollBar == &aEWVScrollBar, "Wer scrollt hier ?" );
1677 long nDiff = aEdtWindow.GetEditView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
1678 aEdtWindow.GetEditView()->Scroll( 0, nDiff );
1679 aBrkWindow.DoScroll( 0, nDiff );
1680 aLineNumberWindow.DoScroll(0, nDiff);
1681 aEdtWindow.GetEditView()->ShowCursor(false, true);
1682 pCurScrollBar->SetThumbPos( aEdtWindow.GetEditView()->GetStartDocPos().Y() );
1685 return 0;
1688 void ComplexEditorWindow::DataChanged(DataChangedEvent const & rDCEvt)
1690 Window::DataChanged(rDCEvt);
1691 if (rDCEvt.GetType() == DATACHANGED_SETTINGS
1692 && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
1694 Color aColor(GetSettings().GetStyleSettings().GetFaceColor());
1695 const AllSettings* pOldSettings = rDCEvt.GetOldSettings();
1696 if (!pOldSettings || aColor != pOldSettings->GetStyleSettings().GetFaceColor())
1698 SetBackground(Wallpaper(aColor));
1699 Invalidate();
1704 void ComplexEditorWindow::SetLineNumberDisplay(bool b)
1706 aLineNumberWindow.Show(b);
1707 Resize();
1710 uno::Reference< awt::XWindowPeer >
1711 EditorWindow::GetComponentInterface(sal_Bool bCreate)
1713 uno::Reference< awt::XWindowPeer > xPeer(
1714 Window::GetComponentInterface(false));
1715 if (!xPeer.is() && bCreate)
1717 // Make sure edit engine and view are available:
1718 if (!pEditEngine)
1719 CreateEditEngine();
1721 xPeer = new ::svt::TextWindowPeer(*GetEditView());
1722 SetComponentInterface(xPeer);
1724 return xPeer;
1729 // WatchTreeListBox
1730 // ================
1733 WatchTreeListBox::WatchTreeListBox( Window* pParent, WinBits nWinBits )
1734 : SvHeaderTabListBox( pParent, nWinBits )
1737 WatchTreeListBox::~WatchTreeListBox()
1739 // Destroy user data
1740 SvTreeListEntry* pEntry = First();
1741 while ( pEntry )
1743 delete (WatchItem*)pEntry->GetUserData();
1744 pEntry = Next( pEntry );
1748 void WatchTreeListBox::SetTabs()
1750 SvHeaderTabListBox::SetTabs();
1751 sal_uInt16 nTabCount_ = aTabs.size();
1752 for( sal_uInt16 i = 0 ; i < nTabCount_ ; i++ )
1754 SvLBoxTab* pTab = aTabs[i];
1755 if( i == 2 )
1756 pTab->nFlags |= SV_LBOXTAB_EDITABLE;
1757 else
1758 pTab->nFlags &= ~SV_LBOXTAB_EDITABLE;
1762 void WatchTreeListBox::RequestingChildren( SvTreeListEntry * pParent )
1764 if( !StarBASIC::IsRunning() )
1765 return;
1767 if( GetChildCount( pParent ) > 0 )
1768 return;
1770 SvTreeListEntry* pEntry = pParent;
1771 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1773 SbxDimArray* pArray = pItem->mpArray;
1774 SbxDimArray* pRootArray = pItem->GetRootArray();
1775 bool bArrayIsRootArray = false;
1776 if( !pArray && pRootArray )
1778 pArray = pRootArray;
1779 bArrayIsRootArray = true;
1782 SbxObject* pObj = pItem->mpObject;
1783 if( pObj )
1785 createAllObjectProperties( pObj );
1786 SbxArray* pProps = pObj->GetProperties();
1787 sal_uInt16 nPropCount = pProps->Count();
1788 pItem->maMemberList.reserve(nPropCount);
1790 for( sal_uInt16 i = 0 ; i < nPropCount - 3 ; i++ )
1792 SbxVariable* pVar = pProps->Get( i );
1794 pItem->maMemberList.push_back(String(pVar->GetName()));
1795 String const& rName = pItem->maMemberList.back();
1796 SvTreeListEntry* pChildEntry = SvTreeListBox::InsertEntry( rName, pEntry );
1797 pChildEntry->SetUserData(new WatchItem(rName));
1799 if( nPropCount > 0 )
1801 UpdateWatches();
1804 else if( pArray )
1806 sal_uInt16 nElementCount = 0;
1808 // Loop through indices of current level
1809 int nParentLevel = bArrayIsRootArray ? pItem->nDimLevel : 0;
1810 int nThisLevel = nParentLevel + 1;
1811 sal_Int32 nMin, nMax;
1812 pArray->GetDim32( nThisLevel, nMin, nMax );
1813 for( sal_Int32 i = nMin ; i <= nMax ; i++ )
1815 WatchItem* pChildItem = new WatchItem(pItem->maName);
1817 // Copy data and create name
1819 OUString aIndexStr = "(";
1820 pChildItem->mpArrayParentItem = pItem;
1821 pChildItem->nDimLevel = nThisLevel;
1822 pChildItem->nDimCount = pItem->nDimCount;
1823 pChildItem->vIndices.resize(pChildItem->nDimCount);
1824 sal_Int32 j;
1825 for( j = 0 ; j < nParentLevel ; j++ )
1827 short n = pChildItem->vIndices[j] = pItem->vIndices[j];
1828 aIndexStr += OUString::number( n ) + ",";
1830 pChildItem->vIndices[nParentLevel] = sal::static_int_cast<short>( i );
1831 aIndexStr += OUString::number( i ) + ")";
1833 OUString aDisplayName;
1834 WatchItem* pArrayRootItem = pChildItem->GetRootItem();
1835 if( pArrayRootItem && pArrayRootItem->mpArrayParentItem )
1836 aDisplayName = pItem->maDisplayName;
1837 else
1838 aDisplayName = pItem->maName;
1839 aDisplayName += aIndexStr;
1840 pChildItem->maDisplayName = aDisplayName;
1842 SvTreeListEntry* pChildEntry = SvTreeListBox::InsertEntry( aDisplayName, pEntry );
1843 nElementCount++;
1844 pChildEntry->SetUserData( pChildItem );
1846 if( nElementCount > 0 )
1848 UpdateWatches();
1853 SbxBase* WatchTreeListBox::ImplGetSBXForEntry( SvTreeListEntry* pEntry, bool& rbArrayElement )
1855 SbxBase* pSBX = NULL;
1856 rbArrayElement = false;
1858 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1859 String aVName( pItem->maName );
1861 SvTreeListEntry* pParentEntry = GetParent( pEntry );
1862 WatchItem* pParentItem = pParentEntry ? (WatchItem*)pParentEntry->GetUserData() : NULL;
1863 if( pParentItem )
1865 SbxObject* pObj = pParentItem->mpObject;
1866 SbxDimArray* pArray;
1867 if( pObj )
1869 pSBX = pObj->Find( aVName, SbxCLASS_DONTCARE );
1870 if (SbxVariable const* pVar = IsSbxVariable(pSBX))
1872 // Force getting value
1873 SbxValues aRes;
1874 aRes.eType = SbxVOID;
1875 pVar->Get( aRes );
1878 // Array?
1879 else if( (pArray = pItem->GetRootArray()) != NULL )
1881 rbArrayElement = true;
1882 if( pParentItem->nDimLevel + 1 == pParentItem->nDimCount )
1883 pSBX = pArray->Get(pItem->vIndices.empty() ? 0 : &*pItem->vIndices.begin());
1886 else
1888 pSBX = StarBASIC::FindSBXInCurrentScope( aVName );
1890 return pSBX;
1893 sal_Bool WatchTreeListBox::EditingEntry( SvTreeListEntry* pEntry, Selection& )
1895 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1897 bool bEdit = false;
1898 if ( StarBASIC::IsRunning() && StarBASIC::GetActiveMethod() && !SbxBase::IsError() )
1900 // No out of scope entries
1901 bool bArrayElement;
1902 SbxBase* pSbx = ImplGetSBXForEntry( pEntry, bArrayElement );
1903 if (IsSbxVariable(pSbx) || bArrayElement)
1905 // Accept no objects and only end nodes of arrays for editing
1906 if( !pItem->mpObject && (pItem->mpArray == NULL || pItem->nDimLevel == pItem->nDimCount) )
1908 aEditingRes = SvHeaderTabListBox::GetEntryText( pEntry, ITEM_ID_VALUE-1 );
1909 aEditingRes = comphelper::string::strip(aEditingRes, ' ');
1910 bEdit = true;
1915 return bEdit;
1918 sal_Bool WatchTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText )
1920 String aResult = comphelper::string::strip(rNewText, ' ');
1922 sal_uInt16 nResultLen = aResult.Len();
1923 sal_Unicode cFirst = aResult.GetChar( 0 );
1924 sal_Unicode cLast = aResult.GetChar( nResultLen - 1 );
1925 if( cFirst == '\"' && cLast == '\"' )
1926 aResult = aResult.Copy( 1, nResultLen - 2 );
1928 return aResult != aEditingRes && ImplBasicEntryEdited(pEntry, aResult);
1931 bool WatchTreeListBox::ImplBasicEntryEdited( SvTreeListEntry* pEntry, const OUString& rResult )
1933 bool bArrayElement;
1934 SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
1936 if (SbxVariable* pVar = IsSbxVariable(pSBX))
1938 SbxDataType eType = pVar->GetType();
1939 if ( (sal_uInt8)eType != (sal_uInt8)SbxOBJECT
1940 && ( eType & SbxARRAY ) == 0 )
1942 // If the type is variable, the conversion of the SBX does not matter,
1943 // else the string is converted.
1944 pVar->PutStringExt( rResult );
1948 if ( SbxBase::IsError() )
1950 SbxBase::ResetError();
1953 UpdateWatches();
1955 // The text should never be taken/copied 1:1,
1956 // as the UpdateWatches will be lost
1957 return false;
1961 namespace
1964 void implCollapseModifiedObjectEntry( SvTreeListEntry* pParent, WatchTreeListBox* pThis )
1966 pThis->Collapse( pParent );
1968 SvTreeList* pModel = pThis->GetModel();
1969 SvTreeListEntry* pDeleteEntry;
1970 while( (pDeleteEntry = pThis->SvTreeListBox::GetEntry( pParent, 0 )) != NULL )
1972 implCollapseModifiedObjectEntry( pDeleteEntry, pThis );
1974 delete (WatchItem*)pDeleteEntry->GetUserData();
1975 pModel->Remove( pDeleteEntry );
1979 String implCreateTypeStringForDimArray( WatchItem* pItem, SbxDataType eType )
1981 OUString aRetStr = getBasicTypeName( eType );
1983 SbxDimArray* pArray = pItem->mpArray;
1984 if( !pArray )
1985 pArray = pItem->GetRootArray();
1986 if( pArray )
1988 int nDimLevel = pItem->nDimLevel;
1989 int nDims = pItem->nDimCount;
1990 if( nDimLevel < nDims )
1992 aRetStr += "(";
1993 for( int i = nDimLevel ; i < nDims ; i++ )
1995 short nMin, nMax;
1996 pArray->GetDim( sal::static_int_cast<short>( i+1 ), nMin, nMax );
1997 aRetStr += OUString::number(nMin) + " to " + OUString::number(nMax);
1998 if( i < nDims - 1 )
1999 aRetStr += ", ";
2001 aRetStr += ")";
2004 return aRetStr;
2007 void implEnableChildren( SvTreeListEntry* pEntry, bool bEnable )
2009 if( bEnable )
2011 pEntry->SetFlags(
2012 (pEntry->GetFlags() &
2013 ~(SV_ENTRYFLAG_NO_NODEBMP | SV_ENTRYFLAG_HAD_CHILDREN))
2014 | SV_ENTRYFLAG_CHILDREN_ON_DEMAND );
2016 else
2018 pEntry->SetFlags(
2019 (pEntry->GetFlags() & ~(SV_ENTRYFLAG_CHILDREN_ON_DEMAND)) );
2023 } // namespace
2025 void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
2027 SbMethod* pCurMethod = StarBASIC::GetActiveMethod();
2029 SbxError eOld = SbxBase::GetError();
2030 setBasicWatchMode( true );
2032 SvTreeListEntry* pEntry = First();
2033 while ( pEntry )
2035 WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
2036 String aVName( pItem->maName );
2037 DBG_ASSERT( aVName.Len(), "Var? - Must not be empty!" );
2038 String aWatchStr;
2039 String aTypeStr;
2040 if ( pCurMethod )
2042 bool bArrayElement;
2043 SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
2045 // Array? If no end node create type string
2046 if( bArrayElement && pItem->nDimLevel < pItem->nDimCount )
2048 SbxDimArray* pRootArray = pItem->GetRootArray();
2049 SbxDataType eType = pRootArray->GetType();
2050 aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
2051 implEnableChildren( pEntry, true );
2054 bool bCollapse = false;
2055 if (SbxVariable const* pVar = IsSbxVariable(pSBX))
2057 // extra treatment of arrays
2058 SbxDataType eType = pVar->GetType();
2059 if ( eType & SbxARRAY )
2061 // consider multidimensinal arrays!
2062 if (SbxDimArray* pNewArray = dynamic_cast<SbxDimArray*>(pVar->GetObject()))
2064 SbxDimArray* pOldArray = pItem->mpArray;
2066 bool bArrayChanged = false;
2067 if( pNewArray != NULL && pOldArray != NULL )
2069 // Compare Array dimensions to see if array has changed
2070 // Can be a copy, so comparing pointers does not work
2071 sal_uInt16 nOldDims = pOldArray->GetDims();
2072 sal_uInt16 nNewDims = pNewArray->GetDims();
2073 if( nOldDims != nNewDims )
2075 bArrayChanged = true;
2077 else
2079 for( int i = 0 ; i < nOldDims ; i++ )
2081 short nOldMin, nOldMax;
2082 short nNewMin, nNewMax;
2084 pOldArray->GetDim( sal::static_int_cast<short>( i+1 ), nOldMin, nOldMax );
2085 pNewArray->GetDim( sal::static_int_cast<short>( i+1 ), nNewMin, nNewMax );
2086 if( nOldMin != nNewMin || nOldMax != nNewMax )
2088 bArrayChanged = true;
2089 break;
2094 else if( pNewArray == NULL || pOldArray == NULL )
2096 bArrayChanged = true;
2098 if( pNewArray )
2100 implEnableChildren( pEntry, true );
2102 // #i37227 Clear always and replace array
2103 if( pNewArray != pOldArray )
2105 pItem->clearWatchItem();
2106 if( pNewArray )
2108 implEnableChildren( pEntry, true );
2110 pItem->mpArray = pNewArray;
2111 sal_uInt16 nDims = pNewArray->GetDims();
2112 pItem->nDimLevel = 0;
2113 pItem->nDimCount = nDims;
2116 if( bArrayChanged && pOldArray != NULL )
2118 bCollapse = true;
2120 aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
2122 else
2124 aWatchStr += "<?>";
2127 else if ( (sal_uInt8)eType == (sal_uInt8)SbxOBJECT )
2129 if (SbxObject* pObj = dynamic_cast<SbxObject*>(pVar->GetObject()))
2131 // Check if member list has changed
2132 bool bObjChanged = false;
2133 if (pItem->mpObject && !pItem->maMemberList.empty())
2135 SbxArray* pProps = pObj->GetProperties();
2136 sal_uInt16 nPropCount = pProps->Count();
2137 for( sal_uInt16 i = 0 ; i < nPropCount - 3 ; i++ )
2139 SbxVariable* pVar_ = pProps->Get( i );
2140 String aName( pVar_->GetName() );
2141 if( pItem->maMemberList[i] != aName )
2143 bObjChanged = true;
2144 break;
2147 if( bObjChanged )
2149 bCollapse = true;
2153 pItem->mpObject = pObj;
2154 implEnableChildren( pEntry, true );
2155 aTypeStr = getBasicObjectTypeName( pObj );
2157 else
2159 aWatchStr = OUString( "Null" );
2160 if( pItem->mpObject != NULL )
2162 bCollapse = true;
2163 pItem->clearWatchItem();
2165 implEnableChildren( pEntry, false );
2169 else
2171 if( pItem->mpObject != NULL )
2173 bCollapse = true;
2174 pItem->clearWatchItem();
2176 implEnableChildren( pEntry, false );
2179 bool bString = ((sal_uInt8)eType == (sal_uInt8)SbxSTRING);
2180 OUString aStrStr( "\"" );
2181 if( bString )
2183 aWatchStr += aStrStr;
2185 aWatchStr += pVar->GetOUString();
2186 if( bString )
2188 aWatchStr += aStrStr;
2191 if( !aTypeStr.Len() )
2193 if( !pVar->IsFixed() )
2195 aTypeStr = OUString( "Variant/" );
2197 aTypeStr += getBasicTypeName( pVar->GetType() );
2200 else if( !bArrayElement )
2202 aWatchStr += "<Out of Scope>";
2205 if( bCollapse )
2207 implCollapseModifiedObjectEntry( pEntry, this );
2211 else if( bBasicStopped )
2213 if( pItem->mpObject || pItem->mpArray )
2215 implCollapseModifiedObjectEntry( pEntry, this );
2216 pItem->mpObject = NULL;
2220 SvHeaderTabListBox::SetEntryText( aWatchStr, pEntry, ITEM_ID_VALUE-1 );
2221 SvHeaderTabListBox::SetEntryText( aTypeStr, pEntry, ITEM_ID_TYPE-1 );
2223 pEntry = Next( pEntry );
2226 // Force redraw
2227 Invalidate();
2229 SbxBase::ResetError();
2230 if( eOld != SbxERR_OK )
2231 SbxBase::SetError( eOld );
2232 setBasicWatchMode( false );
2236 } // namespace basctl
2238 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */