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