Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "helpid.hrc"
21 : #include "baside2.hrc"
22 :
23 : #include "baside2.hxx"
24 : #include "brkdlg.hxx"
25 : #include "iderdll.hxx"
26 : #include "iderdll2.hxx"
27 : #include "objdlg.hxx"
28 :
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 <svtools/syntaxhighlight.hxx>
45 : #include "svtools/treelistentry.hxx"
46 : #include <vcl/taskpanelist.hxx>
47 : #include <vcl/help.hxx>
48 :
49 : #include <vector>
50 :
51 : namespace basctl
52 : {
53 :
54 : using namespace ::com::sun::star;
55 : using namespace ::com::sun::star::uno;
56 :
57 : namespace
58 : {
59 :
60 : sal_uInt16 const NoMarker = 0xFFFF;
61 :
62 : long nVirtToolBoxHeight; // inited in WatchWindow, used in Stackwindow
63 : long nHeaderBarHeight;
64 :
65 : // Returns pBase converted to SbxVariable if valid and is not an SbxMethod.
66 0 : SbxVariable* IsSbxVariable (SbxBase* pBase)
67 : {
68 0 : if (SbxVariable* pVar = dynamic_cast<SbxVariable*>(pBase))
69 0 : if (!dynamic_cast<SbxMethod*>(pVar))
70 0 : return pVar;
71 0 : return 0;
72 : }
73 :
74 0 : Image GetImage (unsigned nId)
75 : {
76 0 : static ImageList const aImagesNormal(IDEResId(RID_IMGLST_LAYOUT));
77 0 : return aImagesNormal.GetImage(nId);
78 : }
79 :
80 : int const nScrollLine = 12;
81 : int const nScrollPage = 60;
82 : int const DWBORDER = 3;
83 :
84 : char const cSuffixes[] = "%&!#@$";
85 :
86 : } // namespace
87 :
88 :
89 : /**
90 : * Helper functions to get/set text in TextEngine using
91 : * the stream interface.
92 : *
93 : * get/setText() only supports tools Strings limited to 64K).
94 : */
95 0 : OUString getTextEngineText (ExtTextEngine& rEngine)
96 : {
97 0 : SvMemoryStream aMemStream;
98 0 : aMemStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
99 0 : aMemStream.SetLineDelimiter( LINEEND_LF );
100 0 : rEngine.Write( aMemStream );
101 0 : sal_uLong nSize = aMemStream.Tell();
102 0 : OUString aText( (const sal_Char*)aMemStream.GetData(),
103 0 : nSize, RTL_TEXTENCODING_UTF8 );
104 0 : return aText;
105 : }
106 :
107 0 : void setTextEngineText (ExtTextEngine& rEngine, OUString const& aStr)
108 : {
109 0 : rEngine.SetText(String());
110 0 : OString aUTF8Str = OUStringToOString( aStr, RTL_TEXTENCODING_UTF8 );
111 0 : SvMemoryStream aMemStream( (void*)aUTF8Str.getStr(), aUTF8Str.getLength(),
112 0 : STREAM_READ | STREAM_SEEK_TO_BEGIN );
113 0 : aMemStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
114 0 : aMemStream.SetLineDelimiter( LINEEND_LF );
115 0 : rEngine.Read(aMemStream);
116 0 : }
117 :
118 : namespace
119 : {
120 :
121 0 : void lcl_DrawIDEWindowFrame( DockingWindow* pWin )
122 : {
123 0 : if ( pWin->IsFloatingMode() )
124 0 : return;
125 :
126 0 : Size aSz = pWin->GetOutputSizePixel();
127 0 : const Color aOldLineColor( pWin->GetLineColor() );
128 0 : pWin->SetLineColor( Color( COL_WHITE ) );
129 : // White line on top
130 0 : pWin->DrawLine( Point( 0, 0 ), Point( aSz.Width(), 0 ) );
131 : // Black line at bottom
132 0 : pWin->SetLineColor( Color( COL_BLACK ) );
133 0 : pWin->DrawLine( Point( 0, aSz.Height() - 1 ),
134 0 : Point( aSz.Width(), aSz.Height() - 1 ) );
135 0 : pWin->SetLineColor( aOldLineColor );
136 : }
137 :
138 0 : void lcl_SeparateNameAndIndex( const String& rVName, String& rVar, String& rIndex )
139 : {
140 0 : rVar = rVName;
141 0 : rIndex.Erase();
142 0 : sal_uInt16 nIndexStart = rVar.Search( '(' );
143 0 : if ( nIndexStart != STRING_NOTFOUND )
144 : {
145 0 : sal_uInt16 nIndexEnd = rVar.Search( ')', nIndexStart );
146 0 : if ( nIndexStart != STRING_NOTFOUND )
147 : {
148 0 : rIndex = rVar.Copy( nIndexStart+1, nIndexEnd-nIndexStart-1 );
149 0 : rVar.Erase( nIndexStart );
150 0 : rVar = comphelper::string::stripEnd(rVar, ' ');
151 0 : rIndex = comphelper::string::strip(rIndex, ' ');
152 : }
153 : }
154 :
155 0 : if ( rVar.Len() )
156 : {
157 0 : sal_uInt16 nLastChar = rVar.Len()-1;
158 0 : if ( strchr( cSuffixes, rVar.GetChar( nLastChar ) ) )
159 0 : rVar.Erase( nLastChar, 1 );
160 : }
161 0 : if ( rIndex.Len() )
162 : {
163 0 : sal_uInt16 nLastChar = rIndex.Len()-1;
164 0 : if ( strchr( cSuffixes, rIndex.GetChar( nLastChar ) ) )
165 0 : rIndex.Erase( nLastChar, 1 );
166 : }
167 0 : }
168 :
169 : } // namespace
170 :
171 :
172 : //
173 : // EditorWindow
174 : // ============
175 : //
176 :
177 : class EditorWindow::ChangesListener:
178 : public cppu::WeakImplHelper1< beans::XPropertiesChangeListener >
179 : {
180 : public:
181 0 : ChangesListener(EditorWindow & editor): editor_(editor) {}
182 :
183 : private:
184 0 : virtual ~ChangesListener() {}
185 :
186 0 : virtual void SAL_CALL disposing(lang::EventObject const &) throw (RuntimeException)
187 : {
188 0 : osl::MutexGuard g(editor_.mutex_);
189 0 : editor_.notifier_.clear();
190 0 : }
191 :
192 0 : virtual void SAL_CALL propertiesChange(
193 : Sequence< beans::PropertyChangeEvent > const &) throw (RuntimeException)
194 : {
195 0 : SolarMutexGuard g;
196 0 : editor_.ImplSetFont();
197 0 : }
198 :
199 : EditorWindow & editor_;
200 : };
201 :
202 0 : class EditorWindow::ProgressInfo : public SfxProgress
203 : {
204 : public:
205 0 : ProgressInfo (SfxObjectShell* pObjSh, String const& rText, sal_uLong nRange) :
206 : SfxProgress(pObjSh, rText, nRange),
207 0 : nCurState(0)
208 0 : { }
209 :
210 0 : void StepProgress ()
211 : {
212 0 : SetState(++nCurState);
213 0 : }
214 :
215 : private:
216 : sal_uLong nCurState;
217 : };
218 :
219 0 : EditorWindow::EditorWindow (Window* pParent, ModulWindow* pModulWindow) :
220 : Window(pParent, WB_BORDER),
221 : pEditView(0),
222 : pEditEngine(0),
223 : rModulWindow(*pModulWindow),
224 : nCurTextWidth(0),
225 : bHighlightning(false),
226 : bDoSyntaxHighlight(true),
227 0 : bDelayHighlight(true)
228 : {
229 0 : SetBackground(Wallpaper(GetSettings().GetStyleSettings().GetFieldColor()));
230 0 : SetPointer( Pointer( POINTER_TEXT ) );
231 0 : SetHelpId( HID_BASICIDE_EDITORWINDOW );
232 :
233 0 : listener_ = new ChangesListener(*this);
234 : Reference< beans::XMultiPropertySet > n(
235 : officecfg::Office::Common::Font::SourceViewFont::get(),
236 0 : UNO_QUERY_THROW);
237 : {
238 0 : osl::MutexGuard g(mutex_);
239 0 : notifier_ = n;
240 : }
241 0 : Sequence< OUString > s(2);
242 0 : s[0] = OUString( "FontHeight" );
243 0 : s[1] = OUString( "FontName" );
244 0 : n->addPropertiesChangeListener(s, listener_.get());
245 0 : }
246 :
247 :
248 0 : EditorWindow::~EditorWindow()
249 : {
250 0 : Reference< beans::XMultiPropertySet > n;
251 : {
252 0 : osl::MutexGuard g(mutex_);
253 0 : n = notifier_;
254 : }
255 0 : if (n.is()) {
256 0 : n->removePropertiesChangeListener(listener_.get());
257 : }
258 :
259 0 : aSyntaxIdleTimer.Stop();
260 :
261 0 : if ( pEditEngine )
262 : {
263 0 : EndListening( *pEditEngine );
264 0 : pEditEngine->RemoveView(pEditView.get());
265 0 : }
266 0 : }
267 :
268 0 : String EditorWindow::GetWordAtCursor()
269 : {
270 0 : String aWord;
271 :
272 0 : if ( pEditView )
273 : {
274 0 : TextEngine* pTextEngine = pEditView->GetTextEngine();
275 0 : if ( pTextEngine )
276 : {
277 : // check first, if the cursor is at a help URL
278 0 : const TextSelection& rSelection = pEditView->GetSelection();
279 0 : const TextPaM& rSelStart = rSelection.GetStart();
280 0 : const TextPaM& rSelEnd = rSelection.GetEnd();
281 0 : OUString aText = pTextEngine->GetText( rSelEnd.GetPara() );
282 0 : CharClass aClass( ::comphelper::getProcessComponentContext() , Application::GetSettings().GetLanguageTag() );
283 0 : sal_Int32 nSelStart = rSelStart.GetIndex();
284 0 : sal_Int32 nSelEnd = rSelEnd.GetIndex();
285 0 : sal_Int32 nLength = aText.getLength();
286 0 : sal_Int32 nStart = 0;
287 0 : sal_Int32 nEnd = nLength;
288 0 : while ( nStart < nLength )
289 : {
290 0 : OUString aURL( URIHelper::FindFirstURLInText( aText, nStart, nEnd, aClass ) );
291 0 : INetURLObject aURLObj( aURL );
292 0 : if ( aURLObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP
293 : && nSelStart >= nStart && nSelStart <= nEnd && nSelEnd >= nStart && nSelEnd <= nEnd )
294 : {
295 0 : aWord = aURL;
296 : break;
297 : }
298 0 : nStart = nEnd;
299 0 : nEnd = nLength;
300 0 : }
301 :
302 : // Not the selected range, but at the CursorPosition,
303 : // if a word is partially selected.
304 0 : if ( !aWord.Len() )
305 0 : aWord = pTextEngine->GetWord( rSelEnd );
306 :
307 : // Can be empty when full word selected, as Cursor behing it
308 0 : if ( !aWord.Len() && pEditView->HasSelection() )
309 0 : aWord = pTextEngine->GetWord( rSelStart );
310 : }
311 : }
312 :
313 0 : return aWord;
314 : }
315 :
316 0 : void EditorWindow::RequestHelp( const HelpEvent& rHEvt )
317 : {
318 0 : bool bDone = false;
319 :
320 : // Should have been activated at some point
321 0 : if ( pEditEngine )
322 : {
323 0 : if ( rHEvt.GetMode() & HELPMODE_CONTEXT )
324 : {
325 0 : String aKeyword = GetWordAtCursor();
326 0 : Application::GetHelp()->SearchKeyword( aKeyword );
327 0 : bDone = true;
328 : }
329 0 : else if ( rHEvt.GetMode() & HELPMODE_QUICK )
330 : {
331 0 : String aHelpText;
332 0 : Point aTopLeft;
333 0 : if ( StarBASIC::IsRunning() )
334 : {
335 0 : Point aWindowPos = rHEvt.GetMousePosPixel();
336 0 : aWindowPos = ScreenToOutputPixel( aWindowPos );
337 0 : Point aDocPos = GetEditView()->GetDocPos( aWindowPos );
338 0 : TextPaM aCursor = GetEditView()->GetTextEngine()->GetPaM(aDocPos, false);
339 0 : TextPaM aStartOfWord;
340 0 : String aWord = GetEditView()->GetTextEngine()->GetWord( aCursor, &aStartOfWord );
341 0 : if ( aWord.Len() && !comphelper::string::isdigitAsciiString(aWord) )
342 : {
343 0 : sal_uInt16 nLastChar =aWord.Len()-1;
344 0 : if ( strchr( cSuffixes, aWord.GetChar( nLastChar ) ) )
345 0 : aWord.Erase( nLastChar, 1 );
346 0 : SbxBase* pSBX = StarBASIC::FindSBXInCurrentScope( aWord );
347 0 : if (SbxVariable const* pVar = IsSbxVariable(pSBX))
348 : {
349 0 : SbxDataType eType = pVar->GetType();
350 0 : if ( (sal_uInt8)eType == (sal_uInt8)SbxOBJECT )
351 : // might cause a crash e. g. at the selections-object
352 : // Type == Object does not mean pVar == Object!
353 : ; // aHelpText = ((SbxObject*)pVar)->GetClassName();
354 0 : else if ( eType & SbxARRAY )
355 : ; // aHelpText = "{...}";
356 0 : else if ( (sal_uInt8)eType != (sal_uInt8)SbxEMPTY )
357 : {
358 0 : aHelpText = pVar->GetName();
359 0 : if ( !aHelpText.Len() ) // name is not copied with the passed parameters
360 0 : aHelpText = aWord;
361 0 : aHelpText += '=';
362 0 : aHelpText += pVar->GetOUString();
363 : }
364 : }
365 0 : if ( aHelpText.Len() )
366 : {
367 0 : aTopLeft = GetEditView()->GetTextEngine()->PaMtoEditCursor( aStartOfWord ).BottomLeft();
368 0 : aTopLeft = GetEditView()->GetWindowPos( aTopLeft );
369 0 : aTopLeft.X() += 5;
370 0 : aTopLeft.Y() += 5;
371 0 : aTopLeft = OutputToScreenPixel( aTopLeft );
372 : }
373 0 : }
374 : }
375 0 : Help::ShowQuickHelp( this, Rectangle( aTopLeft, Size( 1, 1 ) ), aHelpText, QUICKHELP_TOP|QUICKHELP_LEFT);
376 0 : bDone = true;
377 : }
378 : }
379 :
380 0 : if ( !bDone )
381 0 : Window::RequestHelp( rHEvt );
382 0 : }
383 :
384 :
385 0 : void EditorWindow::Resize()
386 : {
387 : // ScrollBars, etc. happens in Adjust...
388 0 : if ( pEditView )
389 : {
390 0 : long nVisY = pEditView->GetStartDocPos().Y();
391 :
392 0 : pEditView->ShowCursor();
393 0 : Size aOutSz( GetOutputSizePixel() );
394 0 : long nMaxVisAreaStart = pEditView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
395 0 : if ( nMaxVisAreaStart < 0 )
396 0 : nMaxVisAreaStart = 0;
397 0 : if ( pEditView->GetStartDocPos().Y() > nMaxVisAreaStart )
398 : {
399 0 : Point aStartDocPos( pEditView->GetStartDocPos() );
400 0 : aStartDocPos.Y() = nMaxVisAreaStart;
401 0 : pEditView->SetStartDocPos( aStartDocPos );
402 0 : pEditView->ShowCursor();
403 0 : rModulWindow.GetBreakPointWindow().GetCurYOffset() = aStartDocPos.Y();
404 0 : rModulWindow.GetLineNumberWindow().GetCurYOffset() = aStartDocPos.Y();
405 : }
406 0 : InitScrollBars();
407 0 : if ( nVisY != pEditView->GetStartDocPos().Y() )
408 0 : Invalidate();
409 : }
410 0 : }
411 :
412 :
413 0 : void EditorWindow::MouseMove( const MouseEvent &rEvt )
414 : {
415 0 : if ( pEditView )
416 0 : pEditView->MouseMove( rEvt );
417 0 : }
418 :
419 :
420 0 : void EditorWindow::MouseButtonUp( const MouseEvent &rEvt )
421 : {
422 0 : if ( pEditView )
423 : {
424 0 : pEditView->MouseButtonUp( rEvt );
425 0 : if (SfxBindings* pBindings = GetBindingsPtr())
426 0 : pBindings->Invalidate( SID_BASICIDE_STAT_POS );
427 : }
428 0 : }
429 :
430 0 : void EditorWindow::MouseButtonDown( const MouseEvent &rEvt )
431 : {
432 0 : GrabFocus();
433 0 : if ( pEditView )
434 0 : pEditView->MouseButtonDown( rEvt );
435 0 : }
436 :
437 0 : void EditorWindow::Command( const CommandEvent& rCEvt )
438 : {
439 0 : if ( pEditView )
440 : {
441 0 : pEditView->Command( rCEvt );
442 0 : if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
443 0 : ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
444 0 : ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
445 : {
446 0 : HandleScrollCommand( rCEvt, rModulWindow.GetHScrollBar(), &rModulWindow.GetEditVScrollBar() );
447 : }
448 : }
449 0 : }
450 :
451 0 : bool EditorWindow::ImpCanModify()
452 : {
453 0 : bool bCanModify = true;
454 0 : if ( StarBASIC::IsRunning() )
455 : {
456 : // If in Trace-mode, abort the trace or refuse input
457 : // Remove markers in the modules in Notify at Basic::Stoped
458 0 : if ( QueryBox( 0, WB_OK_CANCEL, String( IDEResId( RID_STR_WILLSTOPPRG ) ) ).Execute() == RET_OK )
459 : {
460 0 : rModulWindow.GetBasicStatus().bIsRunning = false;
461 0 : StopBasic();
462 : }
463 : else
464 0 : bCanModify = false;
465 : }
466 0 : return bCanModify;
467 : }
468 :
469 0 : void EditorWindow::KeyInput( const KeyEvent& rKEvt )
470 : {
471 0 : if ( !pEditView ) // Happens in Win95
472 0 : return;
473 :
474 : #if OSL_DEBUG_LEVEL > 1
475 : Range aRange = rModulWindow.GetHScrollBar()->GetRange(); (void)aRange;
476 : long nVisSz = rModulWindow.GetHScrollBar()->GetVisibleSize(); (void)nVisSz;
477 : long nPapSz = rModulWindow.GetHScrollBar()->GetPageSize(); (void)nPapSz;
478 : long nLinSz = rModulWindow.GetHScrollBar()->GetLineSize(); (void)nLinSz;
479 : long nThumb = rModulWindow.GetHScrollBar()->GetThumbPos(); (void)nThumb;
480 : #endif
481 0 : bool const bWasModified = pEditEngine->IsModified();
482 : // see if there is an accelerator to be processed first
483 0 : bool bDone = SfxViewShell::Current()->KeyInput( rKEvt );
484 :
485 0 : if ( !bDone && ( !TextEngine::DoesKeyChangeText( rKEvt ) || ImpCanModify() ) )
486 : {
487 0 : if ( ( rKEvt.GetKeyCode().GetCode() == KEY_TAB ) && !rKEvt.GetKeyCode().IsMod1() &&
488 0 : !rKEvt.GetKeyCode().IsMod2() && !GetEditView()->IsReadOnly() )
489 : {
490 0 : TextSelection aSel( pEditView->GetSelection() );
491 0 : if ( aSel.GetStart().GetPara() != aSel.GetEnd().GetPara() )
492 : {
493 0 : bDelayHighlight = false;
494 0 : if ( !rKEvt.GetKeyCode().IsShift() )
495 0 : pEditView->IndentBlock();
496 : else
497 0 : pEditView->UnindentBlock();
498 0 : bDelayHighlight = true;
499 0 : bDone = true;
500 : }
501 : }
502 0 : if ( !bDone )
503 0 : bDone = pEditView->KeyInput( rKEvt );
504 : }
505 0 : if ( !bDone )
506 : {
507 0 : Window::KeyInput( rKEvt );
508 : }
509 : else
510 : {
511 0 : if (SfxBindings* pBindings = GetBindingsPtr())
512 : {
513 0 : pBindings->Invalidate( SID_BASICIDE_STAT_POS );
514 0 : if ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_CURSOR )
515 0 : pBindings->Update( SID_BASICIDE_STAT_POS );
516 0 : if ( !bWasModified && pEditEngine->IsModified() )
517 : {
518 0 : pBindings->Invalidate( SID_SAVEDOC );
519 0 : pBindings->Invalidate( SID_DOC_MODIFIED );
520 0 : pBindings->Invalidate( SID_UNDO );
521 : }
522 0 : if ( rKEvt.GetKeyCode().GetCode() == KEY_INSERT )
523 0 : pBindings->Invalidate( SID_ATTR_INSERT );
524 : }
525 : }
526 : }
527 :
528 0 : void EditorWindow::Paint( const Rectangle& rRect )
529 : {
530 0 : if ( !pEditEngine ) // We need it now at latest
531 0 : CreateEditEngine();
532 :
533 0 : pEditView->Paint( rRect );
534 0 : }
535 :
536 0 : void EditorWindow::LoseFocus()
537 : {
538 0 : SetSourceInBasic();
539 0 : Window::LoseFocus();
540 0 : }
541 :
542 0 : bool EditorWindow::SetSourceInBasic()
543 : {
544 0 : bool bChanged = false;
545 0 : if ( pEditEngine && pEditEngine->IsModified()
546 0 : && !GetEditView()->IsReadOnly() ) // Added for #i60626, otherwise
547 : // any read only bug in the text engine could lead to a crash later
548 : {
549 0 : if ( !StarBASIC::IsRunning() ) // Not at runtime!
550 : {
551 0 : rModulWindow.UpdateModule();
552 0 : bChanged = true;
553 : }
554 : }
555 0 : return bChanged;
556 : }
557 :
558 : // Returns the position of the last character of any of the following
559 : // EOL char combinations: CR, CR/LF, LF, return -1 if no EOL is found
560 0 : sal_Int32 searchEOL( const OUString& rStr, sal_Int32 fromIndex )
561 : {
562 0 : sal_Int32 iRetPos = -1;
563 :
564 0 : sal_Int32 iLF = rStr.indexOf( LINE_SEP, fromIndex );
565 0 : if( iLF != -1 )
566 : {
567 0 : iRetPos = iLF;
568 : }
569 : else
570 : {
571 0 : iRetPos = rStr.indexOf( LINE_SEP_CR, fromIndex );
572 : }
573 0 : return iRetPos;
574 : }
575 :
576 0 : void EditorWindow::CreateEditEngine()
577 : {
578 0 : if ( pEditEngine )
579 0 : return;
580 :
581 0 : pEditEngine.reset(new ExtTextEngine);
582 0 : pEditView.reset(new ExtTextView(pEditEngine.get(), this));
583 0 : pEditView->SetAutoIndentMode(true);
584 0 : pEditEngine->SetUpdateMode(false);
585 0 : pEditEngine->InsertView(pEditView.get());
586 :
587 0 : ImplSetFont();
588 :
589 0 : aSyntaxIdleTimer.SetTimeout( 200 );
590 0 : aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, EditorWindow, SyntaxTimerHdl ) );
591 :
592 0 : aHighlighter.initialize( HIGHLIGHT_BASIC );
593 :
594 0 : bool bWasDoSyntaxHighlight = bDoSyntaxHighlight;
595 0 : bDoSyntaxHighlight = false; // too slow for large texts...
596 0 : OUString aOUSource(rModulWindow.GetModule());
597 0 : sal_Int32 nLines = 0;
598 0 : sal_Int32 nIndex = -1;
599 0 : do
600 : {
601 0 : nLines++;
602 0 : nIndex = searchEOL( aOUSource, nIndex+1 );
603 : }
604 : while ( nIndex >= 0 );
605 :
606 : // nLines*4: SetText+Formatting+DoHighlight+Formatting
607 : // it could be cut down on one formatting but you would wait even longer
608 : // for the text then if the source code is long...
609 : pProgress.reset(new ProgressInfo(
610 0 : GetShell()->GetViewFrame()->GetObjectShell(),
611 : String(IDEResId(RID_STR_GENERATESOURCE)),
612 : nLines*4
613 0 : ));
614 0 : setTextEngineText(*pEditEngine, aOUSource);
615 :
616 0 : pEditView->SetStartDocPos( Point( 0, 0 ) );
617 0 : pEditView->SetSelection( TextSelection() );
618 0 : rModulWindow.GetBreakPointWindow().GetCurYOffset() = 0;
619 0 : rModulWindow.GetLineNumberWindow().GetCurYOffset() = 0;
620 0 : pEditEngine->SetUpdateMode(true);
621 0 : rModulWindow.Update(); // has only been invalidated at UpdateMode = true
622 :
623 0 : pEditView->ShowCursor( true, true );
624 :
625 0 : StartListening( *pEditEngine );
626 :
627 0 : aSyntaxIdleTimer.Stop();
628 0 : bDoSyntaxHighlight = bWasDoSyntaxHighlight;
629 :
630 :
631 0 : for ( sal_uInt16 nLine = 0; nLine < nLines; nLine++ )
632 0 : aSyntaxLineTable.insert( nLine );
633 0 : ForceSyntaxTimeout();
634 :
635 0 : pProgress.reset();
636 :
637 0 : pEditView->EraseVirtualDevice();
638 0 : pEditEngine->SetModified( false );
639 0 : pEditEngine->EnableUndo( true );
640 :
641 0 : InitScrollBars();
642 :
643 0 : if (SfxBindings* pBindings = GetBindingsPtr())
644 0 : pBindings->Invalidate( SID_BASICIDE_STAT_POS );
645 :
646 : DBG_ASSERT( rModulWindow.GetBreakPointWindow().GetCurYOffset() == 0, "CreateEditEngine: Brechpunkte verschoben?" );
647 :
648 : // set readonly mode for readonly libraries
649 0 : ScriptDocument aDocument(rModulWindow.GetDocument());
650 0 : OUString aOULibName(rModulWindow.GetLibName());
651 0 : Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
652 0 : if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && xModLibContainer->isLibraryReadOnly( aOULibName ) )
653 : {
654 0 : rModulWindow.SetReadOnly(true);
655 : }
656 :
657 0 : if ( aDocument.isDocument() && aDocument.isReadOnly() )
658 0 : rModulWindow.SetReadOnly(true);
659 : }
660 :
661 : // virtual
662 0 : void EditorWindow::DataChanged(DataChangedEvent const & rDCEvt)
663 : {
664 0 : Window::DataChanged(rDCEvt);
665 0 : if (rDCEvt.GetType() == DATACHANGED_SETTINGS
666 0 : && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
667 : {
668 0 : Color aColor(GetSettings().GetStyleSettings().GetFieldColor());
669 0 : if (aColor
670 0 : != rDCEvt.GetOldSettings()->GetStyleSettings().GetFieldColor())
671 : {
672 0 : SetBackground(Wallpaper(aColor));
673 0 : Invalidate();
674 : }
675 0 : if (pEditEngine != 0)
676 : {
677 0 : aColor = GetSettings().GetStyleSettings().GetFieldTextColor();
678 0 : if (aColor != rDCEvt.GetOldSettings()->
679 0 : GetStyleSettings().GetFieldTextColor())
680 : {
681 0 : Font aFont(pEditEngine->GetFont());
682 0 : aFont.SetColor(aColor);
683 0 : pEditEngine->SetFont(aFont);
684 : }
685 : }
686 : }
687 0 : }
688 :
689 0 : void EditorWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
690 : {
691 0 : if (TextHint const* pTextHint = dynamic_cast<TextHint const*>(&rHint))
692 : {
693 0 : TextHint const& rTextHint = *pTextHint;
694 0 : if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
695 : {
696 0 : if ( rModulWindow.GetHScrollBar() )
697 0 : rModulWindow.GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
698 0 : rModulWindow.GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
699 0 : rModulWindow.GetBreakPointWindow().DoScroll
700 0 : ( 0, rModulWindow.GetBreakPointWindow().GetCurYOffset() - pEditView->GetStartDocPos().Y() );
701 0 : rModulWindow.GetLineNumberWindow().DoScroll
702 0 : ( 0, rModulWindow.GetLineNumberWindow().GetCurYOffset() - pEditView->GetStartDocPos().Y() );
703 : }
704 0 : else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
705 : {
706 0 : if ( pEditView->GetStartDocPos().Y() )
707 : {
708 0 : long nOutHeight = GetOutputSizePixel().Height();
709 0 : long nTextHeight = pEditEngine->GetTextHeight();
710 0 : if ( nTextHeight < nOutHeight )
711 0 : pEditView->Scroll( 0, pEditView->GetStartDocPos().Y() );
712 :
713 0 : rModulWindow.GetLineNumberWindow().Invalidate();
714 : }
715 :
716 0 : SetScrollBarRanges();
717 : }
718 0 : else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
719 : {
720 0 : if ( rModulWindow.GetHScrollBar() )
721 : {
722 0 : sal_uLong nWidth = pEditEngine->CalcTextWidth();
723 0 : if ( (long)nWidth != nCurTextWidth )
724 : {
725 0 : nCurTextWidth = nWidth;
726 0 : rModulWindow.GetHScrollBar()->SetRange( Range( 0, (long)nCurTextWidth-1) );
727 0 : rModulWindow.GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
728 : }
729 : }
730 0 : long nPrevTextWidth = nCurTextWidth;
731 0 : nCurTextWidth = pEditEngine->CalcTextWidth();
732 0 : if ( nCurTextWidth != nPrevTextWidth )
733 0 : SetScrollBarRanges();
734 : }
735 0 : else if( rTextHint.GetId() == TEXT_HINT_PARAINSERTED )
736 : {
737 0 : ParagraphInsertedDeleted( rTextHint.GetValue(), true );
738 0 : DoDelayedSyntaxHighlight( rTextHint.GetValue() );
739 : }
740 0 : else if( rTextHint.GetId() == TEXT_HINT_PARAREMOVED )
741 : {
742 0 : ParagraphInsertedDeleted( rTextHint.GetValue(), false );
743 : }
744 0 : else if( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED )
745 : {
746 0 : DoDelayedSyntaxHighlight( rTextHint.GetValue() );
747 : }
748 : }
749 0 : }
750 :
751 0 : void EditorWindow::SetScrollBarRanges()
752 : {
753 : // extra method, not InitScrollBars, because for EditEngine events too
754 0 : if ( !pEditEngine )
755 0 : return;
756 :
757 0 : if ( rModulWindow.GetHScrollBar() )
758 0 : rModulWindow.GetHScrollBar()->SetRange( Range( 0, nCurTextWidth-1 ) );
759 :
760 0 : rModulWindow.GetEditVScrollBar().SetRange( Range( 0, pEditEngine->GetTextHeight()-1 ) );
761 : }
762 :
763 0 : void EditorWindow::InitScrollBars()
764 : {
765 0 : if ( !pEditEngine )
766 0 : return;
767 :
768 0 : SetScrollBarRanges();
769 0 : Size aOutSz( GetOutputSizePixel() );
770 0 : rModulWindow.GetEditVScrollBar().SetVisibleSize( aOutSz.Height() );
771 0 : rModulWindow.GetEditVScrollBar().SetPageSize( aOutSz.Height() * 8 / 10 );
772 0 : rModulWindow.GetEditVScrollBar().SetLineSize( GetTextHeight() );
773 0 : rModulWindow.GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
774 0 : rModulWindow.GetEditVScrollBar().Show();
775 :
776 0 : if ( rModulWindow.GetHScrollBar() )
777 : {
778 0 : rModulWindow.GetHScrollBar()->SetVisibleSize( aOutSz.Width() );
779 0 : rModulWindow.GetHScrollBar()->SetPageSize( aOutSz.Width() * 8 / 10 );
780 0 : rModulWindow.GetHScrollBar()->SetLineSize( GetTextWidth( OUString('x') ) );
781 0 : rModulWindow.GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
782 0 : rModulWindow.GetHScrollBar()->Show();
783 : }
784 : }
785 :
786 0 : void EditorWindow::ImpDoHighlight( sal_uLong nLine )
787 : {
788 0 : if ( bDoSyntaxHighlight )
789 : {
790 0 : String aLine( pEditEngine->GetText( nLine ) );
791 0 : Range aChanges = aHighlighter.notifyChange( nLine, 0, &aLine, 1 );
792 0 : if ( aChanges.Len() )
793 : {
794 0 : for ( long n = aChanges.Min() + 1; n <= aChanges.Max(); n++ )
795 0 : aSyntaxLineTable.insert( n );
796 0 : aSyntaxIdleTimer.Start();
797 : }
798 :
799 0 : bool const bWasModified = pEditEngine->IsModified();
800 0 : pEditEngine->RemoveAttribs( nLine, true );
801 0 : HighlightPortions aPortions;
802 0 : aHighlighter.getHighlightPortions( nLine, aLine, aPortions );
803 :
804 0 : for ( size_t i = 0; i < aPortions.size(); i++ )
805 : {
806 0 : HighlightPortion& r = aPortions[i];
807 0 : Color const aColor = rModulWindow.GetLayout().GetSyntaxColor(r.tokenType);
808 0 : pEditEngine->SetAttrib( TextAttribFontColor(aColor), nLine, r.nBegin, r.nEnd, true );
809 : }
810 :
811 0 : pEditEngine->SetModified( bWasModified );
812 : }
813 0 : }
814 :
815 0 : void EditorWindow::UpdateSyntaxHighlighting ()
816 : {
817 0 : unsigned nCount = pEditEngine->GetParagraphCount();
818 0 : for (unsigned i = 0; i < nCount; ++i)
819 0 : DoDelayedSyntaxHighlight(i);
820 0 : }
821 :
822 0 : void EditorWindow::ImplSetFont()
823 : {
824 : OUString sFontName(
825 : officecfg::Office::Common::Font::SourceViewFont::FontName::get().
826 0 : get_value_or( OUString() ) );
827 0 : if ( sFontName.isEmpty() )
828 : {
829 0 : Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, Application::GetSettings().GetUILanguageTag().getLanguageType(), 0 , this ) );
830 0 : sFontName = aTmpFont.GetName();
831 : }
832 0 : Size aFontSize(0, officecfg::Office::Common::Font::SourceViewFont::FontHeight::get());
833 0 : Font aFont( sFontName, aFontSize );
834 0 : aFont.SetColor( GetSettings().GetStyleSettings().GetFieldTextColor() );
835 0 : SetPointFont( aFont );
836 0 : aFont = GetFont();
837 :
838 0 : rModulWindow.GetBreakPointWindow().SetFont( aFont );
839 0 : rModulWindow.GetLineNumberWindow().SetFont( aFont );
840 :
841 0 : if ( pEditEngine )
842 : {
843 0 : bool const bModified = pEditEngine->IsModified();
844 0 : pEditEngine->SetFont( aFont );
845 0 : pEditEngine->SetModified( bModified );
846 0 : }
847 0 : }
848 :
849 0 : void EditorWindow::DoSyntaxHighlight( sal_uLong nPara )
850 : {
851 : // because of the DelayedSyntaxHighlight it's possible
852 : // that this line does not exist anymore!
853 0 : if ( nPara < pEditEngine->GetParagraphCount() )
854 : {
855 : // unfortunately I'm not sure that excactly this line does Modified() ...
856 0 : if ( pProgress )
857 0 : pProgress->StepProgress();
858 0 : ImpDoHighlight( nPara );
859 : }
860 0 : }
861 :
862 0 : void EditorWindow::DoDelayedSyntaxHighlight( sal_uLong nPara )
863 : {
864 : // line is only added to 'Liste' (list), processed in TimerHdl
865 : // => don't manipulate breaks while EditEngine is formatting
866 0 : if ( pProgress )
867 0 : pProgress->StepProgress();
868 :
869 0 : if ( !bHighlightning && bDoSyntaxHighlight )
870 : {
871 0 : if ( bDelayHighlight )
872 : {
873 0 : aSyntaxLineTable.insert( nPara );
874 0 : aSyntaxIdleTimer.Start();
875 : }
876 : else
877 0 : DoSyntaxHighlight( nPara );
878 : }
879 0 : }
880 :
881 0 : IMPL_LINK_NOARG(EditorWindow, SyntaxTimerHdl)
882 : {
883 : DBG_ASSERT( pEditView, "Noch keine View, aber Syntax-Highlight ?!" );
884 :
885 0 : bool const bWasModified = pEditEngine->IsModified();
886 : //pEditEngine->SetUpdateMode(false);
887 :
888 0 : bHighlightning = true;
889 0 : for ( SyntaxLineSet::const_iterator it = aSyntaxLineTable.begin();
890 0 : it != aSyntaxLineTable.end(); ++it )
891 : {
892 0 : sal_uInt16 nLine = *it;
893 0 : DoSyntaxHighlight( nLine );
894 : }
895 :
896 : // #i45572#
897 0 : if ( pEditView )
898 0 : pEditView->ShowCursor( false, true );
899 :
900 0 : pEditEngine->SetModified( bWasModified );
901 :
902 0 : aSyntaxLineTable.clear();
903 0 : bHighlightning = false;
904 :
905 0 : return 0;
906 : }
907 :
908 0 : void EditorWindow::ParagraphInsertedDeleted( sal_uLong nPara, bool bInserted )
909 : {
910 0 : if ( pProgress )
911 0 : pProgress->StepProgress();
912 :
913 0 : if ( !bInserted && ( nPara == TEXT_PARA_ALL ) )
914 : {
915 0 : rModulWindow.GetBreakPoints().reset();
916 0 : rModulWindow.GetBreakPointWindow().Invalidate();
917 0 : rModulWindow.GetLineNumberWindow().Invalidate();
918 0 : aHighlighter.initialize( HIGHLIGHT_BASIC );
919 : }
920 : else
921 : {
922 0 : rModulWindow.GetBreakPoints().AdjustBreakPoints( (sal_uInt16)nPara+1, bInserted );
923 :
924 0 : long nLineHeight = GetTextHeight();
925 0 : Size aSz = rModulWindow.GetBreakPointWindow().GetOutputSize();
926 0 : Rectangle aInvRec( Point( 0, 0 ), aSz );
927 0 : long nY = nPara*nLineHeight - rModulWindow.GetBreakPointWindow().GetCurYOffset();
928 0 : aInvRec.Top() = nY;
929 0 : rModulWindow.GetBreakPointWindow().Invalidate( aInvRec );
930 :
931 0 : Size aLnSz(rModulWindow.GetLineNumberWindow().GetWidth(),
932 0 : GetOutputSizePixel().Height() - 2 * DWBORDER);
933 0 : rModulWindow.GetLineNumberWindow().SetPosSizePixel(Point(DWBORDER + 19, DWBORDER), aLnSz);
934 0 : rModulWindow.GetLineNumberWindow().Invalidate();
935 :
936 0 : if ( bDoSyntaxHighlight )
937 : {
938 0 : String aDummy;
939 0 : aHighlighter.notifyChange( nPara, bInserted ? 1 : (-1), &aDummy, 1 );
940 : }
941 : }
942 0 : }
943 :
944 0 : void EditorWindow::CreateProgress( const String& rText, sal_uLong nRange )
945 : {
946 : DBG_ASSERT( !pProgress, "ProgressInfo existiert schon" );
947 : pProgress.reset(new ProgressInfo(
948 0 : GetShell()->GetViewFrame()->GetObjectShell(),
949 : rText,
950 : nRange
951 0 : ));
952 0 : }
953 :
954 0 : void EditorWindow::DestroyProgress()
955 : {
956 0 : pProgress.reset();
957 0 : }
958 :
959 0 : void EditorWindow::ForceSyntaxTimeout()
960 : {
961 0 : aSyntaxIdleTimer.Stop();
962 0 : aSyntaxIdleTimer.GetTimeoutHdl().Call(&aSyntaxIdleTimer);
963 0 : }
964 :
965 :
966 : //
967 : // BreakPointWindow
968 : // ================
969 : //
970 :
971 0 : BreakPointWindow::BreakPointWindow (Window* pParent, ModulWindow* pModulWindow) :
972 : Window(pParent, WB_BORDER),
973 : rModulWindow(*pModulWindow),
974 : nCurYOffset(0), // memorize nCurYOffset and not take it from EditEngine
975 0 : nMarkerPos(NoMarker)
976 : {
977 0 : setBackgroundColor(GetSettings().GetStyleSettings().GetFieldColor());
978 0 : SetHelpId(HID_BASICIDE_BREAKPOINTWINDOW);
979 0 : }
980 :
981 0 : BreakPointWindow::~BreakPointWindow()
982 : {
983 0 : }
984 :
985 :
986 :
987 0 : void BreakPointWindow::Paint( const Rectangle& )
988 : {
989 0 : if ( SyncYOffset() )
990 0 : return;
991 :
992 0 : Size const aOutSz = GetOutputSize();
993 0 : long const nLineHeight = GetTextHeight();
994 :
995 0 : Image const aBrk[2] = { GetImage(IMGID_BRKDISABLED), GetImage(IMGID_BRKENABLED) };
996 0 : Size const aBmpSz = PixelToLogic(aBrk[1].GetSizePixel());
997 : Point const aBmpOff(
998 0 : (aOutSz.Width() - aBmpSz.Width()) / 2,
999 0 : (nLineHeight - aBmpSz.Height()) / 2
1000 0 : );
1001 :
1002 0 : for (size_t i = 0, n = GetBreakPoints().size(); i < n; ++i)
1003 : {
1004 0 : BreakPoint& rBrk = *GetBreakPoints().at(i);
1005 0 : size_t const nLine = rBrk.nLine - 1;
1006 0 : size_t const nY = nLine*nLineHeight - nCurYOffset;
1007 0 : DrawImage(Point(0, nY) + aBmpOff, aBrk[rBrk.bEnabled]);
1008 : }
1009 0 : ShowMarker(true);
1010 : }
1011 :
1012 :
1013 :
1014 0 : void BreakPointWindow::DoScroll( long nHorzScroll, long nVertScroll )
1015 : {
1016 0 : nCurYOffset -= nVertScroll;
1017 0 : Window::Scroll( nHorzScroll, nVertScroll );
1018 0 : }
1019 :
1020 :
1021 :
1022 0 : void BreakPointWindow::SetMarkerPos( sal_uInt16 nLine, bool bError )
1023 : {
1024 0 : if ( SyncYOffset() )
1025 0 : Update();
1026 :
1027 0 : ShowMarker( false );
1028 0 : nMarkerPos = nLine;
1029 0 : bErrorMarker = bError;
1030 0 : ShowMarker( true );
1031 0 : }
1032 :
1033 0 : void BreakPointWindow::SetNoMarker ()
1034 : {
1035 0 : SetMarkerPos(NoMarker);
1036 0 : }
1037 :
1038 0 : void BreakPointWindow::ShowMarker( bool bShow )
1039 : {
1040 0 : if ( nMarkerPos == NoMarker )
1041 0 : return;
1042 :
1043 0 : Size const aOutSz = GetOutputSize();
1044 0 : long const nLineHeight = GetTextHeight();
1045 :
1046 0 : Image aMarker = GetImage(bErrorMarker ? IMGID_ERRORMARKER : IMGID_STEPMARKER);
1047 :
1048 0 : Size aMarkerSz( aMarker.GetSizePixel() );
1049 0 : aMarkerSz = PixelToLogic( aMarkerSz );
1050 0 : Point aMarkerOff( 0, 0 );
1051 0 : aMarkerOff.X() = ( aOutSz.Width() - aMarkerSz.Width() ) / 2;
1052 0 : aMarkerOff.Y() = ( nLineHeight - aMarkerSz.Height() ) / 2;
1053 :
1054 0 : sal_uLong nY = nMarkerPos*nLineHeight - nCurYOffset;
1055 0 : Point aPos( 0, nY );
1056 0 : aPos += aMarkerOff;
1057 0 : if ( bShow )
1058 0 : DrawImage( aPos, aMarker );
1059 : else
1060 0 : Invalidate( Rectangle( aPos, aMarkerSz ) );
1061 : }
1062 :
1063 :
1064 :
1065 :
1066 0 : BreakPoint* BreakPointWindow::FindBreakPoint( const Point& rMousePos )
1067 : {
1068 0 : size_t nLineHeight = GetTextHeight();
1069 0 : size_t nYPos = rMousePos.Y() + nCurYOffset;
1070 :
1071 0 : for ( size_t i = 0, n = GetBreakPoints().size(); i < n ; ++i )
1072 : {
1073 0 : BreakPoint* pBrk = GetBreakPoints().at( i );
1074 0 : size_t nLine = pBrk->nLine-1;
1075 0 : size_t nY = nLine*nLineHeight;
1076 0 : if ( ( nYPos > nY ) && ( nYPos < ( nY + nLineHeight ) ) )
1077 0 : return pBrk;
1078 : }
1079 0 : return 0;
1080 : }
1081 :
1082 0 : void BreakPointWindow::MouseButtonDown( const MouseEvent& rMEvt )
1083 : {
1084 0 : if ( rMEvt.GetClicks() == 2 )
1085 : {
1086 0 : Point aMousePos( PixelToLogic( rMEvt.GetPosPixel() ) );
1087 0 : long nLineHeight = GetTextHeight();
1088 0 : long nYPos = aMousePos.Y() + nCurYOffset;
1089 0 : long nLine = nYPos / nLineHeight + 1;
1090 0 : rModulWindow.ToggleBreakPoint( (sal_uLong)nLine );
1091 0 : Invalidate();
1092 : }
1093 0 : }
1094 :
1095 :
1096 :
1097 0 : void BreakPointWindow::Command( const CommandEvent& rCEvt )
1098 : {
1099 0 : if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
1100 : {
1101 0 : Point aPos( rCEvt.IsMouseEvent() ? rCEvt.GetMousePosPixel() : Point(1,1) );
1102 0 : Point aEventPos( PixelToLogic( aPos ) );
1103 0 : BreakPoint* pBrk = rCEvt.IsMouseEvent() ? FindBreakPoint( aEventPos ) : 0;
1104 0 : if ( pBrk )
1105 : {
1106 : // test if break point is enabled...
1107 0 : PopupMenu aBrkPropMenu( IDEResId( RID_POPUP_BRKPROPS ) );
1108 0 : aBrkPropMenu.CheckItem( RID_ACTIV, pBrk->bEnabled );
1109 0 : switch ( aBrkPropMenu.Execute( this, aPos ) )
1110 : {
1111 : case RID_ACTIV:
1112 : {
1113 0 : pBrk->bEnabled = !pBrk->bEnabled;
1114 0 : rModulWindow.UpdateBreakPoint( *pBrk );
1115 0 : Invalidate();
1116 : }
1117 0 : break;
1118 : case RID_BRKPROPS:
1119 : {
1120 0 : BreakPointDialog aBrkDlg( this, GetBreakPoints() );
1121 0 : aBrkDlg.SetCurrentBreakPoint( pBrk );
1122 0 : aBrkDlg.Execute();
1123 0 : Invalidate();
1124 : }
1125 0 : break;
1126 0 : }
1127 : }
1128 : else
1129 : {
1130 0 : PopupMenu aBrkListMenu( IDEResId( RID_POPUP_BRKDLG ) );
1131 0 : switch ( aBrkListMenu.Execute( this, aPos ) )
1132 : {
1133 : case RID_BRKDLG:
1134 : {
1135 0 : BreakPointDialog aBrkDlg( this, GetBreakPoints() );
1136 0 : aBrkDlg.Execute();
1137 0 : Invalidate();
1138 : }
1139 0 : break;
1140 0 : }
1141 : }
1142 : }
1143 0 : }
1144 :
1145 0 : bool BreakPointWindow::SyncYOffset()
1146 : {
1147 0 : TextView* pView = rModulWindow.GetEditView();
1148 0 : if ( pView )
1149 : {
1150 0 : long nViewYOffset = pView->GetStartDocPos().Y();
1151 0 : if ( nCurYOffset != nViewYOffset )
1152 : {
1153 0 : nCurYOffset = nViewYOffset;
1154 0 : Invalidate();
1155 0 : return true;
1156 : }
1157 : }
1158 0 : return false;
1159 : }
1160 :
1161 : // virtual
1162 0 : void BreakPointWindow::DataChanged(DataChangedEvent const & rDCEvt)
1163 : {
1164 0 : Window::DataChanged(rDCEvt);
1165 0 : if (rDCEvt.GetType() == DATACHANGED_SETTINGS
1166 0 : && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
1167 : {
1168 0 : Color aColor(GetSettings().GetStyleSettings().GetFieldColor());
1169 0 : if (aColor
1170 0 : != rDCEvt.GetOldSettings()->GetStyleSettings().GetFieldColor())
1171 : {
1172 0 : setBackgroundColor(aColor);
1173 0 : Invalidate();
1174 : }
1175 : }
1176 0 : }
1177 :
1178 0 : void BreakPointWindow::setBackgroundColor(Color aColor)
1179 : {
1180 0 : SetBackground(Wallpaper(aColor));
1181 0 : }
1182 :
1183 :
1184 : //
1185 : // WatchWindow
1186 : // ===========
1187 : //
1188 :
1189 : namespace
1190 : {
1191 : const sal_uInt16 ITEM_ID_VARIABLE = 1;
1192 : const sal_uInt16 ITEM_ID_VALUE = 2;
1193 : const sal_uInt16 ITEM_ID_TYPE = 3;
1194 : }
1195 :
1196 0 : WatchWindow::WatchWindow (Layout* pParent) :
1197 : DockingWindow(pParent),
1198 : aWatchStr( IDEResId( RID_STR_REMOVEWATCH ) ),
1199 : aXEdit( this, IDEResId( RID_EDT_WATCHEDIT ) ),
1200 : aRemoveWatchButton( this, IDEResId( RID_IMGBTN_REMOVEWATCH ) ),
1201 : aTreeListBox( this, WB_BORDER | WB_3DLOOK | WB_HASBUTTONS | WB_HASLINES | WB_HSCROLL | WB_TABSTOP
1202 : | WB_HASLINESATROOT | WB_HASBUTTONSATROOT ),
1203 0 : aHeaderBar( this, WB_BUTTONSTYLE | WB_BORDER )
1204 : {
1205 0 : aXEdit.SetAccessibleName(String(IDEResId( RID_STR_WATCHNAME)));
1206 0 : aTreeListBox.SetAccessibleName(String(IDEResId(RID_STR_WATCHNAME)));
1207 :
1208 0 : long nTextLen = GetTextWidth( aWatchStr ) + DWBORDER + 3;
1209 0 : aXEdit.SetPosPixel( Point( nTextLen, 3 ) );
1210 0 : aXEdit.SetAccHdl( LINK( this, WatchWindow, EditAccHdl ) );
1211 0 : aXEdit.GetAccelerator().InsertItem( 1, KeyCode( KEY_RETURN ) );
1212 0 : aXEdit.GetAccelerator().InsertItem( 2, KeyCode( KEY_ESCAPE ) );
1213 0 : aXEdit.Show();
1214 :
1215 0 : aRemoveWatchButton.Disable();
1216 0 : aRemoveWatchButton.SetClickHdl( LINK( this, WatchWindow, ButtonHdl ) );
1217 0 : aRemoveWatchButton.SetPosPixel( Point( nTextLen + aXEdit.GetSizePixel().Width() + 4, 2 ) );
1218 0 : Size aSz( aRemoveWatchButton.GetModeImage().GetSizePixel() );
1219 0 : aSz.Width() += 6;
1220 0 : aSz.Height() += 6;
1221 0 : aRemoveWatchButton.SetSizePixel( aSz );
1222 0 : aRemoveWatchButton.Show();
1223 :
1224 0 : long nRWBtnSize = aRemoveWatchButton.GetModeImage().GetSizePixel().Height() + 10;
1225 0 : nVirtToolBoxHeight = aXEdit.GetSizePixel().Height() + 7;
1226 :
1227 0 : if ( nRWBtnSize > nVirtToolBoxHeight )
1228 0 : nVirtToolBoxHeight = nRWBtnSize;
1229 :
1230 0 : nHeaderBarHeight = 16;
1231 :
1232 0 : aTreeListBox.SetHelpId(HID_BASICIDE_WATCHWINDOW_LIST);
1233 0 : aTreeListBox.EnableInplaceEditing(true);
1234 0 : aTreeListBox.SetSelectHdl( LINK( this, WatchWindow, TreeListHdl ) );
1235 0 : aTreeListBox.SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight + nHeaderBarHeight ) );
1236 0 : aTreeListBox.SetHighlightRange( 1, 5 );
1237 :
1238 0 : Point aPnt( DWBORDER, nVirtToolBoxHeight + 1 );
1239 0 : aHeaderBar.SetPosPixel( aPnt );
1240 0 : aHeaderBar.SetEndDragHdl( LINK( this, WatchWindow, implEndDragHdl ) );
1241 :
1242 0 : long nVarTabWidth = 220;
1243 0 : long nValueTabWidth = 100;
1244 0 : long nTypeTabWidth = 1250;
1245 0 : aHeaderBar.InsertItem( ITEM_ID_VARIABLE, String( IDEResId( RID_STR_WATCHVARIABLE ) ), nVarTabWidth );
1246 0 : aHeaderBar.InsertItem( ITEM_ID_VALUE, String( IDEResId( RID_STR_WATCHVALUE ) ), nValueTabWidth );
1247 0 : aHeaderBar.InsertItem( ITEM_ID_TYPE, String( IDEResId( RID_STR_WATCHTYPE ) ), nTypeTabWidth );
1248 :
1249 : long tabs[ 4 ];
1250 0 : tabs[ 0 ] = 3; // two tabs
1251 0 : tabs[ 1 ] = 0;
1252 0 : tabs[ 2 ] = nVarTabWidth;
1253 0 : tabs[ 3 ] = nVarTabWidth + nValueTabWidth;
1254 0 : aTreeListBox.SvHeaderTabListBox::SetTabs( tabs, MAP_PIXEL );
1255 0 : aTreeListBox.InitHeaderBar( &aHeaderBar );
1256 :
1257 0 : aTreeListBox.SetNodeDefaultImages( );
1258 :
1259 0 : aHeaderBar.Show();
1260 :
1261 0 : aTreeListBox.Show();
1262 :
1263 0 : SetText( String( IDEResId( RID_STR_WATCHNAME ) ) );
1264 :
1265 0 : SetHelpId( HID_BASICIDE_WATCHWINDOW );
1266 :
1267 : // make watch window keyboard accessible
1268 0 : GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
1269 0 : }
1270 :
1271 :
1272 :
1273 0 : WatchWindow::~WatchWindow()
1274 : {
1275 0 : GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
1276 0 : }
1277 :
1278 :
1279 :
1280 0 : void WatchWindow::Paint( const Rectangle& )
1281 : {
1282 0 : DrawText( Point( DWBORDER, 7 ), aWatchStr );
1283 0 : lcl_DrawIDEWindowFrame( this );
1284 0 : }
1285 :
1286 :
1287 :
1288 0 : void WatchWindow::Resize()
1289 : {
1290 0 : Size aSz = GetOutputSizePixel();
1291 0 : Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );
1292 :
1293 0 : if ( aBoxSz.Width() < 4 )
1294 0 : aBoxSz.Width() = 0;
1295 0 : if ( aBoxSz.Height() < 4 )
1296 0 : aBoxSz.Height() = 0;
1297 :
1298 0 : aBoxSz.Height() -= nHeaderBarHeight;
1299 0 : aTreeListBox.SetSizePixel( aBoxSz );
1300 0 : aTreeListBox.GetHScroll()->SetPageSize( aTreeListBox.GetHScroll()->GetVisibleSize() );
1301 :
1302 0 : aBoxSz.Height() = nHeaderBarHeight;
1303 0 : aHeaderBar.SetSizePixel( aBoxSz );
1304 :
1305 0 : Invalidate();
1306 0 : }
1307 :
1308 0 : struct WatchItem
1309 : {
1310 : String maName;
1311 : String maDisplayName;
1312 : SbxObjectRef mpObject;
1313 : std::vector<String> maMemberList;
1314 :
1315 : SbxDimArrayRef mpArray;
1316 : int nDimLevel; // 0 = Root
1317 : int nDimCount;
1318 : std::vector<short> vIndices;
1319 :
1320 : WatchItem* mpArrayParentItem;
1321 :
1322 0 : WatchItem (String const& rName):
1323 : maName(rName),
1324 : nDimLevel(0),
1325 : nDimCount(0),
1326 0 : mpArrayParentItem(0)
1327 0 : { }
1328 :
1329 0 : void clearWatchItem ()
1330 : {
1331 0 : maMemberList.clear();
1332 0 : }
1333 :
1334 : WatchItem* GetRootItem( void );
1335 : SbxDimArray* GetRootArray( void );
1336 : };
1337 :
1338 0 : WatchItem* WatchItem::GetRootItem( void )
1339 : {
1340 0 : WatchItem* pItem = mpArrayParentItem;
1341 0 : while( pItem )
1342 : {
1343 0 : if( pItem->mpArray.Is() )
1344 0 : break;
1345 0 : pItem = pItem->mpArrayParentItem;
1346 : }
1347 0 : return pItem;
1348 : }
1349 :
1350 0 : SbxDimArray* WatchItem::GetRootArray( void )
1351 : {
1352 0 : WatchItem* pRootItem = GetRootItem();
1353 0 : SbxDimArray* pRet = NULL;
1354 0 : if( pRootItem )
1355 0 : pRet = pRootItem->mpArray;
1356 0 : return pRet;
1357 : }
1358 :
1359 0 : void WatchWindow::AddWatch( const String& rVName )
1360 : {
1361 0 : String aVar, aIndex;
1362 0 : lcl_SeparateNameAndIndex( rVName, aVar, aIndex );
1363 0 : WatchItem* pWatchItem = new WatchItem(aVar);
1364 :
1365 0 : OUString aWatchStr_( aVar );
1366 0 : aWatchStr_ += OUString( "\t\t" );
1367 0 : SvTreeListEntry* pNewEntry = aTreeListBox.InsertEntry( aWatchStr_, 0, true, LIST_APPEND );
1368 0 : pNewEntry->SetUserData( pWatchItem );
1369 :
1370 0 : aTreeListBox.Select(pNewEntry, true);
1371 0 : aTreeListBox.MakeVisible(pNewEntry);
1372 0 : aRemoveWatchButton.Enable();
1373 :
1374 0 : UpdateWatches();
1375 0 : }
1376 :
1377 0 : bool WatchWindow::RemoveSelectedWatch()
1378 : {
1379 0 : SvTreeListEntry* pEntry = aTreeListBox.GetCurEntry();
1380 0 : if ( pEntry )
1381 : {
1382 0 : aTreeListBox.GetModel()->Remove( pEntry );
1383 0 : pEntry = aTreeListBox.GetCurEntry();
1384 0 : if ( pEntry )
1385 0 : aXEdit.SetText( ((WatchItem*)pEntry->GetUserData())->maName );
1386 : else
1387 0 : aXEdit.SetText( String() );
1388 0 : if ( !aTreeListBox.GetEntryCount() )
1389 0 : aRemoveWatchButton.Disable();
1390 0 : return true;
1391 : }
1392 : else
1393 0 : return false;
1394 : }
1395 :
1396 :
1397 0 : IMPL_LINK_INLINE_START( WatchWindow, ButtonHdl, ImageButton *, pButton )
1398 : {
1399 0 : if (pButton == &aRemoveWatchButton)
1400 0 : if (SfxDispatcher* pDispatcher = GetDispatcher())
1401 0 : pDispatcher->Execute(SID_BASICIDE_REMOVEWATCH);
1402 0 : return 0;
1403 : }
1404 0 : IMPL_LINK_INLINE_END( WatchWindow, ButtonHdl, ImageButton *, pButton )
1405 :
1406 :
1407 :
1408 0 : IMPL_LINK_NOARG_INLINE_START(WatchWindow, TreeListHdl)
1409 : {
1410 0 : SvTreeListEntry* pCurEntry = aTreeListBox.GetCurEntry();
1411 0 : if ( pCurEntry && pCurEntry->GetUserData() )
1412 0 : aXEdit.SetText( ((WatchItem*)pCurEntry->GetUserData())->maName );
1413 :
1414 0 : return 0;
1415 : }
1416 0 : IMPL_LINK_NOARG_INLINE_END(WatchWindow, TreeListHdl)
1417 :
1418 :
1419 0 : IMPL_LINK_INLINE_START( WatchWindow, implEndDragHdl, HeaderBar *, pBar )
1420 : {
1421 : (void)pBar;
1422 :
1423 0 : const sal_Int32 TAB_WIDTH_MIN = 10;
1424 : sal_Int32 nMaxWidth =
1425 0 : aHeaderBar.GetSizePixel().getWidth() - 2 * TAB_WIDTH_MIN;
1426 :
1427 0 : sal_Int32 nVariableWith = aHeaderBar.GetItemSize( ITEM_ID_VARIABLE );
1428 0 : if( nVariableWith < TAB_WIDTH_MIN )
1429 0 : aHeaderBar.SetItemSize( ITEM_ID_VARIABLE, TAB_WIDTH_MIN );
1430 0 : else if( nVariableWith > nMaxWidth )
1431 0 : aHeaderBar.SetItemSize( ITEM_ID_VARIABLE, nMaxWidth );
1432 :
1433 0 : sal_Int32 nValueWith = aHeaderBar.GetItemSize( ITEM_ID_VALUE );
1434 0 : if( nValueWith < TAB_WIDTH_MIN )
1435 0 : aHeaderBar.SetItemSize( ITEM_ID_VALUE, TAB_WIDTH_MIN );
1436 0 : else if( nValueWith > nMaxWidth )
1437 0 : aHeaderBar.SetItemSize( ITEM_ID_VALUE, nMaxWidth );
1438 :
1439 0 : if (aHeaderBar.GetItemSize( ITEM_ID_TYPE ) < TAB_WIDTH_MIN)
1440 0 : aHeaderBar.SetItemSize( ITEM_ID_TYPE, TAB_WIDTH_MIN );
1441 :
1442 0 : sal_Int32 nPos = 0;
1443 0 : sal_uInt16 nTabs = aHeaderBar.GetItemCount();
1444 0 : for( sal_uInt16 i = 1 ; i < nTabs ; ++i )
1445 : {
1446 0 : nPos += aHeaderBar.GetItemSize( i );
1447 0 : aTreeListBox.SetTab( i, nPos, MAP_PIXEL );
1448 : }
1449 0 : return 0;
1450 : }
1451 0 : IMPL_LINK_INLINE_END( WatchWindow, implEndDragHdl, HeaderBar *, pBar )
1452 :
1453 :
1454 0 : IMPL_LINK( WatchWindow, EditAccHdl, Accelerator *, pAcc )
1455 : {
1456 0 : switch ( pAcc->GetCurKeyCode().GetCode() )
1457 : {
1458 : case KEY_RETURN:
1459 : {
1460 0 : String aCurText( aXEdit.GetText() );
1461 0 : if ( aCurText.Len() )
1462 : {
1463 0 : AddWatch( aCurText );
1464 0 : aXEdit.SetSelection( Selection( 0, 0xFFFF ) );
1465 0 : }
1466 : }
1467 0 : break;
1468 : case KEY_ESCAPE:
1469 : {
1470 0 : aXEdit.SetText( String() );
1471 : }
1472 0 : break;
1473 : }
1474 :
1475 0 : return 0;
1476 : }
1477 :
1478 0 : void WatchWindow::UpdateWatches( bool bBasicStopped )
1479 : {
1480 0 : aTreeListBox.UpdateWatches( bBasicStopped );
1481 0 : }
1482 :
1483 :
1484 : //
1485 : // StackWindow
1486 : // ===========
1487 : //
1488 :
1489 0 : StackWindow::StackWindow (Layout* pParent) :
1490 : DockingWindow(pParent),
1491 : aTreeListBox( this, WB_BORDER | WB_3DLOOK | WB_HSCROLL | WB_TABSTOP ),
1492 0 : aStackStr( IDEResId( RID_STR_STACK ) )
1493 : {
1494 0 : aTreeListBox.SetHelpId(HID_BASICIDE_STACKWINDOW_LIST);
1495 0 : aTreeListBox.SetAccessibleName(String( IDEResId(RID_STR_STACKNAME)));
1496 0 : aTreeListBox.SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight ) );
1497 0 : aTreeListBox.SetHighlightRange();
1498 0 : aTreeListBox.SetSelectionMode( NO_SELECTION );
1499 0 : aTreeListBox.InsertEntry( String(), 0, false, LIST_APPEND );
1500 0 : aTreeListBox.Show();
1501 :
1502 0 : SetText( String( IDEResId( RID_STR_STACKNAME ) ) );
1503 :
1504 0 : SetHelpId( HID_BASICIDE_STACKWINDOW );
1505 :
1506 : // make stack window keyboard accessible
1507 0 : GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
1508 0 : }
1509 :
1510 :
1511 :
1512 0 : StackWindow::~StackWindow()
1513 : {
1514 0 : GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
1515 0 : }
1516 :
1517 :
1518 :
1519 0 : void StackWindow::Paint( const Rectangle& )
1520 : {
1521 0 : DrawText( Point( DWBORDER, 7 ), aStackStr );
1522 0 : lcl_DrawIDEWindowFrame( this );
1523 0 : }
1524 :
1525 :
1526 :
1527 0 : void StackWindow::Resize()
1528 : {
1529 0 : Size aSz = GetOutputSizePixel();
1530 0 : Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );
1531 :
1532 0 : if ( aBoxSz.Width() < 4 )
1533 0 : aBoxSz.Width() = 0;
1534 0 : if ( aBoxSz.Height() < 4 )
1535 0 : aBoxSz.Height() = 0;
1536 :
1537 0 : aTreeListBox.SetSizePixel( aBoxSz );
1538 :
1539 0 : Invalidate();
1540 0 : }
1541 :
1542 0 : void StackWindow::UpdateCalls()
1543 : {
1544 0 : aTreeListBox.SetUpdateMode(false);
1545 0 : aTreeListBox.Clear();
1546 :
1547 0 : if ( StarBASIC::IsRunning() )
1548 : {
1549 0 : SbxError eOld = SbxBase::GetError();
1550 0 : aTreeListBox.SetSelectionMode( SINGLE_SELECTION );
1551 :
1552 0 : sal_uInt16 nScope = 0;
1553 0 : SbMethod* pMethod = StarBASIC::GetActiveMethod( nScope );
1554 0 : while ( pMethod )
1555 : {
1556 0 : String aEntry( String::CreateFromInt32(nScope ));
1557 0 : if ( aEntry.Len() < 2 )
1558 0 : aEntry.Insert( ' ', 0 );
1559 0 : aEntry += OUString( ": " );
1560 0 : aEntry += pMethod->GetName();
1561 0 : SbxArray* pParams = pMethod->GetParameters();
1562 0 : SbxInfo* pInfo = pMethod->GetInfo();
1563 0 : if ( pParams )
1564 : {
1565 0 : aEntry += '(';
1566 : // 0 is the sub's name...
1567 0 : for ( sal_uInt16 nParam = 1; nParam < pParams->Count(); nParam++ )
1568 : {
1569 0 : SbxVariable* pVar = pParams->Get( nParam );
1570 : DBG_ASSERT( pVar, "Parameter?!" );
1571 0 : if ( !pVar->GetName().isEmpty() )
1572 : {
1573 0 : aEntry += pVar->GetName();
1574 : }
1575 0 : else if ( pInfo )
1576 : {
1577 0 : const SbxParamInfo* pParam = pInfo->GetParam( nParam );
1578 0 : if ( pParam )
1579 : {
1580 0 : aEntry += pParam->aName;
1581 : }
1582 : }
1583 0 : aEntry += '=';
1584 0 : SbxDataType eType = pVar->GetType();
1585 0 : if( eType & SbxARRAY )
1586 : {
1587 0 : aEntry += OUString( "..." );
1588 : }
1589 0 : else if( eType != SbxOBJECT )
1590 : {
1591 0 : aEntry += pVar->GetOUString();
1592 : }
1593 0 : if ( nParam < ( pParams->Count() - 1 ) )
1594 : {
1595 0 : aEntry += OUString( ", " );
1596 : }
1597 : }
1598 0 : aEntry += ')';
1599 : }
1600 0 : aTreeListBox.InsertEntry( aEntry, 0, false, LIST_APPEND );
1601 0 : nScope++;
1602 0 : pMethod = StarBASIC::GetActiveMethod( nScope );
1603 0 : }
1604 :
1605 0 : SbxBase::ResetError();
1606 0 : if( eOld != SbxERR_OK )
1607 0 : SbxBase::SetError( eOld );
1608 : }
1609 : else
1610 : {
1611 0 : aTreeListBox.SetSelectionMode( NO_SELECTION );
1612 0 : aTreeListBox.InsertEntry( String(), 0, false, LIST_APPEND );
1613 : }
1614 :
1615 0 : aTreeListBox.SetUpdateMode(true);
1616 0 : }
1617 :
1618 :
1619 : //
1620 : // ComplexEditorWindow
1621 : // ===================
1622 : //
1623 :
1624 0 : ComplexEditorWindow::ComplexEditorWindow( ModulWindow* pParent ) :
1625 : Window( pParent, WB_3DLOOK | WB_CLIPCHILDREN ),
1626 : aBrkWindow(this, pParent),
1627 : aLineNumberWindow(this, pParent),
1628 : aEdtWindow(this, pParent),
1629 0 : aEWVScrollBar( this, WB_VSCROLL | WB_DRAG )
1630 : {
1631 0 : aEdtWindow.Show();
1632 0 : aBrkWindow.Show();
1633 :
1634 0 : aEWVScrollBar.SetLineSize(nScrollLine);
1635 0 : aEWVScrollBar.SetPageSize(nScrollPage);
1636 0 : aEWVScrollBar.SetScrollHdl( LINK( this, ComplexEditorWindow, ScrollHdl ) );
1637 0 : aEWVScrollBar.Show();
1638 0 : }
1639 :
1640 0 : void ComplexEditorWindow::Resize()
1641 : {
1642 0 : Size aOutSz = GetOutputSizePixel();
1643 0 : Size aSz( aOutSz );
1644 0 : aSz.Width() -= 2*DWBORDER;
1645 0 : aSz.Height() -= 2*DWBORDER;
1646 0 : long nBrkWidth = 20;
1647 0 : long nSBWidth = aEWVScrollBar.GetSizePixel().Width();
1648 :
1649 0 : Size aBrkSz(nBrkWidth, aSz.Height());
1650 :
1651 0 : Size aLnSz(aLineNumberWindow.GetWidth(), aSz.Height());
1652 :
1653 0 : if (aLineNumberWindow.IsVisible())
1654 : {
1655 0 : aBrkWindow.SetPosSizePixel( Point( DWBORDER, DWBORDER ), aBrkSz );
1656 0 : aLineNumberWindow.SetPosSizePixel(Point(DWBORDER + aBrkSz.Width() - 1, DWBORDER), aLnSz);
1657 0 : Size aEWSz(aSz.Width() - nBrkWidth - aLineNumberWindow.GetWidth() - nSBWidth + 2, aSz.Height());
1658 0 : aEdtWindow.SetPosSizePixel( Point( DWBORDER + aBrkSz.Width() + aLnSz.Width() - 1, DWBORDER ), aEWSz );
1659 : }
1660 : else
1661 : {
1662 0 : aBrkWindow.SetPosSizePixel( Point( DWBORDER, DWBORDER ), aBrkSz );
1663 0 : Size aEWSz(aSz.Width() - nBrkWidth - nSBWidth + 2, aSz.Height());
1664 0 : aEdtWindow.SetPosSizePixel(Point(DWBORDER + aBrkSz.Width() - 1, DWBORDER), aEWSz);
1665 : }
1666 :
1667 0 : aEWVScrollBar.SetPosSizePixel( Point( aOutSz.Width() - DWBORDER - nSBWidth, DWBORDER ), Size( nSBWidth, aSz.Height() ) );
1668 0 : }
1669 :
1670 0 : IMPL_LINK( ComplexEditorWindow, ScrollHdl, ScrollBar *, pCurScrollBar )
1671 : {
1672 0 : if ( aEdtWindow.GetEditView() )
1673 : {
1674 : DBG_ASSERT( pCurScrollBar == &aEWVScrollBar, "Wer scrollt hier ?" );
1675 0 : long nDiff = aEdtWindow.GetEditView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
1676 0 : aEdtWindow.GetEditView()->Scroll( 0, nDiff );
1677 0 : aBrkWindow.DoScroll( 0, nDiff );
1678 0 : aLineNumberWindow.DoScroll(0, nDiff);
1679 0 : aEdtWindow.GetEditView()->ShowCursor(false, true);
1680 0 : pCurScrollBar->SetThumbPos( aEdtWindow.GetEditView()->GetStartDocPos().Y() );
1681 : }
1682 :
1683 0 : return 0;
1684 : }
1685 :
1686 0 : void ComplexEditorWindow::DataChanged(DataChangedEvent const & rDCEvt)
1687 : {
1688 0 : Window::DataChanged(rDCEvt);
1689 0 : if (rDCEvt.GetType() == DATACHANGED_SETTINGS
1690 0 : && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
1691 : {
1692 0 : Color aColor(GetSettings().GetStyleSettings().GetFaceColor());
1693 0 : if (aColor
1694 0 : != rDCEvt.GetOldSettings()->GetStyleSettings().GetFaceColor())
1695 : {
1696 0 : SetBackground(Wallpaper(aColor));
1697 0 : Invalidate();
1698 : }
1699 : }
1700 0 : }
1701 :
1702 0 : void ComplexEditorWindow::SetLineNumberDisplay(bool b)
1703 : {
1704 0 : aLineNumberWindow.Show(b);
1705 0 : Resize();
1706 0 : }
1707 :
1708 : uno::Reference< awt::XWindowPeer >
1709 0 : EditorWindow::GetComponentInterface(sal_Bool bCreate)
1710 : {
1711 : uno::Reference< awt::XWindowPeer > xPeer(
1712 0 : Window::GetComponentInterface(false));
1713 0 : if (!xPeer.is() && bCreate)
1714 : {
1715 : // Make sure edit engine and view are available:
1716 0 : if (!pEditEngine)
1717 0 : CreateEditEngine();
1718 :
1719 0 : xPeer = new ::svt::TextWindowPeer(*GetEditView());
1720 0 : SetComponentInterface(xPeer);
1721 : }
1722 0 : return xPeer;
1723 : }
1724 :
1725 :
1726 : //
1727 : // WatchTreeListBox
1728 : // ================
1729 : //
1730 :
1731 0 : WatchTreeListBox::WatchTreeListBox( Window* pParent, WinBits nWinBits )
1732 0 : : SvHeaderTabListBox( pParent, nWinBits )
1733 0 : {}
1734 :
1735 0 : WatchTreeListBox::~WatchTreeListBox()
1736 : {
1737 : // Destroy user data
1738 0 : SvTreeListEntry* pEntry = First();
1739 0 : while ( pEntry )
1740 : {
1741 0 : delete (WatchItem*)pEntry->GetUserData();
1742 0 : pEntry = Next( pEntry );
1743 : }
1744 0 : }
1745 :
1746 0 : void WatchTreeListBox::SetTabs()
1747 : {
1748 0 : SvHeaderTabListBox::SetTabs();
1749 0 : sal_uInt16 nTabCount_ = aTabs.size();
1750 0 : for( sal_uInt16 i = 0 ; i < nTabCount_ ; i++ )
1751 : {
1752 0 : SvLBoxTab* pTab = aTabs[i];
1753 0 : if( i == 2 )
1754 0 : pTab->nFlags |= SV_LBOXTAB_EDITABLE;
1755 : else
1756 0 : pTab->nFlags &= ~SV_LBOXTAB_EDITABLE;
1757 : }
1758 0 : }
1759 :
1760 0 : void WatchTreeListBox::RequestingChildren( SvTreeListEntry * pParent )
1761 : {
1762 0 : if( !StarBASIC::IsRunning() )
1763 0 : return;
1764 :
1765 0 : if( GetChildCount( pParent ) > 0 )
1766 0 : return;
1767 :
1768 0 : SvTreeListEntry* pEntry = pParent;
1769 0 : WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1770 :
1771 0 : SbxDimArray* pArray = pItem->mpArray;
1772 0 : SbxDimArray* pRootArray = pItem->GetRootArray();
1773 0 : bool bArrayIsRootArray = false;
1774 0 : if( !pArray && pRootArray )
1775 : {
1776 0 : pArray = pRootArray;
1777 0 : bArrayIsRootArray = true;
1778 : }
1779 :
1780 0 : SbxObject* pObj = pItem->mpObject;
1781 0 : if( pObj )
1782 : {
1783 0 : createAllObjectProperties( pObj );
1784 0 : SbxArray* pProps = pObj->GetProperties();
1785 0 : sal_uInt16 nPropCount = pProps->Count();
1786 0 : pItem->maMemberList.reserve(nPropCount);
1787 :
1788 0 : for( sal_uInt16 i = 0 ; i < nPropCount - 3 ; i++ )
1789 : {
1790 0 : SbxVariable* pVar = pProps->Get( i );
1791 :
1792 0 : pItem->maMemberList.push_back(String(pVar->GetName()));
1793 0 : String const& rName = pItem->maMemberList.back();
1794 0 : SvTreeListEntry* pChildEntry = SvTreeListBox::InsertEntry( rName, pEntry );
1795 0 : pChildEntry->SetUserData(new WatchItem(rName));
1796 : }
1797 0 : if( nPropCount > 0 )
1798 : {
1799 0 : UpdateWatches();
1800 : }
1801 : }
1802 0 : else if( pArray )
1803 : {
1804 0 : sal_uInt16 nElementCount = 0;
1805 :
1806 : // Loop through indices of current level
1807 0 : int nParentLevel = bArrayIsRootArray ? pItem->nDimLevel : 0;
1808 0 : int nThisLevel = nParentLevel + 1;
1809 : sal_Int32 nMin, nMax;
1810 0 : pArray->GetDim32( nThisLevel, nMin, nMax );
1811 0 : for( sal_Int32 i = nMin ; i <= nMax ; i++ )
1812 : {
1813 0 : WatchItem* pChildItem = new WatchItem(pItem->maName);
1814 :
1815 : // Copy data and create name
1816 :
1817 0 : String aIndexStr = OUString( "(" );
1818 0 : pChildItem->mpArrayParentItem = pItem;
1819 0 : pChildItem->nDimLevel = nThisLevel;
1820 0 : pChildItem->nDimCount = pItem->nDimCount;
1821 0 : pChildItem->vIndices.resize(pChildItem->nDimCount);
1822 : sal_uInt16 j;
1823 0 : for( j = 0 ; j < nParentLevel ; j++ )
1824 : {
1825 0 : short n = pChildItem->vIndices[j] = pItem->vIndices[j];
1826 0 : aIndexStr += String::CreateFromInt32( n );
1827 0 : aIndexStr += OUString( "," );
1828 : }
1829 0 : pChildItem->vIndices[nParentLevel] = sal::static_int_cast<short>( i );
1830 0 : aIndexStr += String::CreateFromInt32( i );
1831 0 : aIndexStr += OUString( ")" );
1832 :
1833 0 : String aDisplayName;
1834 0 : WatchItem* pArrayRootItem = pChildItem->GetRootItem();
1835 0 : if( pArrayRootItem && pArrayRootItem->mpArrayParentItem )
1836 0 : aDisplayName = pItem->maDisplayName;
1837 : else
1838 0 : aDisplayName = pItem->maName;
1839 0 : aDisplayName += aIndexStr;
1840 0 : pChildItem->maDisplayName = aDisplayName;
1841 :
1842 0 : SvTreeListEntry* pChildEntry = SvTreeListBox::InsertEntry( aDisplayName, pEntry );
1843 0 : nElementCount++;
1844 0 : pChildEntry->SetUserData( pChildItem );
1845 0 : }
1846 0 : if( nElementCount > 0 )
1847 : {
1848 0 : UpdateWatches();
1849 : }
1850 : }
1851 : }
1852 :
1853 0 : SbxBase* WatchTreeListBox::ImplGetSBXForEntry( SvTreeListEntry* pEntry, bool& rbArrayElement )
1854 : {
1855 0 : SbxBase* pSBX = NULL;
1856 0 : rbArrayElement = false;
1857 :
1858 0 : WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1859 0 : String aVName( pItem->maName );
1860 :
1861 0 : SvTreeListEntry* pParentEntry = GetParent( pEntry );
1862 0 : WatchItem* pParentItem = pParentEntry ? (WatchItem*)pParentEntry->GetUserData() : NULL;
1863 0 : if( pParentItem )
1864 : {
1865 0 : SbxObject* pObj = pParentItem->mpObject;
1866 : SbxDimArray* pArray;
1867 0 : if( pObj )
1868 : {
1869 0 : pSBX = pObj->Find( aVName, SbxCLASS_DONTCARE );
1870 0 : if (SbxVariable const* pVar = IsSbxVariable(pSBX))
1871 : {
1872 : // Force getting value
1873 0 : SbxValues aRes;
1874 0 : aRes.eType = SbxVOID;
1875 0 : pVar->Get( aRes );
1876 : }
1877 : }
1878 : // Array?
1879 0 : else if( (pArray = pItem->GetRootArray()) != NULL )
1880 : {
1881 0 : rbArrayElement = true;
1882 0 : if( pParentItem->nDimLevel + 1 == pParentItem->nDimCount )
1883 0 : pSBX = pArray->Get(pItem->vIndices.empty() ? 0 : &*pItem->vIndices.begin());
1884 : }
1885 : }
1886 : else
1887 : {
1888 0 : pSBX = StarBASIC::FindSBXInCurrentScope( aVName );
1889 : }
1890 0 : return pSBX;
1891 : }
1892 :
1893 0 : sal_Bool WatchTreeListBox::EditingEntry( SvTreeListEntry* pEntry, Selection& )
1894 : {
1895 0 : WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1896 :
1897 0 : bool bEdit = false;
1898 0 : if ( StarBASIC::IsRunning() && StarBASIC::GetActiveMethod() && !SbxBase::IsError() )
1899 : {
1900 : // No out of scope entries
1901 : bool bArrayElement;
1902 0 : SbxBase* pSbx = ImplGetSBXForEntry( pEntry, bArrayElement );
1903 0 : if (IsSbxVariable(pSbx) || bArrayElement)
1904 : {
1905 : // Accept no objects and only end nodes of arrays for editing
1906 0 : if( !pItem->mpObject && (pItem->mpArray == NULL || pItem->nDimLevel == pItem->nDimCount) )
1907 : {
1908 0 : aEditingRes = SvHeaderTabListBox::GetEntryText( pEntry, ITEM_ID_VALUE-1 );
1909 0 : aEditingRes = comphelper::string::strip(aEditingRes, ' ');
1910 0 : bEdit = true;
1911 : }
1912 : }
1913 : }
1914 :
1915 0 : return bEdit;
1916 : }
1917 :
1918 0 : sal_Bool WatchTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText )
1919 : {
1920 0 : WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
1921 0 : String aVName( pItem->maName );
1922 :
1923 0 : String aResult = comphelper::string::strip(rNewText, ' ');
1924 :
1925 0 : sal_uInt16 nResultLen = aResult.Len();
1926 0 : sal_Unicode cFirst = aResult.GetChar( 0 );
1927 0 : sal_Unicode cLast = aResult.GetChar( nResultLen - 1 );
1928 0 : if( cFirst == '\"' && cLast == '\"' )
1929 0 : aResult = aResult.Copy( 1, nResultLen - 2 );
1930 :
1931 0 : return aResult != aEditingRes && ImplBasicEntryEdited(pEntry, aResult);
1932 : }
1933 :
1934 0 : bool WatchTreeListBox::ImplBasicEntryEdited( SvTreeListEntry* pEntry, const String& rResult )
1935 : {
1936 : bool bArrayElement;
1937 0 : SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
1938 :
1939 0 : if (SbxVariable* pVar = IsSbxVariable(pSBX))
1940 : {
1941 0 : SbxDataType eType = pVar->GetType();
1942 0 : if ( (sal_uInt8)eType != (sal_uInt8)SbxOBJECT
1943 : && ( eType & SbxARRAY ) == 0 )
1944 : {
1945 : // If the type is variable, the conversion of the SBX does not matter,
1946 : // else the string is converted.
1947 0 : pVar->PutStringExt( rResult );
1948 : }
1949 : }
1950 :
1951 0 : if ( SbxBase::IsError() )
1952 : {
1953 0 : SbxBase::ResetError();
1954 : }
1955 :
1956 0 : UpdateWatches();
1957 :
1958 : // The text should never be taken/copied 1:1,
1959 : // as the UpdateWatches will be lost
1960 0 : return false;
1961 : }
1962 :
1963 :
1964 : namespace
1965 : {
1966 :
1967 0 : void implCollapseModifiedObjectEntry( SvTreeListEntry* pParent, WatchTreeListBox* pThis )
1968 : {
1969 0 : pThis->Collapse( pParent );
1970 :
1971 0 : SvTreeList* pModel = pThis->GetModel();
1972 : SvTreeListEntry* pDeleteEntry;
1973 0 : while( (pDeleteEntry = pThis->SvTreeListBox::GetEntry( pParent, 0 )) != NULL )
1974 : {
1975 0 : implCollapseModifiedObjectEntry( pDeleteEntry, pThis );
1976 :
1977 0 : delete (WatchItem*)pDeleteEntry->GetUserData();
1978 0 : pModel->Remove( pDeleteEntry );
1979 : }
1980 0 : }
1981 :
1982 0 : String implCreateTypeStringForDimArray( WatchItem* pItem, SbxDataType eType )
1983 : {
1984 0 : String aRetStr = getBasicTypeName( eType );
1985 :
1986 0 : SbxDimArray* pArray = pItem->mpArray;
1987 0 : if( !pArray )
1988 0 : pArray = pItem->GetRootArray();
1989 0 : if( pArray )
1990 : {
1991 0 : int nDimLevel = pItem->nDimLevel;
1992 0 : int nDims = pItem->nDimCount;
1993 0 : if( nDimLevel < nDims )
1994 : {
1995 0 : aRetStr += '(';
1996 0 : for( int i = nDimLevel ; i < nDims ; i++ )
1997 : {
1998 : short nMin, nMax;
1999 0 : pArray->GetDim( sal::static_int_cast<short>( i+1 ), nMin, nMax );
2000 0 : aRetStr += String::CreateFromInt32( nMin );
2001 0 : aRetStr += OUString( " to " );
2002 0 : aRetStr += String::CreateFromInt32( nMax );
2003 0 : if( i < nDims - 1 )
2004 0 : aRetStr += OUString( ", " );
2005 : }
2006 0 : aRetStr += ')';
2007 : }
2008 : }
2009 0 : return aRetStr;
2010 : }
2011 :
2012 0 : void implEnableChildren( SvTreeListEntry* pEntry, bool bEnable )
2013 : {
2014 0 : if( bEnable )
2015 : {
2016 : pEntry->SetFlags(
2017 0 : (pEntry->GetFlags() &
2018 : ~(SV_ENTRYFLAG_NO_NODEBMP | SV_ENTRYFLAG_HAD_CHILDREN))
2019 0 : | SV_ENTRYFLAG_CHILDREN_ON_DEMAND );
2020 : }
2021 : else
2022 : {
2023 : pEntry->SetFlags(
2024 0 : (pEntry->GetFlags() & ~(SV_ENTRYFLAG_CHILDREN_ON_DEMAND)) );
2025 : }
2026 0 : }
2027 :
2028 : } // namespace
2029 :
2030 0 : void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
2031 : {
2032 0 : SbMethod* pCurMethod = StarBASIC::GetActiveMethod();
2033 :
2034 0 : SbxError eOld = SbxBase::GetError();
2035 0 : setBasicWatchMode( true );
2036 :
2037 0 : SvTreeListEntry* pEntry = First();
2038 0 : while ( pEntry )
2039 : {
2040 0 : WatchItem* pItem = (WatchItem*)pEntry->GetUserData();
2041 0 : String aVName( pItem->maName );
2042 : DBG_ASSERT( aVName.Len(), "Var? - Must not be empty!" );
2043 0 : String aWatchStr;
2044 0 : String aTypeStr;
2045 0 : if ( pCurMethod )
2046 : {
2047 : bool bArrayElement;
2048 0 : SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
2049 :
2050 : // Array? If no end node create type string
2051 0 : if( bArrayElement && pItem->nDimLevel < pItem->nDimCount )
2052 : {
2053 0 : SbxDimArray* pRootArray = pItem->GetRootArray();
2054 0 : SbxDataType eType = pRootArray->GetType();
2055 0 : aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
2056 0 : implEnableChildren( pEntry, true );
2057 : }
2058 :
2059 0 : bool bCollapse = false;
2060 0 : if (SbxVariable const* pVar = IsSbxVariable(pSBX))
2061 : {
2062 : // extra treatment of arrays
2063 0 : SbxDataType eType = pVar->GetType();
2064 0 : if ( eType & SbxARRAY )
2065 : {
2066 : // consider multidimensinal arrays!
2067 0 : if (SbxDimArray* pNewArray = dynamic_cast<SbxDimArray*>(pVar->GetObject()))
2068 : {
2069 0 : SbxDimArray* pOldArray = pItem->mpArray;
2070 :
2071 0 : bool bArrayChanged = false;
2072 0 : if( pNewArray != NULL && pOldArray != NULL )
2073 : {
2074 : // Compare Array dimensions to see if array has changed
2075 : // Can be a copy, so comparing pointers does not work
2076 0 : sal_uInt16 nOldDims = pOldArray->GetDims();
2077 0 : sal_uInt16 nNewDims = pNewArray->GetDims();
2078 0 : if( nOldDims != nNewDims )
2079 : {
2080 0 : bArrayChanged = true;
2081 : }
2082 : else
2083 : {
2084 0 : for( int i = 0 ; i < nOldDims ; i++ )
2085 : {
2086 : short nOldMin, nOldMax;
2087 : short nNewMin, nNewMax;
2088 :
2089 0 : pOldArray->GetDim( sal::static_int_cast<short>( i+1 ), nOldMin, nOldMax );
2090 0 : pNewArray->GetDim( sal::static_int_cast<short>( i+1 ), nNewMin, nNewMax );
2091 0 : if( nOldMin != nNewMin || nOldMax != nNewMax )
2092 : {
2093 0 : bArrayChanged = true;
2094 : break;
2095 : }
2096 : }
2097 0 : }
2098 : }
2099 0 : else if( pNewArray == NULL || pOldArray == NULL )
2100 : {
2101 0 : bArrayChanged = true;
2102 : }
2103 0 : if( pNewArray )
2104 : {
2105 0 : implEnableChildren( pEntry, true );
2106 : }
2107 : // #i37227 Clear always and replace array
2108 0 : if( pNewArray != pOldArray )
2109 : {
2110 0 : pItem->clearWatchItem();
2111 0 : if( pNewArray )
2112 : {
2113 0 : implEnableChildren( pEntry, true );
2114 :
2115 0 : pItem->mpArray = pNewArray;
2116 0 : sal_uInt16 nDims = pNewArray->GetDims();
2117 0 : pItem->nDimLevel = 0;
2118 0 : pItem->nDimCount = nDims;
2119 : }
2120 : }
2121 0 : if( bArrayChanged && pOldArray != NULL )
2122 : {
2123 0 : bCollapse = true;
2124 : }
2125 0 : aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
2126 : }
2127 : else
2128 : {
2129 0 : aWatchStr += OUString( "<?>" );
2130 : }
2131 : }
2132 0 : else if ( (sal_uInt8)eType == (sal_uInt8)SbxOBJECT )
2133 : {
2134 0 : if (SbxObject* pObj = dynamic_cast<SbxObject*>(pVar->GetObject()))
2135 : {
2136 : // Check if member list has changed
2137 0 : bool bObjChanged = false;
2138 0 : if (pItem->mpObject && !pItem->maMemberList.empty())
2139 : {
2140 0 : SbxArray* pProps = pObj->GetProperties();
2141 0 : sal_uInt16 nPropCount = pProps->Count();
2142 0 : for( sal_uInt16 i = 0 ; i < nPropCount - 3 ; i++ )
2143 : {
2144 0 : SbxVariable* pVar_ = pProps->Get( i );
2145 0 : String aName( pVar_->GetName() );
2146 0 : if( pItem->maMemberList[i] != aName )
2147 : {
2148 0 : bObjChanged = true;
2149 : break;
2150 : }
2151 0 : }
2152 0 : if( bObjChanged )
2153 : {
2154 0 : bCollapse = true;
2155 : }
2156 : }
2157 :
2158 0 : pItem->mpObject = pObj;
2159 0 : implEnableChildren( pEntry, true );
2160 0 : aTypeStr = getBasicObjectTypeName( pObj );
2161 : }
2162 : else
2163 : {
2164 0 : aWatchStr = OUString( "Null" );
2165 0 : if( pItem->mpObject != NULL )
2166 : {
2167 0 : bCollapse = true;
2168 0 : pItem->clearWatchItem();
2169 :
2170 0 : implEnableChildren( pEntry, false );
2171 : }
2172 : }
2173 : }
2174 : else
2175 : {
2176 0 : if( pItem->mpObject != NULL )
2177 : {
2178 0 : bCollapse = true;
2179 0 : pItem->clearWatchItem();
2180 :
2181 0 : implEnableChildren( pEntry, false );
2182 : }
2183 :
2184 0 : bool bString = ((sal_uInt8)eType == (sal_uInt8)SbxSTRING);
2185 0 : OUString aStrStr( "\"" );
2186 0 : if( bString )
2187 : {
2188 0 : aWatchStr += aStrStr;
2189 : }
2190 0 : aWatchStr += pVar->GetOUString();
2191 0 : if( bString )
2192 : {
2193 0 : aWatchStr += aStrStr;
2194 0 : }
2195 : }
2196 0 : if( !aTypeStr.Len() )
2197 : {
2198 0 : if( !pVar->IsFixed() )
2199 : {
2200 0 : aTypeStr = OUString( "Variant/" );
2201 : }
2202 0 : aTypeStr += getBasicTypeName( pVar->GetType() );
2203 : }
2204 : }
2205 0 : else if( !bArrayElement )
2206 : {
2207 0 : aWatchStr += OUString( "<Out of Scope>" );
2208 : }
2209 :
2210 0 : if( bCollapse )
2211 : {
2212 0 : implCollapseModifiedObjectEntry( pEntry, this );
2213 : }
2214 :
2215 : }
2216 0 : else if( bBasicStopped )
2217 : {
2218 0 : if( pItem->mpObject || pItem->mpArray )
2219 : {
2220 0 : implCollapseModifiedObjectEntry( pEntry, this );
2221 0 : pItem->mpObject = NULL;
2222 : }
2223 : }
2224 :
2225 0 : SvHeaderTabListBox::SetEntryText( aWatchStr, pEntry, ITEM_ID_VALUE-1 );
2226 0 : SvHeaderTabListBox::SetEntryText( aTypeStr, pEntry, ITEM_ID_TYPE-1 );
2227 :
2228 0 : pEntry = Next( pEntry );
2229 0 : }
2230 :
2231 : // Force redraw
2232 0 : Invalidate();
2233 :
2234 0 : SbxBase::ResetError();
2235 0 : if( eOld != SbxERR_OK )
2236 0 : SbxBase::SetError( eOld );
2237 0 : setBasicWatchMode( false );
2238 0 : }
2239 :
2240 :
2241 : } // namespace basctl
2242 :
2243 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|