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