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