1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include "baside2.hxx" 21 #include <baside3.hxx> 22 #include "brkdlg.hxx" 23 #include <iderdll.hxx> 24 #include "moduldlg.hxx" 25 #include <docsignature.hxx> 26 #include <officecfg/Office/BasicIDE.hxx> 27 28 #include <helpids.h> 29 #include <strings.hrc> 30 31 #include <basic/basmgr.hxx> 32 #include <basic/basrdll.hxx> 33 #include <basic/sbmeth.hxx> 34 #include <com/sun/star/script/ModuleType.hpp> 35 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> 36 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> 37 #include <com/sun/star/ui/dialogs/FilePicker.hpp> 38 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> 39 #include <comphelper/string.hxx> 40 #include <svl/srchdefs.hxx> 41 #include <svtools/ehdl.hxx> 42 #include <sfx2/dinfdlg.hxx> 43 #include <sfx2/dispatch.hxx> 44 #include <sfx2/docfile.hxx> 45 #include <sfx2/printer.hxx> 46 #include <sfx2/request.hxx> 47 #include <sfx2/viewfrm.hxx> 48 #include <sot/exchange.hxx> 49 #include <svl/aeitem.hxx> 50 #include <svl/srchitem.hxx> 51 #include <svl/visitem.hxx> 52 #include <svl/whiter.hxx> 53 #include <svx/svxids.hrc> 54 #include <vcl/settings.hxx> 55 #include <vcl/weld.hxx> 56 #include <vcl/xtextedt.hxx> 57 #include <vcl/textview.hxx> 58 #include <toolkit/helper/vclunohelper.hxx> 59 #include <cassert> 60 #include <osl/diagnose.h> 61 62 namespace basctl 63 { 64 65 namespace 66 { 67 68 namespace Print 69 { 70 long const nLeftMargin = 1700; 71 long const nRightMargin = 900; 72 long const nTopMargin = 2000; 73 long const nBottomMargin = 1000; 74 long const nBorder = 300; 75 } 76 77 short const ValidWindow = 0x1234; 78 79 // What (who) are OW and MTF? Compare to baside3.cxx where an 80 // identically named variable, used in the same way, has the value 81 // "*.*" on Windows, "*" otherwise. Is that what should be done here, 82 // too? 83 84 #if defined(OW) || defined(MTF) 85 char const FilterMask_All[] = "*"; 86 #else 87 char const FilterMask_All[] = "*.*"; 88 #endif 89 90 } // end anonymous namespace 91 92 using namespace ::com::sun::star; 93 using namespace ::com::sun::star::uno; 94 using namespace ::com::sun::star::ui::dialogs; 95 using namespace utl; 96 using namespace comphelper; 97 98 namespace 99 { 100 101 void lcl_PrintHeader( Printer* pPrinter, sal_uInt16 nPages, sal_uInt16 nCurPage, const OUString& rTitle, bool bOutput ) 102 { 103 Size const aSz = pPrinter->GetOutputSize(); 104 105 const Color aOldLineColor( pPrinter->GetLineColor() ); 106 const Color aOldFillColor( pPrinter->GetFillColor() ); 107 const vcl::Font aOldFont( pPrinter->GetFont() ); 108 109 pPrinter->SetLineColor( COL_BLACK ); 110 pPrinter->SetFillColor(); 111 112 vcl::Font aFont( aOldFont ); 113 aFont.SetWeight( WEIGHT_BOLD ); 114 aFont.SetAlignment( ALIGN_BOTTOM ); 115 pPrinter->SetFont( aFont ); 116 117 long nFontHeight = pPrinter->GetTextHeight(); 118 119 // 1st Border => line, 2+3 Border = free space 120 long nYTop = Print::nTopMargin - 3*Print::nBorder - nFontHeight; 121 122 long nXLeft = Print::nLeftMargin - Print::nBorder; 123 long nXRight = aSz.Width() - Print::nRightMargin + Print::nBorder; 124 125 if( bOutput ) 126 pPrinter->DrawRect(tools::Rectangle( 127 Point(nXLeft, nYTop), 128 Size(nXRight - nXLeft, aSz.Height() - nYTop - Print::nBottomMargin + Print::nBorder) 129 )); 130 131 132 long nY = Print::nTopMargin - 2*Print::nBorder; 133 Point aPos(Print::nLeftMargin, nY); 134 if( bOutput ) 135 pPrinter->DrawText( aPos, rTitle ); 136 if ( nPages != 1 ) 137 { 138 aFont.SetWeight( WEIGHT_NORMAL ); 139 pPrinter->SetFont( aFont ); 140 aPos.AdjustX(pPrinter->GetTextWidth( rTitle ) ); 141 142 if( bOutput ) 143 { 144 OUString aPageStr = " [" + IDEResId(RID_STR_PAGE) + " " + OUString::number( nCurPage ) + "]"; 145 pPrinter->DrawText( aPos, aPageStr ); 146 } 147 } 148 149 nY = Print::nTopMargin - Print::nBorder; 150 151 if( bOutput ) 152 pPrinter->DrawLine( Point( nXLeft, nY ), Point( nXRight, nY ) ); 153 154 pPrinter->SetFont( aOldFont ); 155 pPrinter->SetFillColor( aOldFillColor ); 156 pPrinter->SetLineColor( aOldLineColor ); 157 } 158 159 void lcl_ConvertTabsToSpaces( OUString& rLine ) 160 { 161 if ( !rLine.isEmpty() ) 162 { 163 OUStringBuffer aResult( rLine ); 164 sal_Int32 nPos = 0; 165 sal_Int32 nMax = aResult.getLength(); 166 while ( nPos < nMax ) 167 { 168 if ( aResult[nPos] == '\t' ) 169 { 170 // not 4 Blanks, but at 4 TabPos: 171 OUStringBuffer aBlanker; 172 string::padToLength(aBlanker, ( 4 - ( nPos % 4 ) ), ' '); 173 aResult.remove( nPos, 1 ); 174 aResult.insert( nPos, aBlanker.makeStringAndClear() ); 175 nMax = aResult.getLength(); 176 } 177 ++nPos; 178 } 179 rLine = aResult.makeStringAndClear(); 180 } 181 } 182 183 } // namespace 184 185 ModulWindow::ModulWindow (ModulWindowLayout* pParent, ScriptDocument const& rDocument, 186 const OUString& aLibName, const OUString& aName, OUString const & aModule) 187 : BaseWindow(pParent, rDocument, aLibName, aName) 188 , m_rLayout(*pParent) 189 , m_nValid(ValidWindow) 190 , m_aXEditorWindow(VclPtr<ComplexEditorWindow>::Create(this)) 191 , m_aModule(aModule) 192 { 193 m_aXEditorWindow->Show(); 194 SetBackground(); 195 } 196 197 SbModuleRef const & ModulWindow::XModule() 198 { 199 // ModuleWindows can now be created as a result of the 200 // modules getting created via the api. This is a result of an 201 // elementInserted event from the BasicLibrary container. 202 // However the SbModule is also created from a different listener to 203 // the same event ( in basmgr ) Therefore it is possible when we look 204 // for m_xModule it may not yet be available, here we keep trying to access 205 // the module until such time as it exists 206 207 if ( !m_xModule.is() ) 208 { 209 BasicManager* pBasMgr = GetDocument().getBasicManager(); 210 if ( pBasMgr ) 211 { 212 StarBASIC* pBasic = pBasMgr->GetLib( GetLibName() ); 213 if ( pBasic ) 214 { 215 m_xBasic = pBasic; 216 m_xModule = pBasic->FindModule( GetName() ); 217 } 218 } 219 } 220 return m_xModule; 221 } 222 223 ModulWindow::~ModulWindow() 224 { 225 disposeOnce(); 226 } 227 228 void ModulWindow::dispose() 229 { 230 m_nValid = 0; 231 StarBASIC::Stop(); 232 m_aXEditorWindow.disposeAndClear(); 233 BaseWindow::dispose(); 234 } 235 236 237 void ModulWindow::GetFocus() 238 { 239 if (m_nValid != ValidWindow) 240 return; 241 m_aXEditorWindow->GetEdtWindow().GrabFocus(); 242 // don't call basic calls because focus is somewhere else... 243 } 244 245 void ModulWindow::DoInit() 246 { 247 if (GetVScrollBar()) 248 GetVScrollBar()->Hide(); 249 GetHScrollBar()->Show(); 250 GetEditorWindow().InitScrollBars(); 251 } 252 253 void ModulWindow::Paint(vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle&) 254 { 255 } 256 257 void ModulWindow::Resize() 258 { 259 m_aXEditorWindow->SetPosSizePixel( Point( 0, 0 ), GetOutputSizePixel() ); 260 } 261 262 void ModulWindow::CheckCompileBasic() 263 { 264 if ( XModule().is() ) 265 { 266 // never compile while running! 267 bool const bRunning = StarBASIC::IsRunning(); 268 bool const bModified = ( !m_xModule->IsCompiled() || 269 ( GetEditEngine() && GetEditEngine()->IsModified() ) ); 270 271 if ( !bRunning && bModified ) 272 { 273 bool bDone = false; 274 275 GetShell()->GetViewFrame()->GetWindow().EnterWait(); 276 277 AssertValidEditEngine(); 278 GetEditorWindow().SetSourceInBasic(); 279 280 bool bWasModified = GetBasic()->IsModified(); 281 282 bDone = m_xModule->Compile(); 283 if ( !bWasModified ) 284 GetBasic()->SetModified(false); 285 286 if ( bDone ) 287 { 288 GetBreakPoints().SetBreakPointsInBasic( m_xModule.get() ); 289 } 290 291 GetShell()->GetViewFrame()->GetWindow().LeaveWait(); 292 293 m_aStatus.bError = !bDone; 294 m_aStatus.bIsRunning = false; 295 } 296 } 297 } 298 299 void ModulWindow::BasicExecute() 300 { 301 // #116444# check security settings before macro execution 302 ScriptDocument aDocument( GetDocument() ); 303 if ( aDocument.isDocument() ) 304 { 305 if ( !aDocument.allowMacros() ) 306 { 307 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), 308 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTRUNMACRO))); 309 xBox->run(); 310 return; 311 } 312 } 313 314 CheckCompileBasic(); 315 316 if ( XModule().is() && m_xModule->IsCompiled() && !m_aStatus.bError ) 317 { 318 if ( GetBreakPoints().size() ) 319 m_aStatus.nBasicFlags = m_aStatus.nBasicFlags | BasicDebugFlags::Break; 320 321 if ( !m_aStatus.bIsRunning ) 322 { 323 DBG_ASSERT( m_xModule.is(), "No Module!" ); 324 AddStatus( BASWIN_RUNNINGBASIC ); 325 sal_uInt16 nStart, nEnd; 326 TextSelection aSel = GetEditView()->GetSelection(); 327 // Init cursor to top 328 const sal_uInt32 nCurMethodStart = aSel.GetStart().GetPara() + 1; 329 SbMethod* pMethod = nullptr; 330 // first Macro, else blind "Main" (ExtSearch?) 331 for ( sal_uInt16 nMacro = 0; nMacro < m_xModule->GetMethods()->Count(); nMacro++ ) 332 { 333 SbMethod* pM = static_cast<SbMethod*>(m_xModule->GetMethods()->Get( nMacro )); 334 assert(pM && "Method?"); 335 pM->GetLineRange( nStart, nEnd ); 336 if ( nCurMethodStart >= nStart && nCurMethodStart <= nEnd ) 337 { 338 // matched a method to the cursor position 339 pMethod = pM; 340 break; 341 } 342 } 343 if ( !pMethod ) 344 { 345 // If not in a method then prompt the user 346 ChooseMacro(GetFrameWeld(), uno::Reference<frame::XModel>()); 347 return; 348 } 349 pMethod->SetDebugFlags(m_aStatus.nBasicFlags); 350 BasicDLL::SetDebugMode(true); 351 RunMethod(pMethod); 352 BasicDLL::SetDebugMode(false); 353 // if cancelled during Interactive=false 354 BasicDLL::EnableBreak(true); 355 ClearStatus( BASWIN_RUNNINGBASIC ); 356 } 357 else 358 m_aStatus.bIsRunning = false; // cancel of Reschedule() 359 } 360 } 361 362 void ModulWindow::CompileBasic() 363 { 364 CheckCompileBasic(); 365 366 XModule().is() && m_xModule->IsCompiled(); 367 } 368 369 void ModulWindow::BasicRun() 370 { 371 m_aStatus.nBasicFlags = BasicDebugFlags::NONE; 372 BasicExecute(); 373 } 374 375 void ModulWindow::BasicStepOver() 376 { 377 m_aStatus.nBasicFlags = BasicDebugFlags::StepInto | BasicDebugFlags::StepOver; 378 BasicExecute(); 379 } 380 381 382 void ModulWindow::BasicStepInto() 383 { 384 m_aStatus.nBasicFlags = BasicDebugFlags::StepInto; 385 BasicExecute(); 386 } 387 388 void ModulWindow::BasicStepOut() 389 { 390 m_aStatus.nBasicFlags = BasicDebugFlags::StepOut; 391 BasicExecute(); 392 } 393 394 395 void ModulWindow::BasicStop() 396 { 397 StarBASIC::Stop(); 398 m_aStatus.bIsRunning = false; 399 } 400 401 void ModulWindow::LoadBasic() 402 { 403 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); 404 Reference < XFilePicker3 > xFP = FilePicker::createWithMode(xContext, TemplateDescription::FILEOPEN_SIMPLE); 405 406 if ( !m_sCurPath.isEmpty() ) 407 xFP->setDisplayDirectory ( m_sCurPath ); 408 409 xFP->appendFilter( "BASIC" , "*.bas" ); 410 xFP->appendFilter( IDEResId(RID_STR_FILTER_ALLFILES), FilterMask_All ); 411 xFP->setCurrentFilter( "BASIC" ); 412 413 if( xFP->execute() == RET_OK ) 414 { 415 Sequence< OUString > aPaths = xFP->getSelectedFiles(); 416 m_sCurPath = aPaths[0]; 417 SfxMedium aMedium( m_sCurPath, StreamMode::READ | StreamMode::SHARE_DENYWRITE | StreamMode::NOCREATE ); 418 SvStream* pStream = aMedium.GetInStream(); 419 if ( pStream ) 420 { 421 AssertValidEditEngine(); 422 sal_uInt32 nLines = CalcLineCount( *pStream ); 423 // nLines*4: ReadText/Formatting/Highlighting/Formatting 424 GetEditorWindow().CreateProgress( IDEResId(RID_STR_GENERATESOURCE), nLines*4 ); 425 GetEditEngine()->SetUpdateMode( false ); 426 GetEditView()->Read( *pStream ); 427 GetEditEngine()->SetUpdateMode( true ); 428 GetEditorWindow().Update(); 429 GetEditorWindow().ForceSyntaxTimeout(); 430 GetEditorWindow().DestroyProgress(); 431 ErrCode nError = aMedium.GetError(); 432 if ( nError ) 433 ErrorHandler::HandleError( nError ); 434 } 435 else 436 { 437 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), 438 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_COULDNTREAD))); 439 xBox->run(); 440 } 441 } 442 } 443 444 445 void ModulWindow::SaveBasicSource() 446 { 447 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); 448 Reference < XFilePicker3 > xFP = FilePicker::createWithMode(xContext, TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD); 449 450 Reference< XFilePickerControlAccess > xFPControl(xFP, UNO_QUERY); 451 xFPControl->enableControl(ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, false); 452 Any aValue; 453 aValue <<= true; 454 xFPControl->setValue(ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue); 455 456 if ( !m_sCurPath.isEmpty() ) 457 xFP->setDisplayDirectory ( m_sCurPath ); 458 459 xFP->appendFilter( "BASIC", "*.bas" ); 460 xFP->appendFilter( IDEResId(RID_STR_FILTER_ALLFILES), FilterMask_All ); 461 xFP->setCurrentFilter( "BASIC" ); 462 463 if( xFP->execute() == RET_OK ) 464 { 465 Sequence< OUString > aPaths = xFP->getSelectedFiles(); 466 m_sCurPath = aPaths[0]; 467 SfxMedium aMedium( m_sCurPath, StreamMode::WRITE | StreamMode::SHARE_DENYWRITE | StreamMode::TRUNC ); 468 SvStream* pStream = aMedium.GetOutStream(); 469 if ( pStream ) 470 { 471 EnterWait(); 472 AssertValidEditEngine(); 473 GetEditEngine()->Write( *pStream ); 474 aMedium.Commit(); 475 LeaveWait(); 476 ErrCode nError = aMedium.GetError(); 477 if ( nError ) 478 ErrorHandler::HandleError( nError ); 479 } 480 else 481 { 482 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(), 483 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_COULDNTWRITE))); 484 xErrorBox->run(); 485 } 486 } 487 } 488 489 void ModulWindow::ImportDialog() 490 { 491 const ScriptDocument& rDocument = GetDocument(); 492 OUString aLibName = GetLibName(); 493 implImportDialog(GetFrameWeld(), m_sCurPath, rDocument, aLibName); 494 } 495 496 void ModulWindow::ToggleBreakPoint( sal_uLong nLine ) 497 { 498 DBG_ASSERT( XModule().is(), "No Module!" ); 499 500 if ( XModule().is() ) 501 { 502 CheckCompileBasic(); 503 if ( m_aStatus.bError ) 504 { 505 return; 506 } 507 508 BreakPoint* pBrk = GetBreakPoints().FindBreakPoint( nLine ); 509 if ( pBrk ) // remove 510 { 511 m_xModule->ClearBP( static_cast<sal_uInt16>(nLine) ); 512 GetBreakPoints().remove( pBrk ); 513 } 514 else // create one 515 { 516 if ( m_xModule->SetBP( static_cast<sal_uInt16>(nLine)) ) 517 { 518 GetBreakPoints().InsertSorted( BreakPoint( nLine ) ); 519 if ( StarBASIC::IsRunning() ) 520 { 521 for ( sal_uInt16 nMethod = 0; nMethod < m_xModule->GetMethods()->Count(); nMethod++ ) 522 { 523 SbMethod* pMethod = static_cast<SbMethod*>(m_xModule->GetMethods()->Get( nMethod )); 524 assert(pMethod && "Method not found! (NULL)"); 525 pMethod->SetDebugFlags( pMethod->GetDebugFlags() | BasicDebugFlags::Break ); 526 } 527 } 528 } 529 } 530 } 531 } 532 533 void ModulWindow::UpdateBreakPoint( const BreakPoint& rBrk ) 534 { 535 DBG_ASSERT( XModule().is(), "No Module!" ); 536 537 if ( XModule().is() ) 538 { 539 CheckCompileBasic(); 540 541 if ( rBrk.bEnabled ) 542 m_xModule->SetBP( rBrk.nLine ); 543 else 544 m_xModule->ClearBP( rBrk.nLine ); 545 } 546 } 547 548 549 void ModulWindow::BasicToggleBreakPoint() 550 { 551 AssertValidEditEngine(); 552 553 TextSelection aSel = GetEditView()->GetSelection(); 554 aSel.GetStart().GetPara()++; // Basic lines start at 1! 555 aSel.GetEnd().GetPara()++; 556 557 for ( sal_uInt32 nLine = aSel.GetStart().GetPara(); nLine <= aSel.GetEnd().GetPara(); ++nLine ) 558 { 559 ToggleBreakPoint( nLine ); 560 } 561 562 m_aXEditorWindow->GetBrkWindow().Invalidate(); 563 } 564 565 566 void ModulWindow::BasicToggleBreakPointEnabled() 567 { 568 AssertValidEditEngine(); 569 570 TextView* pView = GetEditView(); 571 if ( pView ) 572 { 573 TextSelection aSel = pView->GetSelection(); 574 BreakPointList& rList = GetBreakPoints(); 575 576 for ( sal_uInt32 nLine = ++aSel.GetStart().GetPara(), nEnd = ++aSel.GetEnd().GetPara(); nLine <= nEnd; ++nLine ) 577 { 578 BreakPoint* pBrk = rList.FindBreakPoint( nLine ); 579 if ( pBrk ) 580 { 581 pBrk->bEnabled = !pBrk->bEnabled; 582 UpdateBreakPoint( *pBrk ); 583 } 584 } 585 586 GetBreakPointWindow().Invalidate(); 587 } 588 } 589 590 void ModulWindow::ManageBreakPoints() 591 { 592 BreakPointWindow& rBrkWin = GetBreakPointWindow(); 593 BreakPointDialog aBrkDlg(rBrkWin.GetFrameWeld(), GetBreakPoints()); 594 aBrkDlg.run(); 595 rBrkWin.Invalidate(); 596 } 597 598 void ModulWindow::BasicErrorHdl( StarBASIC const * pBasic ) 599 { 600 GetShell()->GetViewFrame()->ToTop(); 601 602 // Return value: BOOL 603 // FALSE: cancel 604 // TRUE: go on.... 605 sal_uInt16 nErrorLine = StarBASIC::GetLine() - 1; 606 sal_uInt16 nErrCol1 = StarBASIC::GetCol1(); 607 sal_uInt16 nErrCol2 = StarBASIC::GetCol2(); 608 if ( nErrCol2 != 0xFFFF ) 609 nErrCol2++; 610 611 AssertValidEditEngine(); 612 GetEditView()->SetSelection( TextSelection( TextPaM( nErrorLine, nErrCol1 ), TextPaM( nErrorLine, nErrCol2 ) ) ); 613 614 // if other basic, the IDE should try to display the correct module 615 bool const bMarkError = pBasic == GetBasic(); 616 if ( bMarkError ) 617 m_aXEditorWindow->GetBrkWindow().SetMarkerPos(nErrorLine, true); 618 619 // #i47002# 620 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( this ); 621 622 // tdf#118572 make a currently running dialog, regardless of what its modal 623 // to, insensitive to user input until after this error dialog goes away. 624 auto xDialog = Dialog::GetMostRecentExecutingDialog(); 625 const bool bToggleEnableInput = xDialog && xDialog->IsInputEnabled(); 626 if (bToggleEnableInput) 627 xDialog->EnableInput(false); 628 ErrorHandler::HandleError(StarBASIC::GetErrorCode(), GetFrameWeld()); 629 if (bToggleEnableInput) 630 xDialog->EnableInput(true); 631 632 // #i47002# 633 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); 634 if ( !pWindow ) 635 return; 636 637 if ( bMarkError ) 638 m_aXEditorWindow->GetBrkWindow().SetNoMarker(); 639 return; 640 } 641 642 BasicDebugFlags ModulWindow::BasicBreakHdl() 643 { 644 // Return value: sal_uInt16 => see SB-Debug-Flags 645 sal_uInt16 nErrorLine = StarBASIC::GetLine(); 646 647 648 BreakPoint* pBrk = GetBreakPoints().FindBreakPoint( nErrorLine ); 649 if ( pBrk ) 650 { 651 pBrk->nHitCount++; 652 if ( pBrk->nHitCount <= pBrk->nStopAfter && GetBasic()->IsBreak() ) 653 return m_aStatus.nBasicFlags; // go on... 654 } 655 656 nErrorLine--; // EditEngine starts at 0, Basic at 1 657 658 AssertValidEditEngine(); 659 GetEditView()->SetSelection( TextSelection( TextPaM( nErrorLine, 0 ), TextPaM( nErrorLine, 0 ) ) ); 660 m_aXEditorWindow->GetBrkWindow().SetMarkerPos( nErrorLine ); 661 662 m_rLayout.UpdateDebug(false); 663 664 m_aStatus.bIsInReschedule = true; 665 m_aStatus.bIsRunning = true; 666 667 AddStatus( BASWIN_INRESCHEDULE ); 668 669 InvalidateDebuggerSlots(); 670 671 while( m_aStatus.bIsRunning ) 672 Application::Yield(); 673 674 m_aStatus.bIsInReschedule = false; 675 m_aXEditorWindow->GetBrkWindow().SetNoMarker(); 676 677 ClearStatus( BASWIN_INRESCHEDULE ); 678 679 return m_aStatus.nBasicFlags; 680 } 681 682 void ModulWindow::BasicAddWatch() 683 { 684 AssertValidEditEngine(); 685 bool bAdd = true; 686 if ( !GetEditView()->HasSelection() ) 687 { 688 TextPaM aWordStart; 689 OUString aWord = GetEditEngine()->GetWord( GetEditView()->GetSelection().GetEnd(), &aWordStart ); 690 if ( !aWord.isEmpty() ) 691 { 692 TextSelection aSel( aWordStart ); 693 aSel.GetEnd().GetIndex() += aWord.getLength(); 694 GetEditView()->SetSelection( aSel ); 695 } 696 else 697 bAdd = false; 698 } 699 if ( bAdd ) 700 { 701 TextSelection aSel = GetEditView()->GetSelection(); 702 if ( aSel.GetStart().GetPara() == aSel.GetEnd().GetPara() ) // single line selection 703 m_rLayout.BasicAddWatch(GetEditView()->GetSelected()); 704 } 705 } 706 707 708 void ModulWindow::EditMacro( const OUString& rMacroName ) 709 { 710 DBG_ASSERT( XModule().is(), "No Module!" ); 711 712 if ( XModule().is() ) 713 { 714 CheckCompileBasic(); 715 716 if ( !m_aStatus.bError ) 717 { 718 sal_uInt16 nStart, nEnd; 719 SbMethod* pMethod = static_cast<SbMethod*>(m_xModule->Find( rMacroName, SbxClassType::Method )); 720 if ( pMethod ) 721 { 722 pMethod->GetLineRange( nStart, nEnd ); 723 if ( nStart ) 724 { 725 nStart--; 726 nEnd--; 727 } 728 TextSelection aSel( TextPaM( nStart, 0 ), TextPaM( nStart, 0 ) ); 729 AssertValidEditEngine(); 730 TextView * pView = GetEditView(); 731 // scroll if applicable so that first line is at the top 732 long nVisHeight = GetOutputSizePixel().Height(); 733 if ( pView->GetTextEngine()->GetTextHeight() > nVisHeight ) 734 { 735 long nMaxY = pView->GetTextEngine()->GetTextHeight() - nVisHeight; 736 long nOldStartY = pView->GetStartDocPos().Y(); 737 long nNewStartY = static_cast<long>(nStart) * pView->GetTextEngine()->GetCharHeight(); 738 nNewStartY = std::min( nNewStartY, nMaxY ); 739 pView->Scroll( 0, -(nNewStartY-nOldStartY) ); 740 pView->ShowCursor( false ); 741 GetEditVScrollBar().SetThumbPos( pView->GetStartDocPos().Y() ); 742 } 743 pView->SetSelection( aSel ); 744 pView->ShowCursor(); 745 pView->GetWindow()->GrabFocus(); 746 } 747 } 748 } 749 } 750 751 void ModulWindow::StoreData() 752 { 753 // StoreData is called when the BasicManager is destroyed or 754 // this window is closed. 755 // => interrupts undesired! 756 GetEditorWindow().SetSourceInBasic(); 757 } 758 759 bool ModulWindow::CanClose() 760 { 761 return true; 762 } 763 764 bool ModulWindow::AllowUndo() 765 { 766 return GetEditorWindow().CanModify(); 767 } 768 769 void ModulWindow::UpdateData() 770 { 771 DBG_ASSERT( XModule().is(), "No Module!" ); 772 // UpdateData is called when the source has changed from outside 773 // => interrupts undesired! 774 775 if ( XModule().is() ) 776 { 777 SetModule( m_xModule->GetSource32() ); 778 779 if ( GetEditView() ) 780 { 781 TextSelection aSel = GetEditView()->GetSelection(); 782 setTextEngineText(*GetEditEngine(), m_xModule->GetSource32()); 783 GetEditView()->SetSelection( aSel ); 784 GetEditEngine()->SetModified( false ); 785 MarkDocumentModified( GetDocument() ); 786 } 787 } 788 } 789 790 sal_Int32 ModulWindow::countPages( Printer* pPrinter ) 791 { 792 return FormatAndPrint( pPrinter, -1 ); 793 } 794 795 void ModulWindow::printPage( sal_Int32 nPage, Printer* pPrinter ) 796 { 797 FormatAndPrint( pPrinter, nPage ); 798 } 799 800 /* implementation note: this is totally inefficient for the XRenderable interface 801 usage since the whole "document" will be format for every page. Should this ever 802 become a problem we should 803 - format only once for every new printer 804 - keep an index list for each page which is the starting paragraph 805 */ 806 sal_Int32 ModulWindow::FormatAndPrint( Printer* pPrinter, sal_Int32 nPrintPage ) 807 { 808 AssertValidEditEngine(); 809 810 MapMode eOldMapMode( pPrinter->GetMapMode() ); 811 vcl::Font aOldFont( pPrinter->GetFont() ); 812 813 vcl::Font aFont( GetEditEngine()->GetFont() ); 814 aFont.SetAlignment( ALIGN_BOTTOM ); 815 aFont.SetTransparent( true ); 816 aFont.SetFontSize( Size( 0, 360 ) ); 817 pPrinter->SetFont( aFont ); 818 pPrinter->SetMapMode(MapMode(MapUnit::Map100thMM)); 819 820 OUString aTitle( CreateQualifiedName() ); 821 822 sal_Int32 nLineHeight = pPrinter->GetTextHeight(); 823 if(nLineHeight == 0) 824 { 825 nLineHeight = 1; 826 } 827 828 Size aPaperSz = pPrinter->GetOutputSize(); 829 aPaperSz.AdjustWidth( -(Print::nLeftMargin + Print::nRightMargin) ); 830 aPaperSz.AdjustHeight( -(Print::nTopMargin + Print::nBottomMargin) ); 831 832 // nLinepPage is not correct if there's a line break 833 sal_Int32 nLinespPage = aPaperSz.Height()/nLineHeight; 834 long nXTextWidth = pPrinter->approximate_char_width(); 835 836 sal_Int32 nCharspLine = aPaperSz.Width() / std::max<long>(nXTextWidth, 1); 837 const sal_uInt32 nParas = GetEditEngine()->GetParagraphCount(); 838 839 sal_Int32 nPages = nParas/nLinespPage+1; 840 sal_Int32 nCurPage = 1; 841 842 lcl_PrintHeader( pPrinter, nPages, nCurPage, aTitle, nPrintPage == 0 ); 843 Point aPos( Print::nLeftMargin, Print::nTopMargin ); 844 for ( sal_uInt32 nPara = 0; nPara < nParas; ++nPara ) 845 { 846 OUString aLine( GetEditEngine()->GetText( nPara ) ); 847 lcl_ConvertTabsToSpaces( aLine ); 848 sal_Int32 nLines = aLine.getLength()/nCharspLine+1; 849 for (sal_Int32 nLine = 0; nLine < nLines; ++nLine) 850 { 851 sal_Int32 nBeginIndex = nLine*nCharspLine; 852 sal_Int32 nCopyCount = std::min<sal_Int32>(nCharspLine, aLine.getLength()-nBeginIndex); 853 OUString aTmpLine = aLine.copy(nBeginIndex, nCopyCount); 854 aPos.AdjustY(nLineHeight ); 855 if ( aPos.Y() > ( aPaperSz.Height() + Print::nTopMargin ) ) 856 { 857 nCurPage++; 858 lcl_PrintHeader( pPrinter, nPages, nCurPage, aTitle, nCurPage-1 == nPrintPage ); 859 aPos = Point(Print::nLeftMargin, Print::nTopMargin + nLineHeight); 860 } 861 if( nCurPage-1 == nPrintPage ) 862 pPrinter->DrawText( aPos, aTmpLine ); 863 } 864 aPos.AdjustY(10 ); // nParaSpace 865 } 866 867 pPrinter->SetFont( aOldFont ); 868 pPrinter->SetMapMode( eOldMapMode ); 869 870 return nCurPage; 871 } 872 873 void ModulWindow::ExecuteCommand (SfxRequest& rReq) 874 { 875 AssertValidEditEngine(); 876 switch (rReq.GetSlot()) 877 { 878 case SID_DELETE: 879 { 880 if (!IsReadOnly()) 881 { 882 KeyEvent aFakeDelete(0, KEY_DELETE); 883 (void)GetEditView()->KeyInput(aFakeDelete); 884 } 885 break; 886 } 887 case SID_SELECTALL: 888 { 889 TextSelection aSel( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ); 890 TextView * pView = GetEditView(); 891 pView->SetSelection( aSel ); 892 pView->GetWindow()->GrabFocus(); 893 break; 894 } 895 case SID_BASICRUN: 896 { 897 BasicRun(); 898 } 899 break; 900 case SID_BASICCOMPILE: 901 { 902 CompileBasic(); 903 } 904 break; 905 case SID_BASICSTEPOVER: 906 { 907 BasicStepOver(); 908 } 909 break; 910 case SID_BASICSTEPINTO: 911 { 912 BasicStepInto(); 913 } 914 break; 915 case SID_BASICSTEPOUT: 916 { 917 BasicStepOut(); 918 } 919 break; 920 case SID_BASICLOAD: 921 { 922 LoadBasic(); 923 } 924 break; 925 case SID_BASICSAVEAS: 926 { 927 SaveBasicSource(); 928 } 929 break; 930 case SID_IMPORT_DIALOG: 931 { 932 ImportDialog(); 933 } 934 break; 935 case SID_BASICIDE_MATCHGROUP: 936 { 937 GetEditView()->MatchGroup(); 938 } 939 break; 940 case SID_BASICIDE_TOGGLEBRKPNT: 941 { 942 BasicToggleBreakPoint(); 943 } 944 break; 945 case SID_BASICIDE_MANAGEBRKPNTS: 946 { 947 ManageBreakPoints(); 948 } 949 break; 950 case SID_BASICIDE_TOGGLEBRKPNTENABLED: 951 { 952 BasicToggleBreakPointEnabled(); 953 } 954 break; 955 case SID_BASICIDE_ADDWATCH: 956 { 957 BasicAddWatch(); 958 } 959 break; 960 case SID_BASICIDE_REMOVEWATCH: 961 { 962 m_rLayout.BasicRemoveWatch(); 963 } 964 break; 965 case SID_CUT: 966 { 967 if ( !IsReadOnly() ) 968 { 969 GetEditView()->Cut(); 970 if (SfxBindings* pBindings = GetBindingsPtr()) 971 pBindings->Invalidate( SID_DOC_MODIFIED ); 972 } 973 } 974 break; 975 case SID_COPY: 976 { 977 GetEditView()->Copy(); 978 } 979 break; 980 case SID_PASTE: 981 { 982 if ( !IsReadOnly() ) 983 { 984 GetEditView()->Paste(); 985 if (SfxBindings* pBindings = GetBindingsPtr()) 986 pBindings->Invalidate( SID_DOC_MODIFIED ); 987 } 988 } 989 break; 990 case SID_BASICIDE_BRKPNTSCHANGED: 991 { 992 GetBreakPointWindow().Invalidate(); 993 } 994 break; 995 case SID_SHOWLINES: 996 { 997 const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(rReq.GetSlot()); 998 bool bLineNumbers = pItem && pItem->GetValue(); 999 m_aXEditorWindow->SetLineNumberDisplay(bLineNumbers); 1000 1001 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); 1002 officecfg::Office::BasicIDE::EditorSettings::LineNumbering::set(bLineNumbers, batch); 1003 batch->commit(); 1004 } 1005 break; 1006 case SID_BASICIDE_DELETECURRENT: 1007 { 1008 if (QueryDelModule(m_aName, GetFrameWeld())) 1009 if (m_aDocument.removeModule(m_aLibName, m_aName)) 1010 MarkDocumentModified(m_aDocument); 1011 } 1012 break; 1013 case FID_SEARCH_OFF: 1014 GrabFocus(); 1015 break; 1016 case SID_GOTOLINE: 1017 { 1018 GotoLineDialog aGotoDlg(GetFrameWeld()); 1019 if (aGotoDlg.run() == RET_OK) 1020 { 1021 if (sal_Int32 const nLine = aGotoDlg.GetLineNumber()) 1022 { 1023 TextSelection const aSel(TextPaM(nLine - 1, 0), TextPaM(nLine - 1, 0)); 1024 GetEditView()->SetSelection(aSel); 1025 } 1026 } 1027 break; 1028 } 1029 } 1030 } 1031 1032 void ModulWindow::ExecuteGlobal (SfxRequest& rReq) 1033 { 1034 switch (rReq.GetSlot()) 1035 { 1036 case SID_SIGNATURE: 1037 { 1038 DocumentSignature aSignature(m_aDocument); 1039 if (aSignature.supportsSignatures()) 1040 { 1041 aSignature.signScriptingContent(rReq.GetFrameWeld()); 1042 if (SfxBindings* pBindings = GetBindingsPtr()) 1043 pBindings->Invalidate(SID_SIGNATURE); 1044 } 1045 } 1046 break; 1047 } 1048 } 1049 1050 1051 void ModulWindow::GetState( SfxItemSet &rSet ) 1052 { 1053 SfxWhichIter aIter(rSet); 1054 for ( sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich() ) 1055 { 1056 switch ( nWh ) 1057 { 1058 case SID_CUT: 1059 { 1060 if ( !GetEditView() || !GetEditView()->HasSelection() ) 1061 rSet.DisableItem( nWh ); 1062 1063 if ( IsReadOnly() ) 1064 rSet.DisableItem( nWh ); 1065 } 1066 break; 1067 case SID_COPY: 1068 { 1069 if ( !GetEditView() || !GetEditView()->HasSelection() ) 1070 rSet.DisableItem( nWh ); 1071 } 1072 break; 1073 case SID_PASTE: 1074 { 1075 if ( !IsPasteAllowed() ) 1076 rSet.DisableItem( nWh ); 1077 1078 if ( IsReadOnly() ) 1079 rSet.DisableItem( nWh ); 1080 } 1081 break; 1082 case SID_BASICIDE_STAT_POS: 1083 { 1084 TextView* pView = GetEditView(); 1085 if ( pView ) 1086 { 1087 TextSelection aSel = pView->GetSelection(); 1088 OUString aPos = IDEResId( RID_STR_LINE ) + 1089 " " + 1090 OUString::number(aSel.GetEnd().GetPara()+1) + 1091 ", " + 1092 IDEResId( RID_STR_COLUMN ) + 1093 " " + 1094 OUString::number(aSel.GetEnd().GetIndex()+1); 1095 SfxStringItem aItem( SID_BASICIDE_STAT_POS, aPos ); 1096 rSet.Put( aItem ); 1097 } 1098 } 1099 break; 1100 case SID_BASICIDE_STAT_TITLE: 1101 { 1102 // search for current procedure name (Sub or Function) 1103 TextView* pView = GetEditView(); 1104 if ( pView ) 1105 { 1106 OUString sProcName; 1107 1108 TextSelection aSel = pView->GetSelection(); 1109 1110 sal_uInt32 i = aSel.GetStart().GetPara(); 1111 do 1112 { 1113 OUString aCurrLine = GetEditEngine()->GetText( i ); 1114 OUString sProcType; 1115 if (GetEditorWindow().GetProcedureName(aCurrLine, sProcType, sProcName)) 1116 break; 1117 } while (i--); 1118 1119 OUString aTitle = CreateQualifiedName(); 1120 if (!sProcName.isEmpty()) 1121 aTitle += "." + sProcName; 1122 1123 SfxStringItem aTitleItem( SID_BASICIDE_STAT_TITLE, aTitle ); 1124 rSet.Put( aTitleItem ); 1125 } 1126 } 1127 break; 1128 case SID_ATTR_INSERT: 1129 { 1130 TextView* pView = GetEditView(); 1131 if ( pView ) 1132 { 1133 SfxBoolItem aItem( SID_ATTR_INSERT, pView->IsInsertMode() ); 1134 rSet.Put( aItem ); 1135 } 1136 } 1137 break; 1138 case SID_SHOWLINES: 1139 { 1140 bool bLineNumbers = ::officecfg::Office::BasicIDE::EditorSettings::LineNumbering::get(); 1141 rSet.Put(SfxBoolItem(nWh, bLineNumbers)); 1142 break; 1143 } 1144 case SID_SELECTALL: 1145 { 1146 if ( !GetEditView() ) 1147 rSet.DisableItem( nWh ); 1148 } 1149 break; 1150 } 1151 } 1152 } 1153 1154 void ModulWindow::DoScroll( ScrollBar* pCurScrollBar ) 1155 { 1156 if ( ( pCurScrollBar == GetHScrollBar() ) && GetEditView() ) 1157 { 1158 // don't scroll with the value but rather use the Thumb-Pos for the VisArea: 1159 long nDiff = GetEditView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos(); 1160 GetEditView()->Scroll( nDiff, 0 ); 1161 GetEditView()->ShowCursor( false ); 1162 pCurScrollBar->SetThumbPos( GetEditView()->GetStartDocPos().X() ); 1163 1164 } 1165 } 1166 1167 bool ModulWindow::IsModified() 1168 { 1169 return GetEditEngine() && GetEditEngine()->IsModified(); 1170 } 1171 1172 OUString ModulWindow::GetSbModuleName() 1173 { 1174 OUString aModuleName; 1175 if ( XModule().is() ) 1176 aModuleName = m_xModule->GetName(); 1177 return aModuleName; 1178 } 1179 1180 OUString ModulWindow::GetTitle() 1181 { 1182 return GetSbModuleName(); 1183 } 1184 1185 void ModulWindow::ShowCursor( bool bOn ) 1186 { 1187 if ( GetEditEngine() ) 1188 { 1189 TextView* pView = GetEditEngine()->GetActiveView(); 1190 if ( pView ) 1191 { 1192 if ( bOn ) 1193 pView->ShowCursor(); 1194 else 1195 pView->HideCursor(); 1196 } 1197 } 1198 } 1199 1200 void ModulWindow::AssertValidEditEngine() 1201 { 1202 if ( !GetEditEngine() ) 1203 GetEditorWindow().CreateEditEngine(); 1204 } 1205 1206 void ModulWindow::Activating () 1207 { 1208 bool bLineNumbers = ::officecfg::Office::BasicIDE::EditorSettings::LineNumbering::get(); 1209 m_aXEditorWindow->SetLineNumberDisplay(bLineNumbers); 1210 Show(); 1211 } 1212 1213 void ModulWindow::Deactivating() 1214 { 1215 Hide(); 1216 } 1217 1218 sal_uInt16 ModulWindow::StartSearchAndReplace( const SvxSearchItem& rSearchItem, bool bFromStart ) 1219 { 1220 if (IsSuspended()) 1221 return 0; 1222 1223 // one could also relinquish syntaxhighlighting/formatting instead of the stupid replace-everything... 1224 AssertValidEditEngine(); 1225 TextView* pView = GetEditView(); 1226 TextSelection aSel; 1227 if ( bFromStart ) 1228 { 1229 aSel = pView->GetSelection(); 1230 if ( !rSearchItem.GetBackward() ) 1231 pView->SetSelection( TextSelection() ); 1232 else 1233 pView->SetSelection( TextSelection( TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ) ); 1234 } 1235 1236 bool const bForward = !rSearchItem.GetBackward(); 1237 sal_uInt16 nFound = 0; 1238 if ( ( rSearchItem.GetCommand() == SvxSearchCmd::FIND ) || 1239 ( rSearchItem.GetCommand() == SvxSearchCmd::FIND_ALL ) ) 1240 { 1241 nFound = pView->Search( rSearchItem.GetSearchOptions() , bForward ) ? 1 : 0; 1242 } 1243 else if ( ( rSearchItem.GetCommand() == SvxSearchCmd::REPLACE ) || 1244 ( rSearchItem.GetCommand() == SvxSearchCmd::REPLACE_ALL ) ) 1245 { 1246 if ( !IsReadOnly() ) 1247 { 1248 bool const bAll = rSearchItem.GetCommand() == SvxSearchCmd::REPLACE_ALL; 1249 nFound = pView->Replace( rSearchItem.GetSearchOptions() , bAll , bForward ); 1250 } 1251 } 1252 1253 if ( bFromStart && !nFound ) 1254 pView->SetSelection( aSel ); 1255 1256 return nFound; 1257 } 1258 1259 SfxUndoManager* ModulWindow::GetUndoManager() 1260 { 1261 if ( GetEditEngine() ) 1262 return &GetEditEngine()->GetUndoManager(); 1263 return nullptr; 1264 } 1265 1266 SearchOptionFlags ModulWindow::GetSearchOptions() 1267 { 1268 SearchOptionFlags nOptions = SearchOptionFlags::SEARCH | 1269 SearchOptionFlags::WHOLE_WORDS | 1270 SearchOptionFlags::BACKWARDS | 1271 SearchOptionFlags::REG_EXP | 1272 SearchOptionFlags::EXACT | 1273 SearchOptionFlags::SELECTION | 1274 SearchOptionFlags::SIMILARITY; 1275 1276 if ( !IsReadOnly() ) 1277 { 1278 nOptions |= SearchOptionFlags::REPLACE; 1279 nOptions |= SearchOptionFlags::REPLACE_ALL; 1280 } 1281 1282 return nOptions; 1283 } 1284 1285 void ModulWindow::BasicStarted() 1286 { 1287 if ( XModule().is() ) 1288 { 1289 m_aStatus.bIsRunning = true; 1290 BreakPointList& rList = GetBreakPoints(); 1291 if ( rList.size() ) 1292 { 1293 rList.ResetHitCount(); 1294 rList.SetBreakPointsInBasic( m_xModule.get() ); 1295 for ( sal_uInt16 nMethod = 0; nMethod < m_xModule->GetMethods()->Count(); nMethod++ ) 1296 { 1297 SbMethod* pMethod = static_cast<SbMethod*>(m_xModule->GetMethods()->Get( nMethod )); 1298 assert(pMethod && "Method not found! (NULL)"); 1299 pMethod->SetDebugFlags( pMethod->GetDebugFlags() | BasicDebugFlags::Break ); 1300 } 1301 } 1302 } 1303 } 1304 1305 void ModulWindow::BasicStopped() 1306 { 1307 m_aStatus.bIsRunning = false; 1308 GetBreakPointWindow().SetNoMarker(); 1309 } 1310 1311 EntryDescriptor ModulWindow::CreateEntryDescriptor() 1312 { 1313 ScriptDocument aDocument( GetDocument() ); 1314 OUString aLibName( GetLibName() ); 1315 LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName ); 1316 OUString aModName( GetName() ); 1317 OUString aLibSubName; 1318 if( m_xBasic.is() && aDocument.isInVBAMode() && XModule().is() ) 1319 { 1320 switch( m_xModule->GetModuleType() ) 1321 { 1322 case script::ModuleType::DOCUMENT: 1323 { 1324 aLibSubName = IDEResId( RID_STR_DOCUMENT_OBJECTS ); 1325 uno::Reference< container::XNameContainer > xLib = aDocument.getOrCreateLibrary( E_SCRIPTS, aLibName ); 1326 if( xLib.is() ) 1327 { 1328 OUString sObjName; 1329 ModuleInfoHelper::getObjectName( xLib, aModName, sObjName ); 1330 if( !sObjName.isEmpty() ) 1331 { 1332 aModName += " (" + sObjName + ")"; 1333 } 1334 } 1335 break; 1336 } 1337 case script::ModuleType::FORM: 1338 aLibSubName = IDEResId( RID_STR_USERFORMS ); 1339 break; 1340 case script::ModuleType::NORMAL: 1341 aLibSubName = IDEResId( RID_STR_NORMAL_MODULES ); 1342 break; 1343 case script::ModuleType::CLASS: 1344 aLibSubName = IDEResId( RID_STR_CLASS_MODULES ); 1345 break; 1346 } 1347 } 1348 return EntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aModName, OBJ_TYPE_MODULE ); 1349 } 1350 1351 void ModulWindow::SetReadOnly (bool b) 1352 { 1353 if ( GetEditView() ) 1354 GetEditView()->SetReadOnly( b ); 1355 } 1356 1357 bool ModulWindow::IsReadOnly() 1358 { 1359 return GetEditView() && GetEditView()->IsReadOnly(); 1360 } 1361 1362 bool ModulWindow::IsPasteAllowed() 1363 { 1364 bool bPaste = false; 1365 1366 // get clipboard 1367 Reference< datatransfer::clipboard::XClipboard > xClipboard = GetClipboard(); 1368 if ( xClipboard.is() ) 1369 { 1370 1371 Reference< datatransfer::XTransferable > xTransf; 1372 { 1373 SolarMutexReleaser aReleaser; 1374 // get clipboard content 1375 xTransf = xClipboard->getContents(); 1376 } 1377 if ( xTransf.is() ) 1378 { 1379 datatransfer::DataFlavor aFlavor; 1380 SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor ); 1381 if ( xTransf->isDataFlavorSupported( aFlavor ) ) 1382 bPaste = true; 1383 } 1384 } 1385 1386 return bPaste; 1387 } 1388 1389 void ModulWindow::OnNewDocument () 1390 { 1391 bool bLineNumbers = ::officecfg::Office::BasicIDE::EditorSettings::LineNumbering::get(); 1392 m_aXEditorWindow->SetLineNumberDisplay(bLineNumbers); 1393 } 1394 1395 char const* ModulWindow::GetHid () const 1396 { 1397 return HID_BASICIDE_MODULWINDOW; 1398 } 1399 ItemType ModulWindow::GetType () const 1400 { 1401 return TYPE_MODULE; 1402 } 1403 1404 bool ModulWindow::HasActiveEditor () const 1405 { 1406 return !IsSuspended(); 1407 } 1408 1409 1410 void ModulWindow::UpdateModule () 1411 { 1412 OUString const aModule = getTextEngineText(*GetEditEngine()); 1413 1414 // update module in basic 1415 assert(m_xModule.is()); 1416 1417 // update module in module window 1418 SetModule(aModule); 1419 1420 // update module in library 1421 OSL_VERIFY(m_aDocument.updateModule(m_aLibName, m_aName, aModule)); 1422 1423 GetEditEngine()->SetModified(false); 1424 MarkDocumentModified(m_aDocument); 1425 } 1426 1427 ModulWindowLayout::ModulWindowLayout (vcl::Window* pParent, ObjectCatalog& rObjectCatalog_) : 1428 Layout(pParent), 1429 pChild(nullptr), 1430 aWatchWindow(VclPtr<WatchWindow>::Create(this)), 1431 aStackWindow(VclPtr<StackWindow>::Create(this)), 1432 rObjectCatalog(rObjectCatalog_) 1433 { } 1434 1435 ModulWindowLayout::~ModulWindowLayout() 1436 { 1437 disposeOnce(); 1438 } 1439 1440 void ModulWindowLayout::dispose() 1441 { 1442 aWatchWindow.disposeAndClear(); 1443 aStackWindow.disposeAndClear(); 1444 pChild.clear(); 1445 Layout::dispose(); 1446 } 1447 1448 void ModulWindowLayout::UpdateDebug (bool bBasicStopped) 1449 { 1450 aWatchWindow->UpdateWatches(bBasicStopped); 1451 aStackWindow->UpdateCalls(); 1452 } 1453 1454 void ModulWindowLayout::Paint (vcl::RenderContext& rRenderContext, tools::Rectangle const&) 1455 { 1456 rRenderContext.DrawText(Point(), IDEResId(RID_STR_NOMODULE)); 1457 } 1458 1459 void ModulWindowLayout::Activating (BaseWindow& rChild) 1460 { 1461 assert(dynamic_cast<ModulWindow*>(&rChild)); 1462 pChild = &static_cast<ModulWindow&>(rChild); 1463 aWatchWindow->Show(); 1464 aStackWindow->Show(); 1465 rObjectCatalog.Show(); 1466 rObjectCatalog.SetLayoutWindow(this); 1467 rObjectCatalog.UpdateEntries(); 1468 Layout::Activating(rChild); 1469 aSyntaxColors.SetActiveEditor(&pChild->GetEditorWindow()); 1470 } 1471 1472 void ModulWindowLayout::Deactivating () 1473 { 1474 aSyntaxColors.SetActiveEditor(nullptr); 1475 Layout::Deactivating(); 1476 aWatchWindow->Hide(); 1477 aStackWindow->Hide(); 1478 rObjectCatalog.Hide(); 1479 pChild = nullptr; 1480 } 1481 1482 void ModulWindowLayout::GetState (SfxItemSet &rSet, unsigned nWhich) 1483 { 1484 switch (nWhich) 1485 { 1486 case SID_SHOW_PROPERTYBROWSER: 1487 rSet.Put(SfxVisibilityItem(nWhich, false)); 1488 break; 1489 1490 case SID_BASICIDE_CHOOSEMACRO: 1491 rSet.Put(SfxVisibilityItem(nWhich, true)); 1492 break; 1493 } 1494 } 1495 1496 void ModulWindowLayout::BasicAddWatch (OUString const& rWatchStr) 1497 { 1498 aWatchWindow->AddWatch(rWatchStr); 1499 } 1500 1501 void ModulWindowLayout::BasicRemoveWatch () 1502 { 1503 aWatchWindow->RemoveSelectedWatch(); 1504 } 1505 1506 void ModulWindowLayout::OnFirstSize (long const nWidth, long const nHeight) 1507 { 1508 AddToLeft(&rObjectCatalog, Size(nWidth * 0.20, nHeight * 0.75)); 1509 AddToBottom(aWatchWindow.get(), Size(nWidth * 0.67, nHeight * 0.25)); 1510 AddToBottom(aStackWindow.get(), Size(nWidth * 0.33, nHeight * 0.25)); 1511 } 1512 1513 ModulWindowLayout::SyntaxColors::SyntaxColors () : 1514 pEditor(nullptr) 1515 { 1516 aConfig.AddListener(this); 1517 1518 NewConfig(true); 1519 } 1520 1521 ModulWindowLayout::SyntaxColors::~SyntaxColors () 1522 { 1523 aConfig.RemoveListener(this); 1524 } 1525 1526 // virtual 1527 void ModulWindowLayout::SyntaxColors::ConfigurationChanged (utl::ConfigurationBroadcaster*, ConfigurationHints) 1528 { 1529 NewConfig(false); 1530 } 1531 1532 // when a new configuration has to be set 1533 void ModulWindowLayout::SyntaxColors::NewConfig (bool bFirst) 1534 { 1535 static struct 1536 { 1537 TokenType eTokenType; 1538 svtools::ColorConfigEntry eEntry; 1539 } 1540 const vIds[] = 1541 { 1542 { TokenType::Unknown, svtools::FONTCOLOR }, 1543 { TokenType::Identifier, svtools::BASICIDENTIFIER }, 1544 { TokenType::Whitespace, svtools::FONTCOLOR }, 1545 { TokenType::Number, svtools::BASICNUMBER }, 1546 { TokenType::String, svtools::BASICSTRING }, 1547 { TokenType::EOL, svtools::FONTCOLOR }, 1548 { TokenType::Comment, svtools::BASICCOMMENT }, 1549 { TokenType::Error, svtools::BASICERROR }, 1550 { TokenType::Operator, svtools::BASICOPERATOR }, 1551 { TokenType::Keywords, svtools::BASICKEYWORD }, 1552 }; 1553 1554 Color aDocColor = aConfig.GetColorValue(svtools::DOCCOLOR).nColor; 1555 if (bFirst || aDocColor != m_aBackgroundColor) 1556 { 1557 m_aBackgroundColor = aDocColor; 1558 if (!bFirst && pEditor) 1559 { 1560 pEditor->SetBackground(Wallpaper(m_aBackgroundColor)); 1561 pEditor->Invalidate(); 1562 } 1563 } 1564 1565 Color aFontColor = aConfig.GetColorValue(svtools::FONTCOLOR).nColor; 1566 if (bFirst || aFontColor != m_aFontColor) 1567 { 1568 m_aFontColor = aFontColor; 1569 if (!bFirst && pEditor) 1570 pEditor->ChangeFontColor(m_aFontColor); 1571 } 1572 1573 bool bChanged = false; 1574 for (unsigned i = 0; i != SAL_N_ELEMENTS(vIds); ++i) 1575 { 1576 Color const aColor = aConfig.GetColorValue(vIds[i].eEntry).nColor; 1577 Color& rMyColor = aColors[vIds[i].eTokenType]; 1578 if (bFirst || aColor != rMyColor) 1579 { 1580 rMyColor = aColor; 1581 bChanged = true; 1582 } 1583 } 1584 if (bChanged && !bFirst && pEditor) 1585 pEditor->UpdateSyntaxHighlighting(); 1586 } 1587 1588 } // namespace basctl 1589 1590 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1591
