Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / basctl / source / basicide / baside2.cxx
blob08ee292a6d943c36404d1fb09ab77118bf6271d3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
28 #include <helpids.h>
29 #include <strings.hrc>
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 <sfx2/dinfdlg.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/docfile.hxx>
43 #include <sfx2/printer.hxx>
44 #include <sfx2/request.hxx>
45 #include <sot/exchange.hxx>
46 #include <svl/aeitem.hxx>
47 #include <svl/srchitem.hxx>
48 #include <svl/visitem.hxx>
49 #include <svl/whiter.hxx>
50 #include <svx/svxids.hrc>
51 #include <vcl/settings.hxx>
52 #include <vcl/weld.hxx>
53 #include <vcl/xtextedt.hxx>
54 #include <toolkit/helper/vclunohelper.hxx>
55 #include <cassert>
57 namespace basctl
60 namespace
63 namespace Print
65 long const nLeftMargin = 1700;
66 long const nRightMargin = 900;
67 long const nTopMargin = 2000;
68 long const nBottomMargin = 1000;
69 long const nBorder = 300;
72 short const ValidWindow = 0x1234;
74 // What (who) are OW and MTF? Compare to baside3.cxx where an
75 // identically named variable, used in the same way, has the value
76 // "*.*" on Windows, "*" otherwise. Is that what should be done here,
77 // too?
79 #if defined(OW) || defined(MTF)
80 char const FilterMask_All[] = "*";
81 #else
82 char const FilterMask_All[] = "*.*";
83 #endif
85 } // end anonymous namespace
87 using namespace ::com::sun::star;
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::ui::dialogs;
90 using namespace utl;
91 using namespace comphelper;
93 namespace
96 void lcl_PrintHeader( Printer* pPrinter, sal_uInt16 nPages, sal_uInt16 nCurPage, const OUString& rTitle, bool bOutput )
98 Size const aSz = pPrinter->GetOutputSize();
100 const Color aOldLineColor( pPrinter->GetLineColor() );
101 const Color aOldFillColor( pPrinter->GetFillColor() );
102 const vcl::Font aOldFont( pPrinter->GetFont() );
104 pPrinter->SetLineColor( COL_BLACK );
105 pPrinter->SetFillColor();
107 vcl::Font aFont( aOldFont );
108 aFont.SetWeight( WEIGHT_BOLD );
109 aFont.SetAlignment( ALIGN_BOTTOM );
110 pPrinter->SetFont( aFont );
112 long nFontHeight = pPrinter->GetTextHeight();
114 // 1st Border => line, 2+3 Border = free space
115 long nYTop = Print::nTopMargin - 3*Print::nBorder - nFontHeight;
117 long nXLeft = Print::nLeftMargin - Print::nBorder;
118 long nXRight = aSz.Width() - Print::nRightMargin + Print::nBorder;
120 if( bOutput )
121 pPrinter->DrawRect(tools::Rectangle(
122 Point(nXLeft, nYTop),
123 Size(nXRight - nXLeft, aSz.Height() - nYTop - Print::nBottomMargin + Print::nBorder)
127 long nY = Print::nTopMargin - 2*Print::nBorder;
128 Point aPos(Print::nLeftMargin, nY);
129 if( bOutput )
130 pPrinter->DrawText( aPos, rTitle );
131 if ( nPages != 1 )
133 aFont.SetWeight( WEIGHT_NORMAL );
134 pPrinter->SetFont( aFont );
135 aPos.AdjustX(pPrinter->GetTextWidth( rTitle ) );
137 if( bOutput )
139 OUString aPageStr = " [" + IDEResId(RID_STR_PAGE) + " " + OUString::number( nCurPage ) + "]";
140 pPrinter->DrawText( aPos, aPageStr );
144 nY = Print::nTopMargin - Print::nBorder;
146 if( bOutput )
147 pPrinter->DrawLine( Point( nXLeft, nY ), Point( nXRight, nY ) );
149 pPrinter->SetFont( aOldFont );
150 pPrinter->SetFillColor( aOldFillColor );
151 pPrinter->SetLineColor( aOldLineColor );
154 void lcl_ConvertTabsToSpaces( OUString& rLine )
156 if ( !rLine.isEmpty() )
158 OUStringBuffer aResult( rLine );
159 sal_Int32 nPos = 0;
160 sal_Int32 nMax = aResult.getLength();
161 while ( nPos < nMax )
163 if ( aResult[nPos] == '\t' )
165 // not 4 Blanks, but at 4 TabPos:
166 OUStringBuffer aBlanker;
167 string::padToLength(aBlanker, ( 4 - ( nPos % 4 ) ), ' ');
168 aResult.remove( nPos, 1 );
169 aResult.insert( nPos, aBlanker.makeStringAndClear() );
170 nMax = aResult.getLength();
172 ++nPos;
174 rLine = aResult.makeStringAndClear();
178 } // namespace
180 ModulWindow::ModulWindow (ModulWindowLayout* pParent, ScriptDocument const& rDocument,
181 const OUString& aLibName, const OUString& aName, OUString const & aModule)
182 : BaseWindow(pParent, rDocument, aLibName, aName)
183 , m_rLayout(*pParent)
184 , m_nValid(ValidWindow)
185 , m_aXEditorWindow(VclPtr<ComplexEditorWindow>::Create(this))
186 , m_aModule(aModule)
188 m_aXEditorWindow->Show();
189 SetBackground();
192 SbModuleRef const & ModulWindow::XModule()
194 // ModuleWindows can now be created as a result of the
195 // modules getting created via the api. This is a result of an
196 // elementInserted event from the BasicLibrary container.
197 // However the SbModule is also created from a different listener to
198 // the same event ( in basmgr ) Therefore it is possible when we look
199 // for m_xModule it may not yet be available, here we keep trying to access
200 // the module until such time as it exists
202 if ( !m_xModule.is() )
204 BasicManager* pBasMgr = GetDocument().getBasicManager();
205 if ( pBasMgr )
207 StarBASIC* pBasic = pBasMgr->GetLib( GetLibName() );
208 if ( pBasic )
210 m_xBasic = pBasic;
211 m_xModule = pBasic->FindModule( GetName() );
215 return m_xModule;
218 ModulWindow::~ModulWindow()
220 disposeOnce();
223 void ModulWindow::dispose()
225 m_nValid = 0;
226 StarBASIC::Stop();
227 m_aXEditorWindow.disposeAndClear();
228 BaseWindow::dispose();
232 void ModulWindow::GetFocus()
234 if (m_nValid != ValidWindow)
235 return;
236 m_aXEditorWindow->GetEdtWindow().GrabFocus();
237 // don't call basic calls because focus is somewhere else...
240 void ModulWindow::DoInit()
242 if (GetVScrollBar())
243 GetVScrollBar()->Hide();
244 GetHScrollBar()->Show();
245 GetEditorWindow().InitScrollBars();
248 void ModulWindow::Paint(vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle&)
252 void ModulWindow::Resize()
254 m_aXEditorWindow->SetPosSizePixel( Point( 0, 0 ), GetOutputSizePixel() );
257 void ModulWindow::CheckCompileBasic()
259 if ( XModule().is() )
261 // never compile while running!
262 bool const bRunning = StarBASIC::IsRunning();
263 bool const bModified = ( !m_xModule->IsCompiled() ||
264 ( GetEditEngine() && GetEditEngine()->IsModified() ) );
266 if ( !bRunning && bModified )
268 bool bDone = false;
270 GetShell()->GetViewFrame()->GetWindow().EnterWait();
272 if( bModified )
274 AssertValidEditEngine();
275 GetEditorWindow().SetSourceInBasic();
278 bool bWasModified = GetBasic()->IsModified();
280 bDone = m_xModule->Compile();
281 if ( !bWasModified )
282 GetBasic()->SetModified(false);
284 if ( bDone )
286 GetBreakPoints().SetBreakPointsInBasic( m_xModule.get() );
289 GetShell()->GetViewFrame()->GetWindow().LeaveWait();
291 m_aStatus.bError = !bDone;
292 m_aStatus.bIsRunning = false;
297 void ModulWindow::BasicExecute()
299 // #116444# check security settings before macro execution
300 ScriptDocument aDocument( GetDocument() );
301 if ( aDocument.isDocument() )
303 if ( !aDocument.allowMacros() )
305 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
306 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTRUNMACRO)));
307 xBox->run();
308 return;
312 CheckCompileBasic();
314 if ( XModule().is() && m_xModule->IsCompiled() && !m_aStatus.bError )
316 if ( GetBreakPoints().size() )
317 m_aStatus.nBasicFlags = m_aStatus.nBasicFlags | BasicDebugFlags::Break;
319 if ( !m_aStatus.bIsRunning )
321 DBG_ASSERT( m_xModule.is(), "No Module!" );
322 AddStatus( BASWIN_RUNNINGBASIC );
323 sal_uInt16 nStart, nEnd;
324 TextSelection aSel = GetEditView()->GetSelection();
325 // Init cursor to top
326 const sal_uInt32 nCurMethodStart = aSel.GetStart().GetPara() + 1;
327 SbMethod* pMethod = nullptr;
328 // first Macro, else blind "Main" (ExtSearch?)
329 for ( sal_uInt16 nMacro = 0; nMacro < m_xModule->GetMethods()->Count(); nMacro++ )
331 SbMethod* pM = static_cast<SbMethod*>(m_xModule->GetMethods()->Get( nMacro ));
332 assert(pM && "Method?");
333 pM->GetLineRange( nStart, nEnd );
334 if ( nCurMethodStart >= nStart && nCurMethodStart <= nEnd )
336 // matched a method to the cursor position
337 pMethod = pM;
338 break;
341 if ( !pMethod )
343 // If not in a method then prompt the user
344 ChooseMacro( uno::Reference< frame::XModel >() );
345 return;
347 if ( pMethod )
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 );
356 ClearStatus( BASWIN_RUNNINGBASIC );
358 else
359 m_aStatus.bIsRunning = false; // cancel of Reschedule()
363 void ModulWindow::CompileBasic()
365 CheckCompileBasic();
367 XModule().is() && m_xModule->IsCompiled();
370 void ModulWindow::BasicRun()
372 m_aStatus.nBasicFlags = BasicDebugFlags::NONE;
373 BasicExecute();
376 void ModulWindow::BasicStepOver()
378 m_aStatus.nBasicFlags = BasicDebugFlags::StepInto | BasicDebugFlags::StepOver;
379 BasicExecute();
383 void ModulWindow::BasicStepInto()
385 m_aStatus.nBasicFlags = BasicDebugFlags::StepInto;
386 BasicExecute();
389 void ModulWindow::BasicStepOut()
391 m_aStatus.nBasicFlags = BasicDebugFlags::StepOut;
392 BasicExecute();
396 void ModulWindow::BasicStop()
398 StarBASIC::Stop();
399 m_aStatus.bIsRunning = false;
402 void ModulWindow::LoadBasic()
404 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
405 Reference < XFilePicker3 > xFP = FilePicker::createWithMode(xContext, TemplateDescription::FILEOPEN_SIMPLE);
407 if ( !m_sCurPath.isEmpty() )
408 xFP->setDisplayDirectory ( m_sCurPath );
410 xFP->appendFilter( "BASIC" , "*.bas" );
411 xFP->appendFilter( IDEResId(RID_STR_FILTER_ALLFILES), FilterMask_All );
412 xFP->setCurrentFilter( "BASIC" );
414 if( xFP->execute() == RET_OK )
416 Sequence< OUString > aPaths = xFP->getSelectedFiles();
417 m_sCurPath = aPaths[0];
418 SfxMedium aMedium( m_sCurPath, StreamMode::READ | StreamMode::SHARE_DENYWRITE | StreamMode::NOCREATE );
419 SvStream* pStream = aMedium.GetInStream();
420 if ( pStream )
422 AssertValidEditEngine();
423 sal_uInt32 nLines = CalcLineCount( *pStream );
424 // nLines*4: ReadText/Formatting/Highlighting/Formatting
425 GetEditorWindow().CreateProgress( IDEResId(RID_STR_GENERATESOURCE), nLines*4 );
426 GetEditEngine()->SetUpdateMode( false );
427 GetEditView()->Read( *pStream );
428 GetEditEngine()->SetUpdateMode( true );
429 GetEditorWindow().Update();
430 GetEditorWindow().ForceSyntaxTimeout();
431 GetEditorWindow().DestroyProgress();
432 ErrCode nError = aMedium.GetError();
433 if ( nError )
434 ErrorHandler::HandleError( nError );
436 else
438 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
439 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_COULDNTREAD)));
440 xBox->run();
446 void ModulWindow::SaveBasicSource()
448 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
449 Reference < XFilePicker3 > xFP = FilePicker::createWithMode(xContext, TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD);
451 Reference< XFilePickerControlAccess > xFPControl(xFP, UNO_QUERY);
452 xFPControl->enableControl(ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, false);
453 Any aValue;
454 aValue <<= true;
455 xFPControl->setValue(ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue);
457 if ( !m_sCurPath.isEmpty() )
458 xFP->setDisplayDirectory ( m_sCurPath );
460 xFP->appendFilter( "BASIC", "*.bas" );
461 xFP->appendFilter( IDEResId(RID_STR_FILTER_ALLFILES), FilterMask_All );
462 xFP->setCurrentFilter( "BASIC" );
464 if( xFP->execute() == RET_OK )
466 Sequence< OUString > aPaths = xFP->getSelectedFiles();
467 m_sCurPath = aPaths[0];
468 SfxMedium aMedium( m_sCurPath, StreamMode::WRITE | StreamMode::SHARE_DENYWRITE | StreamMode::TRUNC );
469 SvStream* pStream = aMedium.GetOutStream();
470 if ( pStream )
472 EnterWait();
473 AssertValidEditEngine();
474 GetEditEngine()->Write( *pStream );
475 aMedium.Commit();
476 LeaveWait();
477 ErrCode nError = aMedium.GetError();
478 if ( nError )
479 ErrorHandler::HandleError( nError );
481 else
483 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
484 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_COULDNTWRITE)));
485 xErrorBox->run();
490 void ModulWindow::ImportDialog()
492 const ScriptDocument& rDocument = GetDocument();
493 OUString aLibName = GetLibName();
494 implImportDialog(GetFrameWeld(), m_sCurPath, rDocument, aLibName);
497 void ModulWindow::ToggleBreakPoint( sal_uLong nLine )
499 DBG_ASSERT( XModule().is(), "No Modul!" );
501 if ( XModule().is() )
503 CheckCompileBasic();
504 if ( m_aStatus.bError )
506 return;
509 BreakPoint* pBrk = GetBreakPoints().FindBreakPoint( nLine );
510 if ( pBrk ) // remove
512 m_xModule->ClearBP( static_cast<sal_uInt16>(nLine) );
513 delete GetBreakPoints().remove( pBrk );
515 else // create one
517 if ( m_xModule->SetBP( static_cast<sal_uInt16>(nLine)) )
519 GetBreakPoints().InsertSorted( new BreakPoint( nLine ) );
520 if ( StarBASIC::IsRunning() )
522 for ( sal_uInt16 nMethod = 0; nMethod < m_xModule->GetMethods()->Count(); nMethod++ )
524 SbMethod* pMethod = static_cast<SbMethod*>(m_xModule->GetMethods()->Get( nMethod ));
525 assert(pMethod && "Method not found! (NULL)");
526 pMethod->SetDebugFlags( pMethod->GetDebugFlags() | BasicDebugFlags::Break );
534 void ModulWindow::UpdateBreakPoint( const BreakPoint& rBrk )
536 DBG_ASSERT( XModule().is(), "No Module!" );
538 if ( XModule().is() )
540 CheckCompileBasic();
542 if ( rBrk.bEnabled )
543 m_xModule->SetBP( static_cast<sal_uInt16>(rBrk.nLine) );
544 else
545 m_xModule->ClearBP( static_cast<sal_uInt16>(rBrk.nLine) );
550 void ModulWindow::BasicToggleBreakPoint()
552 AssertValidEditEngine();
554 TextSelection aSel = GetEditView()->GetSelection();
555 aSel.GetStart().GetPara()++; // Basic lines start at 1!
556 aSel.GetEnd().GetPara()++;
558 for ( sal_uInt32 nLine = aSel.GetStart().GetPara(); nLine <= aSel.GetEnd().GetPara(); ++nLine )
560 ToggleBreakPoint( nLine );
563 m_aXEditorWindow->GetBrkWindow().Invalidate();
567 void ModulWindow::BasicToggleBreakPointEnabled()
569 AssertValidEditEngine();
571 TextView* pView = GetEditView();
572 if ( pView )
574 TextSelection aSel = pView->GetSelection();
575 BreakPointList& rList = GetBreakPoints();
577 for ( sal_uInt32 nLine = ++aSel.GetStart().GetPara(), nEnd = ++aSel.GetEnd().GetPara(); nLine <= nEnd; ++nLine )
579 BreakPoint* pBrk = rList.FindBreakPoint( nLine );
580 if ( pBrk )
582 pBrk->bEnabled = !pBrk->bEnabled;
583 UpdateBreakPoint( *pBrk );
587 GetBreakPointWindow().Invalidate();
592 void ModulWindow::ManageBreakPoints()
594 BreakPointWindow& rBrkWin = GetBreakPointWindow();
595 ScopedVclPtrInstance< BreakPointDialog > aBrkDlg( &rBrkWin, GetBreakPoints() );
596 aBrkDlg->Execute();
597 rBrkWin.Invalidate();
601 bool ModulWindow::BasicErrorHdl( StarBASIC const * pBasic )
603 GetShell()->GetViewFrame()->ToTop();
605 // Return value: BOOL
606 // FALSE: cancel
607 // TRUE: go on....
608 sal_uInt16 nErrorLine = StarBASIC::GetLine() - 1;
609 sal_uInt16 nErrCol1 = StarBASIC::GetCol1();
610 sal_uInt16 nErrCol2 = StarBASIC::GetCol2();
611 if ( nErrCol2 != 0xFFFF )
612 nErrCol2++;
614 AssertValidEditEngine();
615 GetEditView()->SetSelection( TextSelection( TextPaM( nErrorLine, nErrCol1 ), TextPaM( nErrorLine, nErrCol2 ) ) );
617 // if other basic, the IDE should try to display the correct module
618 bool const bMarkError = pBasic == GetBasic();
619 if ( bMarkError )
620 m_aXEditorWindow->GetBrkWindow().SetMarkerPos(nErrorLine, true);
622 // #i47002#
623 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( this );
625 ErrorHandler::HandleError( StarBASIC::GetErrorCode() );
627 // #i47002#
628 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
629 if ( !pWindow )
630 return false;
632 if ( bMarkError )
633 m_aXEditorWindow->GetBrkWindow().SetNoMarker();
634 return false;
637 BasicDebugFlags ModulWindow::BasicBreakHdl()
639 // Return value: sal_uInt16 => see SB-Debug-Flags
640 sal_uInt16 nErrorLine = StarBASIC::GetLine();
643 BreakPoint* pBrk = GetBreakPoints().FindBreakPoint( nErrorLine );
644 if ( pBrk )
646 pBrk->nHitCount++;
647 if ( pBrk->nHitCount <= pBrk->nStopAfter && GetBasic()->IsBreak() )
648 return m_aStatus.nBasicFlags; // go on...
651 nErrorLine--; // EditEngine starts at 0, Basic at 1
653 AssertValidEditEngine();
654 GetEditView()->SetSelection( TextSelection( TextPaM( nErrorLine, 0 ), TextPaM( nErrorLine, 0 ) ) );
655 m_aXEditorWindow->GetBrkWindow().SetMarkerPos( nErrorLine );
657 m_rLayout.UpdateDebug(false);
659 m_aStatus.bIsInReschedule = true;
660 m_aStatus.bIsRunning = true;
662 AddStatus( BASWIN_INRESCHEDULE );
664 InvalidateDebuggerSlots();
666 while( m_aStatus.bIsRunning )
667 Application::Yield();
669 m_aStatus.bIsInReschedule = false;
670 m_aXEditorWindow->GetBrkWindow().SetNoMarker();
672 ClearStatus( BASWIN_INRESCHEDULE );
674 return m_aStatus.nBasicFlags;
677 void ModulWindow::BasicAddWatch()
679 AssertValidEditEngine();
680 bool bAdd = true;
681 if ( !GetEditView()->HasSelection() )
683 TextPaM aWordStart;
684 OUString aWord = GetEditEngine()->GetWord( GetEditView()->GetSelection().GetEnd(), &aWordStart );
685 if ( !aWord.isEmpty() )
687 TextSelection aSel( aWordStart );
688 aSel.GetEnd().GetIndex() += aWord.getLength();
689 GetEditView()->SetSelection( aSel );
691 else
692 bAdd = false;
694 if ( bAdd )
696 TextSelection aSel = GetEditView()->GetSelection();
697 if ( aSel.GetStart().GetPara() == aSel.GetEnd().GetPara() ) // single line selection
698 m_rLayout.BasicAddWatch(GetEditView()->GetSelected());
703 void ModulWindow::EditMacro( const OUString& rMacroName )
705 DBG_ASSERT( XModule().is(), "No Module!" );
707 if ( XModule().is() )
709 CheckCompileBasic();
711 if ( !m_aStatus.bError )
713 sal_uInt16 nStart, nEnd;
714 SbMethod* pMethod = static_cast<SbMethod*>(m_xModule->Find( rMacroName, SbxClassType::Method ));
715 if ( pMethod )
717 pMethod->GetLineRange( nStart, nEnd );
718 if ( nStart )
720 nStart--;
721 nEnd--;
723 TextSelection aSel( TextPaM( nStart, 0 ), TextPaM( nStart, 0 ) );
724 AssertValidEditEngine();
725 TextView * pView = GetEditView();
726 // scroll if applicable so that first line is at the top
727 long nVisHeight = GetOutputSizePixel().Height();
728 if ( pView->GetTextEngine()->GetTextHeight() > nVisHeight )
730 long nMaxY = pView->GetTextEngine()->GetTextHeight() - nVisHeight;
731 long nOldStartY = pView->GetStartDocPos().Y();
732 long nNewStartY = static_cast<long>(nStart) * pView->GetTextEngine()->GetCharHeight();
733 nNewStartY = std::min( nNewStartY, nMaxY );
734 pView->Scroll( 0, -(nNewStartY-nOldStartY) );
735 pView->ShowCursor( false );
736 GetEditVScrollBar().SetThumbPos( pView->GetStartDocPos().Y() );
738 pView->SetSelection( aSel );
739 pView->ShowCursor();
740 pView->GetWindow()->GrabFocus();
746 void ModulWindow::StoreData()
748 // StoreData is called when the BasicManager is destroyed or
749 // this window is closed.
750 // => interrupts undesired!
751 GetEditorWindow().SetSourceInBasic();
754 bool ModulWindow::CanClose()
756 return true;
759 bool ModulWindow::AllowUndo()
761 return GetEditorWindow().CanModify();
764 void ModulWindow::UpdateData()
766 DBG_ASSERT( XModule().is(), "No Module!" );
767 // UpdateData is called when the source has changed from outside
768 // => interrupts undesired!
770 if ( XModule().is() )
772 SetModule( m_xModule->GetSource32() );
774 if ( GetEditView() )
776 TextSelection aSel = GetEditView()->GetSelection();
777 setTextEngineText(*GetEditEngine(), m_xModule->GetSource32());
778 GetEditView()->SetSelection( aSel );
779 GetEditEngine()->SetModified( false );
780 MarkDocumentModified( GetDocument() );
785 sal_Int32 ModulWindow::countPages( Printer* pPrinter )
787 return FormatAndPrint( pPrinter, -1 );
790 void ModulWindow::printPage( sal_Int32 nPage, Printer* pPrinter )
792 FormatAndPrint( pPrinter, nPage );
795 /* implementation note: this is totally inefficient for the XRenderable interface
796 usage since the whole "document" will be format for every page. Should this ever
797 become a problem we should
798 - format only once for every new printer
799 - keep an index list for each page which is the starting paragraph
801 sal_Int32 ModulWindow::FormatAndPrint( Printer* pPrinter, sal_Int32 nPrintPage )
803 AssertValidEditEngine();
805 MapMode eOldMapMode( pPrinter->GetMapMode() );
806 vcl::Font aOldFont( pPrinter->GetFont() );
808 vcl::Font aFont( GetEditEngine()->GetFont() );
809 aFont.SetAlignment( ALIGN_BOTTOM );
810 aFont.SetTransparent( true );
811 aFont.SetFontSize( Size( 0, 360 ) );
812 pPrinter->SetFont( aFont );
813 pPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
815 OUString aTitle( CreateQualifiedName() );
817 sal_Int32 nLineHeight = pPrinter->GetTextHeight();
818 if(nLineHeight == 0)
820 nLineHeight = 1;
823 Size aPaperSz = pPrinter->GetOutputSize();
824 aPaperSz.AdjustWidth( -(Print::nLeftMargin + Print::nRightMargin) );
825 aPaperSz.AdjustHeight( -(Print::nTopMargin + Print::nBottomMargin) );
827 // nLinepPage is not correct if there's a line break
828 sal_Int32 nLinespPage = aPaperSz.Height()/nLineHeight;
829 long nXTextWidth = pPrinter->approximate_char_width();
831 sal_Int32 nCharspLine = aPaperSz.Width() / std::max<long>(nXTextWidth, 1);
832 const sal_uInt32 nParas = GetEditEngine()->GetParagraphCount();
834 sal_Int32 nPages = nParas/nLinespPage+1;
835 sal_Int32 nCurPage = 1;
837 lcl_PrintHeader( pPrinter, nPages, nCurPage, aTitle, nPrintPage == 0 );
838 Point aPos( Print::nLeftMargin, Print::nTopMargin );
839 for ( sal_uInt32 nPara = 0; nPara < nParas; ++nPara )
841 OUString aLine( GetEditEngine()->GetText( nPara ) );
842 lcl_ConvertTabsToSpaces( aLine );
843 sal_Int32 nLines = aLine.getLength()/nCharspLine+1;
844 for (sal_Int32 nLine = 0; nLine < nLines; ++nLine)
846 sal_Int32 nBeginIndex = nLine*nCharspLine;
847 sal_Int32 nCopyCount = std::min<sal_Int32>(nCharspLine, aLine.getLength()-nBeginIndex);
848 OUString aTmpLine = aLine.copy(nBeginIndex, nCopyCount);
849 aPos.AdjustY(nLineHeight );
850 if ( aPos.Y() > ( aPaperSz.Height() + Print::nTopMargin ) )
852 nCurPage++;
853 lcl_PrintHeader( pPrinter, nPages, nCurPage, aTitle, nCurPage-1 == nPrintPage );
854 aPos = Point(Print::nLeftMargin, Print::nTopMargin + nLineHeight);
856 if( nCurPage-1 == nPrintPage )
857 pPrinter->DrawText( aPos, aTmpLine );
859 aPos.AdjustY(10 ); // nParaSpace
862 pPrinter->SetFont( aOldFont );
863 pPrinter->SetMapMode( eOldMapMode );
865 return nCurPage;
868 void ModulWindow::ExecuteCommand (SfxRequest& rReq)
870 AssertValidEditEngine();
871 switch (rReq.GetSlot())
873 case SID_DELETE:
875 if (!IsReadOnly())
877 KeyEvent aFakeDelete(0, KEY_DELETE);
878 (void)GetEditView()->KeyInput(aFakeDelete);
880 break;
882 case SID_SELECTALL:
884 TextSelection aSel( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) );
885 TextView * pView = GetEditView();
886 pView->SetSelection( aSel );
887 pView->GetWindow()->GrabFocus();
888 break;
890 case SID_BASICRUN:
892 BasicRun();
894 break;
895 case SID_BASICCOMPILE:
897 CompileBasic();
899 break;
900 case SID_BASICSTEPOVER:
902 BasicStepOver();
904 break;
905 case SID_BASICSTEPINTO:
907 BasicStepInto();
909 break;
910 case SID_BASICSTEPOUT:
912 BasicStepOut();
914 break;
915 case SID_BASICLOAD:
917 LoadBasic();
919 break;
920 case SID_BASICSAVEAS:
922 SaveBasicSource();
924 break;
925 case SID_IMPORT_DIALOG:
927 ImportDialog();
929 break;
930 case SID_BASICIDE_MATCHGROUP:
932 GetEditView()->MatchGroup();
934 break;
935 case SID_BASICIDE_TOGGLEBRKPNT:
937 BasicToggleBreakPoint();
939 break;
940 case SID_BASICIDE_MANAGEBRKPNTS:
942 ManageBreakPoints();
944 break;
945 case SID_BASICIDE_TOGGLEBRKPNTENABLED:
947 BasicToggleBreakPointEnabled();
949 break;
950 case SID_BASICIDE_ADDWATCH:
952 BasicAddWatch();
954 break;
955 case SID_BASICIDE_REMOVEWATCH:
957 m_rLayout.BasicRemoveWatch();
959 break;
960 case SID_CUT:
962 if ( !IsReadOnly() )
964 GetEditView()->Cut();
965 if (SfxBindings* pBindings = GetBindingsPtr())
966 pBindings->Invalidate( SID_DOC_MODIFIED );
969 break;
970 case SID_COPY:
972 GetEditView()->Copy();
974 break;
975 case SID_PASTE:
977 if ( !IsReadOnly() )
979 GetEditView()->Paste();
980 if (SfxBindings* pBindings = GetBindingsPtr())
981 pBindings->Invalidate( SID_DOC_MODIFIED );
984 break;
985 case SID_BASICIDE_BRKPNTSCHANGED:
987 GetBreakPointWindow().Invalidate();
989 break;
990 case SID_SHOWLINES:
992 const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(rReq.GetSlot());
993 bool bLineNumbers = pItem && pItem->GetValue();
994 m_aXEditorWindow->SetLineNumberDisplay(bLineNumbers);
996 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
997 officecfg::Office::BasicIDE::EditorSettings::LineNumbering::set(bLineNumbers, batch);
998 batch->commit();
1000 break;
1001 case SID_BASICIDE_DELETECURRENT:
1003 if (QueryDelModule(m_aName, GetFrameWeld()))
1004 if (m_aDocument.removeModule(m_aLibName, m_aName))
1005 MarkDocumentModified(m_aDocument);
1007 break;
1008 case FID_SEARCH_OFF:
1009 GrabFocus();
1010 break;
1011 case SID_GOTOLINE:
1013 GotoLineDialog aGotoDlg(GetFrameWeld());
1014 if (aGotoDlg.run() == RET_OK)
1016 if (sal_Int32 const nLine = aGotoDlg.GetLineNumber())
1018 TextSelection const aSel(TextPaM(nLine - 1, 0), TextPaM(nLine - 1, 0));
1019 GetEditView()->SetSelection(aSel);
1022 break;
1027 void ModulWindow::ExecuteGlobal (SfxRequest& rReq)
1029 switch (rReq.GetSlot())
1031 case SID_SIGNATURE:
1033 DocumentSignature aSignature(m_aDocument);
1034 if (aSignature.supportsSignatures())
1036 aSignature.signScriptingContent(rReq.GetFrameWeld());
1037 if (SfxBindings* pBindings = GetBindingsPtr())
1038 pBindings->Invalidate(SID_SIGNATURE);
1041 break;
1046 void ModulWindow::GetState( SfxItemSet &rSet )
1048 SfxWhichIter aIter(rSet);
1049 for ( sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich() )
1051 switch ( nWh )
1053 case SID_CUT:
1055 if ( !GetEditView() || !GetEditView()->HasSelection() )
1056 rSet.DisableItem( nWh );
1058 if ( IsReadOnly() )
1059 rSet.DisableItem( nWh );
1061 break;
1062 case SID_COPY:
1064 if ( !GetEditView() || !GetEditView()->HasSelection() )
1065 rSet.DisableItem( nWh );
1067 break;
1068 case SID_PASTE:
1070 if ( !IsPasteAllowed() )
1071 rSet.DisableItem( nWh );
1073 if ( IsReadOnly() )
1074 rSet.DisableItem( nWh );
1076 break;
1077 case SID_BASICIDE_STAT_POS:
1079 TextView* pView = GetEditView();
1080 if ( pView )
1082 TextSelection aSel = pView->GetSelection();
1083 OUString aPos = IDEResId( RID_STR_LINE ) +
1084 " " +
1085 OUString::number(aSel.GetEnd().GetPara()+1) +
1086 ", " +
1087 IDEResId( RID_STR_COLUMN ) +
1088 " " +
1089 OUString::number(aSel.GetEnd().GetIndex()+1);
1090 SfxStringItem aItem( SID_BASICIDE_STAT_POS, aPos );
1091 rSet.Put( aItem );
1094 break;
1095 case SID_BASICIDE_STAT_TITLE:
1097 // search for current procedure name (Sub or Function)
1098 TextView* pView = GetEditView();
1099 if ( pView )
1101 OUString sProcName;
1103 TextSelection aSel = pView->GetSelection();
1105 sal_uInt32 i = aSel.GetStart().GetPara();
1108 OUString aCurrLine = GetEditEngine()->GetText( i );
1109 OUString sProcType;
1110 if (GetEditorWindow().GetProcedureName(aCurrLine, sProcType, sProcName))
1111 break;
1112 } while (i--);
1114 OUString aTitle = CreateQualifiedName();
1115 if (!sProcName.isEmpty())
1116 aTitle += "." + sProcName;
1118 SfxStringItem aTitleItem( SID_BASICIDE_STAT_TITLE, aTitle );
1119 rSet.Put( aTitleItem );
1122 break;
1123 case SID_ATTR_INSERT:
1125 TextView* pView = GetEditView();
1126 if ( pView )
1128 SfxBoolItem aItem( SID_ATTR_INSERT, pView->IsInsertMode() );
1129 rSet.Put( aItem );
1132 break;
1133 case SID_SHOWLINES:
1135 bool bLineNumbers = ::officecfg::Office::BasicIDE::EditorSettings::LineNumbering::get();
1136 rSet.Put(SfxBoolItem(nWh, bLineNumbers));
1137 break;
1139 case SID_SELECTALL:
1141 if ( !GetEditView() )
1142 rSet.DisableItem( nWh );
1144 break;
1149 void ModulWindow::DoScroll( ScrollBar* pCurScrollBar )
1151 if ( ( pCurScrollBar == GetHScrollBar() ) && GetEditView() )
1153 // don't scroll with the value but rather use the Thumb-Pos for the VisArea:
1154 long nDiff = GetEditView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
1155 GetEditView()->Scroll( nDiff, 0 );
1156 GetEditView()->ShowCursor( false );
1157 pCurScrollBar->SetThumbPos( GetEditView()->GetStartDocPos().X() );
1162 bool ModulWindow::IsModified()
1164 return GetEditEngine() && GetEditEngine()->IsModified();
1167 OUString ModulWindow::GetSbModuleName()
1169 OUString aModuleName;
1170 if ( XModule().is() )
1171 aModuleName = m_xModule->GetName();
1172 return aModuleName;
1175 OUString ModulWindow::GetTitle()
1177 return GetSbModuleName();
1180 void ModulWindow::ShowCursor( bool bOn )
1182 if ( GetEditEngine() )
1184 TextView* pView = GetEditEngine()->GetActiveView();
1185 if ( pView )
1187 if ( bOn )
1188 pView->ShowCursor();
1189 else
1190 pView->HideCursor();
1195 void ModulWindow::AssertValidEditEngine()
1197 if ( !GetEditEngine() )
1198 GetEditorWindow().CreateEditEngine();
1201 void ModulWindow::Activating ()
1203 bool bLineNumbers = ::officecfg::Office::BasicIDE::EditorSettings::LineNumbering::get();
1204 m_aXEditorWindow->SetLineNumberDisplay(bLineNumbers);
1205 Show();
1208 void ModulWindow::Deactivating()
1210 Hide();
1213 sal_uInt16 ModulWindow::StartSearchAndReplace( const SvxSearchItem& rSearchItem, bool bFromStart )
1215 if (IsSuspended())
1216 return 0;
1218 // one could also relinquish syntaxhighlighting/formatting instead of the stupid replace-everything...
1219 AssertValidEditEngine();
1220 TextView* pView = GetEditView();
1221 TextSelection aSel;
1222 if ( bFromStart )
1224 aSel = pView->GetSelection();
1225 if ( !rSearchItem.GetBackward() )
1226 pView->SetSelection( TextSelection() );
1227 else
1228 pView->SetSelection( TextSelection( TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ) );
1231 bool const bForward = !rSearchItem.GetBackward();
1232 sal_uInt16 nFound = 0;
1233 if ( ( rSearchItem.GetCommand() == SvxSearchCmd::FIND ) ||
1234 ( rSearchItem.GetCommand() == SvxSearchCmd::FIND_ALL ) )
1236 nFound = pView->Search( rSearchItem.GetSearchOptions() , bForward ) ? 1 : 0;
1238 else if ( ( rSearchItem.GetCommand() == SvxSearchCmd::REPLACE ) ||
1239 ( rSearchItem.GetCommand() == SvxSearchCmd::REPLACE_ALL ) )
1241 if ( !IsReadOnly() )
1243 bool const bAll = rSearchItem.GetCommand() == SvxSearchCmd::REPLACE_ALL;
1244 nFound = pView->Replace( rSearchItem.GetSearchOptions() , bAll , bForward );
1248 if ( bFromStart && !nFound )
1249 pView->SetSelection( aSel );
1251 return nFound;
1254 svl::IUndoManager* ModulWindow::GetUndoManager()
1256 if ( GetEditEngine() )
1257 return &GetEditEngine()->GetUndoManager();
1258 return nullptr;
1261 SearchOptionFlags ModulWindow::GetSearchOptions()
1263 SearchOptionFlags nOptions = SearchOptionFlags::SEARCH |
1264 SearchOptionFlags::WHOLE_WORDS |
1265 SearchOptionFlags::BACKWARDS |
1266 SearchOptionFlags::REG_EXP |
1267 SearchOptionFlags::EXACT |
1268 SearchOptionFlags::SELECTION |
1269 SearchOptionFlags::SIMILARITY;
1271 if ( !IsReadOnly() )
1273 nOptions |= SearchOptionFlags::REPLACE;
1274 nOptions |= SearchOptionFlags::REPLACE_ALL;
1277 return nOptions;
1280 void ModulWindow::BasicStarted()
1282 if ( XModule().is() )
1284 m_aStatus.bIsRunning = true;
1285 BreakPointList& rList = GetBreakPoints();
1286 if ( rList.size() )
1288 rList.ResetHitCount();
1289 rList.SetBreakPointsInBasic( m_xModule.get() );
1290 for ( sal_uInt16 nMethod = 0; nMethod < m_xModule->GetMethods()->Count(); nMethod++ )
1292 SbMethod* pMethod = static_cast<SbMethod*>(m_xModule->GetMethods()->Get( nMethod ));
1293 assert(pMethod && "Method not found! (NULL)");
1294 pMethod->SetDebugFlags( pMethod->GetDebugFlags() | BasicDebugFlags::Break );
1300 void ModulWindow::BasicStopped()
1302 m_aStatus.bIsRunning = false;
1303 GetBreakPointWindow().SetNoMarker();
1306 EntryDescriptor ModulWindow::CreateEntryDescriptor()
1308 ScriptDocument aDocument( GetDocument() );
1309 OUString aLibName( GetLibName() );
1310 LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName );
1311 OUString aModName( GetName() );
1312 OUString aLibSubName;
1313 if( m_xBasic.is() && aDocument.isInVBAMode() && XModule().is() )
1315 switch( m_xModule->GetModuleType() )
1317 case script::ModuleType::DOCUMENT:
1319 aLibSubName = IDEResId( RID_STR_DOCUMENT_OBJECTS );
1320 uno::Reference< container::XNameContainer > xLib = aDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
1321 if( xLib.is() )
1323 OUString sObjName;
1324 ModuleInfoHelper::getObjectName( xLib, aModName, sObjName );
1325 if( !sObjName.isEmpty() )
1327 aModName += " (" + sObjName + ")";
1330 break;
1332 case script::ModuleType::FORM:
1333 aLibSubName = IDEResId( RID_STR_USERFORMS );
1334 break;
1335 case script::ModuleType::NORMAL:
1336 aLibSubName = IDEResId( RID_STR_NORMAL_MODULES );
1337 break;
1338 case script::ModuleType::CLASS:
1339 aLibSubName = IDEResId( RID_STR_CLASS_MODULES );
1340 break;
1343 return EntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aModName, OBJ_TYPE_MODULE );
1346 void ModulWindow::SetReadOnly (bool b)
1348 if ( GetEditView() )
1349 GetEditView()->SetReadOnly( b );
1352 bool ModulWindow::IsReadOnly()
1354 return GetEditView() && GetEditView()->IsReadOnly();
1357 bool ModulWindow::IsPasteAllowed()
1359 bool bPaste = false;
1361 // get clipboard
1362 Reference< datatransfer::clipboard::XClipboard > xClipboard = GetClipboard();
1363 if ( xClipboard.is() )
1366 Reference< datatransfer::XTransferable > xTransf;
1368 SolarMutexReleaser aReleaser;
1369 // get clipboard content
1370 xTransf = xClipboard->getContents();
1372 if ( xTransf.is() )
1374 datatransfer::DataFlavor aFlavor;
1375 SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
1376 if ( xTransf->isDataFlavorSupported( aFlavor ) )
1377 bPaste = true;
1381 return bPaste;
1384 void ModulWindow::OnNewDocument ()
1386 bool bLineNumbers = ::officecfg::Office::BasicIDE::EditorSettings::LineNumbering::get();
1387 m_aXEditorWindow->SetLineNumberDisplay(bLineNumbers);
1390 char const* ModulWindow::GetHid () const
1392 return HID_BASICIDE_MODULWINDOW;
1394 ItemType ModulWindow::GetType () const
1396 return TYPE_MODULE;
1399 bool ModulWindow::HasActiveEditor () const
1401 return !IsSuspended();
1405 void ModulWindow::UpdateModule ()
1407 OUString const aModule = getTextEngineText(*GetEditEngine());
1409 // update module in basic
1410 assert(m_xModule.is());
1412 // update module in module window
1413 SetModule(aModule);
1415 // update module in library
1416 OSL_VERIFY(m_aDocument.updateModule(m_aLibName, m_aName, aModule));
1418 GetEditEngine()->SetModified(false);
1419 MarkDocumentModified(m_aDocument);
1422 ModulWindowLayout::ModulWindowLayout (vcl::Window* pParent, ObjectCatalog& rObjectCatalog_) :
1423 Layout(pParent),
1424 pChild(nullptr),
1425 aWatchWindow(VclPtr<WatchWindow>::Create(this)),
1426 aStackWindow(VclPtr<StackWindow>::Create(this)),
1427 rObjectCatalog(rObjectCatalog_)
1430 ModulWindowLayout::~ModulWindowLayout()
1432 disposeOnce();
1435 void ModulWindowLayout::dispose()
1437 aWatchWindow.disposeAndClear();
1438 aStackWindow.disposeAndClear();
1439 pChild.clear();
1440 Layout::dispose();
1443 void ModulWindowLayout::UpdateDebug (bool bBasicStopped)
1445 aWatchWindow->UpdateWatches(bBasicStopped);
1446 aStackWindow->UpdateCalls();
1449 void ModulWindowLayout::Paint (vcl::RenderContext& rRenderContext, tools::Rectangle const&)
1451 rRenderContext.DrawText(Point(), IDEResId(RID_STR_NOMODULE));
1454 void ModulWindowLayout::Activating (BaseWindow& rChild)
1456 assert(dynamic_cast<ModulWindow*>(&rChild));
1457 pChild = &static_cast<ModulWindow&>(rChild);
1458 aWatchWindow->Show();
1459 aStackWindow->Show();
1460 rObjectCatalog.Show();
1461 rObjectCatalog.SetLayoutWindow(this);
1462 rObjectCatalog.UpdateEntries();
1463 Layout::Activating(rChild);
1464 aSyntaxColors.SetActiveEditor(&pChild->GetEditorWindow());
1467 void ModulWindowLayout::Deactivating ()
1469 aSyntaxColors.SetActiveEditor(nullptr);
1470 Layout::Deactivating();
1471 aWatchWindow->Hide();
1472 aStackWindow->Hide();
1473 rObjectCatalog.Hide();
1474 pChild = nullptr;
1477 void ModulWindowLayout::GetState (SfxItemSet &rSet, unsigned nWhich)
1479 switch (nWhich)
1481 case SID_SHOW_PROPERTYBROWSER:
1482 rSet.Put(SfxVisibilityItem(nWhich, false));
1483 break;
1485 case SID_BASICIDE_CHOOSEMACRO:
1486 rSet.Put(SfxVisibilityItem(nWhich, true));
1487 break;
1491 void ModulWindowLayout::BasicAddWatch (OUString const& rWatchStr)
1493 aWatchWindow->AddWatch(rWatchStr);
1496 void ModulWindowLayout::BasicRemoveWatch ()
1498 aWatchWindow->RemoveSelectedWatch();
1501 void ModulWindowLayout::OnFirstSize (long const nWidth, long const nHeight)
1503 AddToLeft(&rObjectCatalog, Size(nWidth * 0.20, nHeight * 0.75));
1504 AddToBottom(aWatchWindow.get(), Size(nWidth * 0.67, nHeight * 0.25));
1505 AddToBottom(aStackWindow.get(), Size(nWidth * 0.33, nHeight * 0.25));
1508 ModulWindowLayout::SyntaxColors::SyntaxColors () :
1509 pEditor(nullptr)
1511 aConfig.AddListener(this);
1513 NewConfig(true);
1516 ModulWindowLayout::SyntaxColors::~SyntaxColors ()
1518 aConfig.RemoveListener(this);
1521 // virtual
1522 void ModulWindowLayout::SyntaxColors::ConfigurationChanged (utl::ConfigurationBroadcaster*, ConfigurationHints)
1524 NewConfig(false);
1527 // when a new configuration has to be set
1528 void ModulWindowLayout::SyntaxColors::NewConfig (bool bFirst)
1530 static struct
1532 TokenType eTokenType;
1533 svtools::ColorConfigEntry eEntry;
1535 const vIds[] =
1537 { TokenType::Unknown, svtools::FONTCOLOR },
1538 { TokenType::Identifier, svtools::BASICIDENTIFIER },
1539 { TokenType::Whitespace, svtools::FONTCOLOR },
1540 { TokenType::Number, svtools::BASICNUMBER },
1541 { TokenType::String, svtools::BASICSTRING },
1542 { TokenType::EOL, svtools::FONTCOLOR },
1543 { TokenType::Comment, svtools::BASICCOMMENT },
1544 { TokenType::Error, svtools::BASICERROR },
1545 { TokenType::Operator, svtools::BASICOPERATOR },
1546 { TokenType::Keywords, svtools::BASICKEYWORD },
1549 Color aDocColor = aConfig.GetColorValue(svtools::DOCCOLOR).nColor;
1550 if (bFirst || aDocColor != m_aBackgroundColor)
1552 m_aBackgroundColor = aDocColor;
1553 if (!bFirst && pEditor)
1555 pEditor->SetBackground(Wallpaper(m_aBackgroundColor));
1556 pEditor->Invalidate();
1560 Color aFontColor = aConfig.GetColorValue(svtools::FONTCOLOR).nColor;
1561 if (bFirst || aFontColor != m_aFontColor)
1563 m_aFontColor = aFontColor;
1564 if (!bFirst && pEditor)
1565 pEditor->ChangeFontColor(m_aFontColor);
1568 bool bChanged = false;
1569 for (unsigned i = 0; i != SAL_N_ELEMENTS(vIds); ++i)
1571 Color const aColor = aConfig.GetColorValue(vIds[i].eEntry).nColor;
1572 Color& rMyColor = aColors[vIds[i].eTokenType];
1573 if (bFirst || aColor != rMyColor)
1575 rMyColor = aColor;
1576 bChanged = true;
1579 if (bChanged && !bFirst && pEditor)
1580 pEditor->UpdateSyntaxHighlighting();
1583 } // namespace basctl
1585 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */