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