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