1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
23 #include "iderdll.hxx"
24 #include "moduldlg.hxx"
25 #include "docsignature.hxx"
28 #include "baside2.hrc"
30 #include <basic/basmgr.hxx>
31 #include <basic/basrdll.hxx>
32 #include <basic/sbmeth.hxx>
33 #include <com/sun/star/script/ModuleType.hpp>
34 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
35 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
36 #include <com/sun/star/ui/dialogs/FilePicker.hpp>
37 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
38 #include <comphelper/string.hxx>
39 #include <sfx2/dinfdlg.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/docfile.hxx>
42 #include <sfx2/printer.hxx>
43 #include <sfx2/request.hxx>
44 #include <sot/exchange.hxx>
45 #include <svl/aeitem.hxx>
46 #include <svl/srchitem.hxx>
47 #include <svl/visitem.hxx>
48 #include <svl/whiter.hxx>
49 #include <vcl/xtextedt.hxx>
50 #include <vcl/settings.hxx>
51 #include <toolkit/helper/vclunohelper.hxx>
61 long const nLeftMargin
= 1700;
62 long const nRightMargin
= 900;
63 long const nTopMargin
= 2000;
64 long const nBottomMargin
= 1000;
65 long const nBorder
= 300;
68 short const ValidWindow
= 0x1234;
70 // What (who) are OW and MTF? Compare to baside3.cxx where an
71 // identically named variable, used in the same way, has the value
72 // "*.*" on Windows, "*" otherwise. Is that what should be done here,
75 #if defined(OW) || defined(MTF)
76 char const FilterMask_All
[] = "*";
78 char const FilterMask_All
[] = "*.*";
81 } // end anonymous namespace
83 using namespace ::com::sun::star
;
84 using namespace ::com::sun::star::uno
;
85 using namespace ::com::sun::star::ui::dialogs
;
87 using namespace comphelper
;
89 TYPEINIT1( ModulWindow
, BaseWindow
);
94 void lcl_PrintHeader( Printer
* pPrinter
, sal_uInt16 nPages
, sal_uInt16 nCurPage
, const OUString
& rTitle
, bool bOutput
)
96 Size
const aSz
= pPrinter
->GetOutputSize();
98 const Color
aOldLineColor( pPrinter
->GetLineColor() );
99 const Color
aOldFillColor( pPrinter
->GetFillColor() );
100 const vcl::Font
aOldFont( pPrinter
->GetFont() );
102 pPrinter
->SetLineColor( Color( COL_BLACK
) );
103 pPrinter
->SetFillColor();
105 vcl::Font
aFont( aOldFont
);
106 aFont
.SetWeight( WEIGHT_BOLD
);
107 aFont
.SetAlign( ALIGN_BOTTOM
);
108 pPrinter
->SetFont( aFont
);
110 long nFontHeight
= pPrinter
->GetTextHeight();
112 // 1st Border => line, 2+3 Border = free space
113 long nYTop
= Print::nTopMargin
- 3*Print::nBorder
- nFontHeight
;
115 long nXLeft
= Print::nLeftMargin
- Print::nBorder
;
116 long nXRight
= aSz
.Width() - Print::nRightMargin
+ Print::nBorder
;
119 pPrinter
->DrawRect(Rectangle(
120 Point(nXLeft
, nYTop
),
121 Size(nXRight
- nXLeft
, aSz
.Height() - nYTop
- Print::nBottomMargin
+ Print::nBorder
)
125 long nY
= Print::nTopMargin
- 2*Print::nBorder
;
126 Point
aPos(Print::nLeftMargin
, nY
);
128 pPrinter
->DrawText( aPos
, rTitle
);
131 aFont
.SetWeight( WEIGHT_NORMAL
);
132 pPrinter
->SetFont( aFont
);
133 aPos
.X() += pPrinter
->GetTextWidth( rTitle
);
137 OUString aPageStr
= " [" + IDE_RESSTR(RID_STR_PAGE
) + " " + OUString::number( nCurPage
) + "]";
138 pPrinter
->DrawText( aPos
, aPageStr
);
142 nY
= Print::nTopMargin
- Print::nBorder
;
145 pPrinter
->DrawLine( Point( nXLeft
, nY
), Point( nXRight
, nY
) );
147 pPrinter
->SetFont( aOldFont
);
148 pPrinter
->SetFillColor( aOldFillColor
);
149 pPrinter
->SetLineColor( aOldLineColor
);
152 void lcl_ConvertTabsToSpaces( OUString
& rLine
)
154 if ( !rLine
.isEmpty() )
156 OUStringBuffer
aResult( rLine
);
158 sal_Int32 nMax
= aResult
.getLength();
159 while ( nPos
< nMax
)
161 if ( aResult
[nPos
] == '\t' )
163 // not 4 Blanks, but at 4 TabPos:
164 OUStringBuffer aBlanker
;
165 string::padToLength(aBlanker
, ( 4 - ( nPos
% 4 ) ), ' ');
166 aResult
.remove( nPos
, 1 );
167 aResult
.insert( nPos
, aBlanker
.makeStringAndClear() );
168 nMax
= aResult
.getLength();
172 rLine
= aResult
.makeStringAndClear();
176 // until we have some configuration lets just keep
177 // persist this value for the process lifetime
178 bool bSourceLinesEnabled
= false;
182 ModulWindow::ModulWindow (ModulWindowLayout
* pParent
, ScriptDocument
const& rDocument
,
183 const OUString
& aLibName
, const OUString
& aName
, OUString
& aModule
)
184 : BaseWindow(pParent
, rDocument
, aLibName
, aName
)
186 , nValid(ValidWindow
)
187 , aXEditorWindow(VclPtr
<ComplexEditorWindow
>::Create(this))
190 aXEditorWindow
->Show();
194 SbModuleRef
ModulWindow::XModule()
196 // ModuleWindows can now be created as a result of the
197 // modules getting created via the api. This is a result of an
198 // elementInserted event from the BasicLibrary container.
199 // However the SbModule is also created from a different listener to
200 // the same event ( in basmgr ) Therefore it is possible when we look
201 // for xModule it may not yet be available, here we keep tring to access
202 // the module until such time as it exists
206 BasicManager
* pBasMgr
= GetDocument().getBasicManager();
209 StarBASIC
* pBasic
= pBasMgr
->GetLib( GetLibName() );
213 xModule
= pBasic
->FindModule( GetName() );
220 ModulWindow::~ModulWindow()
225 void ModulWindow::dispose()
229 aXEditorWindow
.disposeAndClear();
230 BaseWindow::dispose();
234 void ModulWindow::GetFocus()
236 if (nValid
!= ValidWindow
)
238 aXEditorWindow
->GetEdtWindow().GrabFocus();
239 // don't call basic calls because focus is somewhere else...
242 void ModulWindow::DoInit()
245 GetVScrollBar()->Hide();
246 GetHScrollBar()->Show();
247 GetEditorWindow().InitScrollBars();
250 void ModulWindow::Paint(vcl::RenderContext
& /*rRenderContext*/, const Rectangle
&)
254 void ModulWindow::Resize()
256 aXEditorWindow
->SetPosSizePixel( Point( 0, 0 ),
257 Size( GetOutputSizePixel() ) );
260 void ModulWindow::CheckCompileBasic()
262 if ( XModule().Is() )
264 // never compile while running!
265 bool const bRunning
= StarBASIC::IsRunning();
266 bool const bModified
= ( !xModule
->IsCompiled() ||
267 ( GetEditEngine() && GetEditEngine()->IsModified() ) );
269 if ( !bRunning
&& bModified
)
273 GetShell()->GetViewFrame()->GetWindow().EnterWait();
277 AssertValidEditEngine();
278 GetEditorWindow().SetSourceInBasic();
281 bool bWasModified
= GetBasic()->IsModified();
283 bDone
= StarBASIC::Compile( xModule
);
285 GetBasic()->SetModified(false);
289 GetBreakPoints().SetBreakPointsInBasic( xModule
);
292 GetShell()->GetViewFrame()->GetWindow().LeaveWait();
294 aStatus
.bError
= !bDone
;
295 aStatus
.bIsRunning
= false;
300 bool ModulWindow::BasicExecute()
302 // #116444# check security settings before macro execution
303 ScriptDocument
aDocument( GetDocument() );
304 if ( aDocument
.isDocument() )
306 if ( !aDocument
.allowMacros() )
308 ScopedVclPtrInstance
<MessageDialog
>::Create(this, IDE_RESSTR(RID_STR_CANNOTRUNMACRO
), VCL_MESSAGE_WARNING
)->Execute();
315 if ( XModule().Is() && xModule
->IsCompiled() && !aStatus
.bError
)
317 if ( GetBreakPoints().size() )
318 aStatus
.nBasicFlags
= aStatus
.nBasicFlags
| SbDEBUG_BREAK
;
320 if ( !aStatus
.bIsRunning
)
322 DBG_ASSERT( xModule
.Is(), "Kein Modul!" );
323 AddStatus( BASWIN_RUNNINGBASIC
);
324 sal_uInt16 nStart
, nEnd
, nCurMethodStart
= 0;
325 TextSelection aSel
= GetEditView()->GetSelection();
326 // Init cursor to top
327 nCurMethodStart
= ( aSel
.GetStart().GetPara() + 1 );
328 SbMethod
* pMethod
= 0;
329 // first Macro, else blind "Main" (ExtSearch?)
330 for ( sal_uInt16 nMacro
= 0; nMacro
< xModule
->GetMethods()->Count(); nMacro
++ )
332 SbMethod
* pM
= static_cast<SbMethod
*>(xModule
->GetMethods()->Get( nMacro
));
333 DBG_ASSERT( pM
, "Method?" );
334 pM
->GetLineRange( nStart
, nEnd
);
335 if ( nCurMethodStart
>= nStart
&& nCurMethodStart
<= nEnd
)
337 // matched a method to the cursor position
344 // If not in a method then prompt the user
345 return ( !ChooseMacro( uno::Reference
< frame::XModel
>(), false, OUString() ).isEmpty() );
349 pMethod
->SetDebugFlags( 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
);
359 aStatus
.bIsRunning
= false; // cancel of Reschedule()
362 bool bDone
= !aStatus
.bError
;
367 bool ModulWindow::CompileBasic()
371 return XModule().Is() && xModule
->IsCompiled();
374 bool ModulWindow::BasicRun()
376 aStatus
.nBasicFlags
= 0;
377 return BasicExecute();
380 bool ModulWindow::BasicStepOver()
382 aStatus
.nBasicFlags
= SbDEBUG_STEPINTO
| SbDEBUG_STEPOVER
;
383 return BasicExecute();
387 bool ModulWindow::BasicStepInto()
389 aStatus
.nBasicFlags
= SbDEBUG_STEPINTO
;
390 return BasicExecute();
393 bool ModulWindow::BasicStepOut()
395 aStatus
.nBasicFlags
= SbDEBUG_STEPOUT
;
396 return BasicExecute();
401 void ModulWindow::BasicStop()
404 aStatus
.bIsRunning
= false;
407 bool ModulWindow::LoadBasic()
411 Reference
< uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
412 Reference
< XFilePicker3
> xFP
= FilePicker::createWithMode(xContext
, TemplateDescription::FILEOPEN_SIMPLE
);
414 if ( !aCurPath
.isEmpty() )
415 xFP
->setDisplayDirectory ( aCurPath
);
417 xFP
->appendFilter( "BASIC" , "*.bas" );
418 xFP
->appendFilter( IDE_RESSTR(RID_STR_FILTER_ALLFILES
), OUString( FilterMask_All
) );
419 xFP
->setCurrentFilter( "BASIC" );
421 if( xFP
->execute() == RET_OK
)
423 Sequence
< OUString
> aPaths
= xFP
->getFiles();
424 aCurPath
= aPaths
[0];
425 SfxMedium
aMedium( aCurPath
, StreamMode::READ
| StreamMode::SHARE_DENYWRITE
| StreamMode::NOCREATE
);
426 SvStream
* pStream
= aMedium
.GetInStream();
429 AssertValidEditEngine();
430 sal_uLong nLines
= CalcLineCount( *pStream
);
431 // nLines*4: ReadText/Formatting/Highlighting/Formatting
432 GetEditorWindow().CreateProgress( IDEResId(RID_STR_GENERATESOURCE
).toString(), nLines
*4 );
433 GetEditEngine()->SetUpdateMode( false );
434 GetEditView()->Read( *pStream
);
435 GetEditEngine()->SetUpdateMode( true );
436 GetEditorWindow().Update();
437 GetEditorWindow().ForceSyntaxTimeout();
438 GetEditorWindow().DestroyProgress();
439 sal_uLong nError
= aMedium
.GetError();
441 ErrorHandler::HandleError( nError
);
446 ScopedVclPtrInstance
<MessageDialog
>::Create(this, IDE_RESSTR(RID_STR_COULDNTREAD
))->Execute();
452 bool ModulWindow::SaveBasicSource()
456 Reference
< uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
457 Reference
< XFilePicker3
> xFP
= FilePicker::createWithMode(xContext
, TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD
);
459 Reference
< XFilePickerControlAccess
> xFPControl(xFP
, UNO_QUERY
);
460 xFPControl
->enableControl(ExtendedFilePickerElementIds::CHECKBOX_PASSWORD
, false);
463 xFPControl
->setValue(ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION
, 0, aValue
);
465 if ( !aCurPath
.isEmpty() )
466 xFP
->setDisplayDirectory ( aCurPath
);
468 xFP
->appendFilter( "BASIC", "*.bas" );
469 xFP
->appendFilter( IDE_RESSTR(RID_STR_FILTER_ALLFILES
), OUString( FilterMask_All
) );
470 xFP
->setCurrentFilter( "BASIC" );
472 if( xFP
->execute() == RET_OK
)
474 Sequence
< OUString
> aPaths
= xFP
->getFiles();
475 aCurPath
= aPaths
[0];
476 SfxMedium
aMedium( aCurPath
, StreamMode::WRITE
| StreamMode::SHARE_DENYWRITE
| StreamMode::TRUNC
);
477 SvStream
* pStream
= aMedium
.GetOutStream();
481 AssertValidEditEngine();
482 GetEditEngine()->Write( *pStream
);
485 sal_uLong nError
= aMedium
.GetError();
487 ErrorHandler::HandleError( nError
);
492 ScopedVclPtrInstance
<MessageDialog
>::Create(this, IDEResId(RID_STR_COULDNTWRITE
))->Execute();
498 bool ModulWindow::ImportDialog()
500 const ScriptDocument
& rDocument
= GetDocument();
501 OUString aLibName
= GetLibName();
502 return implImportDialog( this, aCurPath
, rDocument
, aLibName
);
505 bool ModulWindow::ToggleBreakPoint( sal_uLong nLine
)
507 DBG_ASSERT( XModule().Is(), "Kein Modul!" );
509 bool bNewBreakPoint
= false;
511 if ( XModule().Is() )
514 if ( aStatus
.bError
)
519 BreakPoint
* pBrk
= GetBreakPoints().FindBreakPoint( nLine
);
520 if ( pBrk
) // remove
522 xModule
->ClearBP( (sal_uInt16
)nLine
);
523 delete GetBreakPoints().remove( pBrk
);
527 if ( xModule
->SetBP( (sal_uInt16
)nLine
) )
529 GetBreakPoints().InsertSorted( new BreakPoint( nLine
) );
530 bNewBreakPoint
= true;
531 if ( StarBASIC::IsRunning() )
533 for ( sal_uInt16 nMethod
= 0; nMethod
< xModule
->GetMethods()->Count(); nMethod
++ )
535 SbMethod
* pMethod
= static_cast<SbMethod
*>(xModule
->GetMethods()->Get( nMethod
));
536 DBG_ASSERT( pMethod
, "Methode nicht gefunden! (NULL)" );
537 pMethod
->SetDebugFlags( pMethod
->GetDebugFlags() | SbDEBUG_BREAK
);
544 return bNewBreakPoint
;
547 void ModulWindow::UpdateBreakPoint( const BreakPoint
& rBrk
)
549 DBG_ASSERT( XModule().Is(), "Kein Modul!" );
551 if ( XModule().Is() )
556 xModule
->SetBP( (sal_uInt16
)rBrk
.nLine
);
558 xModule
->ClearBP( (sal_uInt16
)rBrk
.nLine
);
563 bool ModulWindow::BasicToggleBreakPoint()
565 AssertValidEditEngine();
567 TextSelection aSel
= GetEditView()->GetSelection();
568 aSel
.GetStart().GetPara()++; // Basic lines start at 1!
569 aSel
.GetEnd().GetPara()++;
571 bool bNewBreakPoint
= false;
573 for ( sal_uLong nLine
= aSel
.GetStart().GetPara(); nLine
<= aSel
.GetEnd().GetPara(); nLine
++ )
575 if ( ToggleBreakPoint( nLine
) )
576 bNewBreakPoint
= true;
579 aXEditorWindow
->GetBrkWindow().Invalidate();
580 return bNewBreakPoint
;
584 void ModulWindow::BasicToggleBreakPointEnabled()
586 AssertValidEditEngine();
588 ExtTextView
* pView
= GetEditView();
591 TextSelection aSel
= pView
->GetSelection();
592 BreakPointList
& rList
= GetBreakPoints();
594 for ( sal_uLong nLine
= ++aSel
.GetStart().GetPara(), nEnd
= ++aSel
.GetEnd().GetPara(); nLine
<= nEnd
; ++nLine
)
596 BreakPoint
* pBrk
= rList
.FindBreakPoint( nLine
);
599 pBrk
->bEnabled
= !pBrk
->bEnabled
;
600 UpdateBreakPoint( *pBrk
);
604 GetBreakPointWindow().Invalidate();
609 void ModulWindow::ManageBreakPoints()
611 BreakPointWindow
& rBrkWin
= GetBreakPointWindow();
612 ScopedVclPtrInstance
< BreakPointDialog
> aBrkDlg( &rBrkWin
, GetBreakPoints() );
614 rBrkWin
.Invalidate();
618 bool ModulWindow::BasicErrorHdl( StarBASIC
* pBasic
)
625 sal_uInt16 nErrorLine
= StarBASIC::GetLine() - 1;
626 sal_uInt16 nErrCol1
= StarBASIC::GetCol1();
627 sal_uInt16 nErrCol2
= StarBASIC::GetCol2();
628 if ( nErrCol2
!= 0xFFFF )
631 AssertValidEditEngine();
632 GetEditView()->SetSelection( TextSelection( TextPaM( nErrorLine
, nErrCol1
), TextPaM( nErrorLine
, nErrCol2
) ) );
634 // if other basic, the IDE should try to display the correct module
635 bool const bMarkError
= pBasic
== GetBasic();
637 aXEditorWindow
->GetBrkWindow().SetMarkerPos(nErrorLine
, true);
640 Reference
< awt::XWindow
> xWindow
= VCLUnoHelper::GetInterface( this );
642 ErrorHandler::HandleError( StarBASIC::GetErrorCode() );
645 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
650 aXEditorWindow
->GetBrkWindow().SetNoMarker();
654 long ModulWindow::BasicBreakHdl( StarBASIC
* pBasic
)
656 // #i69280 Required in Window despite normal usage in next command!
659 // Return value: sal_uInt16 => see SB-Debug-Flags
660 sal_uInt16 nErrorLine
= StarBASIC::GetLine();
663 BreakPoint
* pBrk
= GetBreakPoints().FindBreakPoint( nErrorLine
);
667 if ( pBrk
->nHitCount
<= pBrk
->nStopAfter
&& GetBasic()->IsBreak() )
668 return aStatus
.nBasicFlags
; // go on...
671 nErrorLine
--; // EditEngine starts at 0, Basic at 1
673 AssertValidEditEngine();
674 GetEditView()->SetSelection( TextSelection( TextPaM( nErrorLine
, 0 ), TextPaM( nErrorLine
, 0 ) ) );
675 aXEditorWindow
->GetBrkWindow().SetMarkerPos( nErrorLine
);
677 rLayout
.UpdateDebug(false);
679 aStatus
.bIsInReschedule
= true;
680 aStatus
.bIsRunning
= true;
682 AddStatus( BASWIN_INRESCHEDULE
);
684 InvalidateDebuggerSlots();
686 while( aStatus
.bIsRunning
)
687 Application::Yield();
689 aStatus
.bIsInReschedule
= false;
690 aXEditorWindow
->GetBrkWindow().SetNoMarker();
692 ClearStatus( BASWIN_INRESCHEDULE
);
694 return aStatus
.nBasicFlags
;
697 void ModulWindow::BasicAddWatch()
699 AssertValidEditEngine();
701 if ( !GetEditView()->HasSelection() )
704 OUString aWord
= GetEditEngine()->GetWord( GetEditView()->GetSelection().GetEnd(), &aWordStart
);
705 if ( !aWord
.isEmpty() )
707 TextSelection
aSel( aWordStart
);
708 sal_uInt16
& rIndex
= aSel
.GetEnd().GetIndex();
709 rIndex
= rIndex
+ aWord
.getLength();
710 GetEditView()->SetSelection( aSel
);
716 TextSelection aSel
= GetEditView()->GetSelection();
717 if ( aSel
.GetStart().GetPara() == aSel
.GetEnd().GetPara() ) // single line selection
718 rLayout
.BasicAddWatch(GetEditView()->GetSelected());
724 void ModulWindow::EditMacro( const OUString
& rMacroName
)
726 DBG_ASSERT( XModule().Is(), "Kein Modul!" );
728 if ( XModule().Is() )
732 if ( !aStatus
.bError
)
734 sal_uInt16 nStart
, nEnd
;
735 SbMethod
* pMethod
= static_cast<SbMethod
*>(xModule
->Find( rMacroName
, SbxCLASS_METHOD
));
738 pMethod
->GetLineRange( nStart
, nEnd
);
744 TextSelection
aSel( TextPaM( nStart
, 0 ), TextPaM( nStart
, 0 ) );
745 AssertValidEditEngine();
746 TextView
* pView
= GetEditView();
747 // scroll if applicabel so that first line is at the top
748 long nVisHeight
= GetOutputSizePixel().Height();
749 if ( (long)pView
->GetTextEngine()->GetTextHeight() > nVisHeight
)
751 long nMaxY
= (long)pView
->GetTextEngine()->GetTextHeight() - nVisHeight
;
752 long nOldStartY
= pView
->GetStartDocPos().Y();
753 long nNewStartY
= (long)nStart
* (long)pView
->GetTextEngine()->GetCharHeight();
754 nNewStartY
= std::min( nNewStartY
, nMaxY
);
755 pView
->Scroll( 0, -(nNewStartY
-nOldStartY
) );
756 pView
->ShowCursor( false, true );
757 GetEditVScrollBar().SetThumbPos( pView
->GetStartDocPos().Y() );
759 pView
->SetSelection( aSel
);
761 pView
->GetWindow()->GrabFocus();
767 void ModulWindow::StoreData()
769 // StoreData is called when the BasicManager is destroyed or
770 // this window is closed.
771 // => interrupts undesired!
772 GetEditorWindow().SetSourceInBasic();
775 bool ModulWindow::CanClose()
780 bool ModulWindow::AllowUndo()
782 return GetEditorWindow().CanModify();
785 void ModulWindow::UpdateData()
787 DBG_ASSERT( XModule().Is(), "Kein Modul!" );
788 // UpdateData is called when the source has changed from outside
789 // => interrupts undesired!
791 if ( XModule().Is() )
793 SetModule( xModule
->GetSource32() );
797 TextSelection aSel
= GetEditView()->GetSelection();
798 setTextEngineText(*GetEditEngine(), xModule
->GetSource32());
799 GetEditView()->SetSelection( aSel
);
800 GetEditEngine()->SetModified( false );
801 MarkDocumentModified( GetDocument() );
806 sal_Int32
ModulWindow::countPages( Printer
* pPrinter
)
808 return FormatAndPrint( pPrinter
, -1 );
811 void ModulWindow::printPage( sal_Int32 nPage
, Printer
* pPrinter
)
813 FormatAndPrint( pPrinter
, nPage
);
816 /* implementation note: this is totally inefficient for the XRenderable interface
817 usage since the whole "document" will be format for every page. Should this ever
818 become a problem we should
819 - format only once for every new printer
820 - keep an index list for each page which is the starting paragraph
822 sal_Int32
ModulWindow::FormatAndPrint( Printer
* pPrinter
, sal_Int32 nPrintPage
)
824 AssertValidEditEngine();
826 MapMode
eOldMapMode( pPrinter
->GetMapMode() );
827 vcl::Font
aOldFont( pPrinter
->GetFont() );
829 vcl::Font
aFont( GetEditEngine()->GetFont() );
830 aFont
.SetAlign( ALIGN_BOTTOM
);
831 aFont
.SetTransparent( true );
832 aFont
.SetSize( Size( 0, 360 ) );
833 pPrinter
->SetFont( aFont
);
834 pPrinter
->SetMapMode( MAP_100TH_MM
);
836 OUString
aTitle( CreateQualifiedName() );
838 sal_Int32 nLineHeight
= pPrinter
->GetTextHeight();
843 sal_Int32 nParaSpace
= 10;
845 Size aPaperSz
= pPrinter
->GetOutputSize();
846 aPaperSz
.Width() -= (Print::nLeftMargin
+ Print::nRightMargin
);
847 aPaperSz
.Height() -= (Print::nTopMargin
+ Print::nBottomMargin
);
849 // nLinepPage is not correct if there's a line break
850 sal_Int32 nLinespPage
= aPaperSz
.Height()/nLineHeight
;
851 long nXTextWidth
= pPrinter
->approximate_char_width();
853 sal_Int32 nCharspLine
= aPaperSz
.Width() / (nXTextWidth
> 1 ? nXTextWidth
: 1);
854 sal_uLong nParas
= GetEditEngine()->GetParagraphCount();
856 sal_Int32 nPages
= nParas
/nLinespPage
+1;
857 sal_Int32 nCurPage
= 1;
859 lcl_PrintHeader( pPrinter
, nPages
, nCurPage
, aTitle
, nPrintPage
== 0 );
860 Point
aPos( Print::nLeftMargin
, Print::nTopMargin
);
861 for ( sal_uLong nPara
= 0; nPara
< nParas
; nPara
++ )
863 OUString
aLine( GetEditEngine()->GetText( nPara
) );
864 lcl_ConvertTabsToSpaces( aLine
);
865 sal_Int32 nLines
= aLine
.getLength()/nCharspLine
+1;
866 for (sal_Int32 nLine
= 0; nLine
< nLines
; ++nLine
)
868 sal_Int32 nBeginIndex
= nLine
*nCharspLine
;
869 sal_Int32 nCopyCount
= std::min
<sal_Int32
>(nCharspLine
, aLine
.getLength()-nBeginIndex
);
870 OUString aTmpLine
= aLine
.copy(nBeginIndex
, nCopyCount
);
871 aPos
.Y() += nLineHeight
;
872 if ( aPos
.Y() > ( aPaperSz
.Height() + Print::nTopMargin
) )
875 lcl_PrintHeader( pPrinter
, nPages
, nCurPage
, aTitle
, nCurPage
-1 == nPrintPage
);
876 aPos
= Point(Print::nLeftMargin
, Print::nTopMargin
+ nLineHeight
);
878 if( nCurPage
-1 == nPrintPage
)
879 pPrinter
->DrawText( aPos
, aTmpLine
);
881 aPos
.Y() += nParaSpace
;
884 pPrinter
->SetFont( aOldFont
);
885 pPrinter
->SetMapMode( eOldMapMode
);
890 void ModulWindow::ExecuteCommand (SfxRequest
& rReq
)
892 AssertValidEditEngine();
893 switch (rReq
.GetSlot())
897 KeyEvent
aFakeDelete( 0, KEY_DELETE
);
898 bool bDone
= GetEditView()->KeyInput( aFakeDelete
);
901 BaseWindow::KeyInput(aFakeDelete
);
907 TextSelection
aSel( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL
, 0xFFFF ) );
908 TextView
* pView
= GetEditView();
909 pView
->SetSelection( aSel
);
910 pView
->GetWindow()->GrabFocus();
918 case SID_BASICCOMPILE
:
923 case SID_BASICSTEPOVER
:
928 case SID_BASICSTEPINTO
:
933 case SID_BASICSTEPOUT
:
943 case SID_BASICSAVEAS
:
948 case SID_IMPORT_DIALOG
:
953 case SID_BASICIDE_MATCHGROUP
:
955 GetEditView()->MatchGroup();
958 case SID_BASICIDE_TOGGLEBRKPNT
:
960 BasicToggleBreakPoint();
963 case SID_BASICIDE_MANAGEBRKPNTS
:
968 case SID_BASICIDE_TOGGLEBRKPNTENABLED
:
970 BasicToggleBreakPointEnabled();
973 case SID_BASICIDE_ADDWATCH
:
978 case SID_BASICIDE_REMOVEWATCH
:
980 rLayout
.BasicRemoveWatch();
987 GetEditView()->Cut();
988 if (SfxBindings
* pBindings
= GetBindingsPtr())
989 pBindings
->Invalidate( SID_DOC_MODIFIED
);
995 GetEditView()->Copy();
1000 if ( !IsReadOnly() )
1002 GetEditView()->Paste();
1003 if (SfxBindings
* pBindings
= GetBindingsPtr())
1004 pBindings
->Invalidate( SID_DOC_MODIFIED
);
1008 case SID_BASICIDE_BRKPNTSCHANGED
:
1010 GetBreakPointWindow().Invalidate();
1015 SFX_REQUEST_ARG(rReq
, pItem
, SfxBoolItem
, rReq
.GetSlot(), false);
1016 bSourceLinesEnabled
= pItem
&& pItem
->GetValue();
1017 aXEditorWindow
->SetLineNumberDisplay(bSourceLinesEnabled
);
1020 case SID_BASICIDE_DELETECURRENT
:
1022 if (QueryDelModule(m_aName
, this))
1023 if (m_aDocument
.removeModule(m_aLibName
, m_aName
))
1024 MarkDocumentModified(m_aDocument
);
1027 case FID_SEARCH_OFF
:
1032 ScopedVclPtrInstance
< GotoLineDialog
> aGotoDlg(this);
1033 if (aGotoDlg
->Execute())
1034 if (sal_Int32
const nLine
= aGotoDlg
->GetLineNumber())
1036 TextSelection
const aSel(TextPaM(nLine
- 1, 0), TextPaM(nLine
- 1, 0));
1037 GetEditView()->SetSelection(aSel
);
1044 void ModulWindow::ExecuteGlobal (SfxRequest
& rReq
)
1046 switch (rReq
.GetSlot())
1050 DocumentSignature
aSignature(m_aDocument
);
1051 if (aSignature
.supportsSignatures())
1053 aSignature
.signScriptingContent();
1054 if (SfxBindings
* pBindings
= GetBindingsPtr())
1055 pBindings
->Invalidate(SID_SIGNATURE
);
1064 void ModulWindow::GetState( SfxItemSet
&rSet
)
1066 SfxWhichIter
aIter(rSet
);
1067 for ( sal_uInt16 nWh
= aIter
.FirstWhich(); 0 != nWh
; nWh
= aIter
.NextWhich() )
1073 if ( !GetEditView() || !GetEditView()->HasSelection() )
1074 rSet
.DisableItem( nWh
);
1077 rSet
.DisableItem( nWh
);
1082 if ( !GetEditView() || !GetEditView()->HasSelection() )
1083 rSet
.DisableItem( nWh
);
1088 if ( !IsPasteAllowed() )
1089 rSet
.DisableItem( nWh
);
1092 rSet
.DisableItem( nWh
);
1095 case SID_BASICIDE_STAT_POS
:
1097 TextView
* pView
= GetEditView();
1100 TextSelection aSel
= pView
->GetSelection();
1101 OUString aPos
= OUString( IDEResId( RID_STR_LINE
) ) +
1103 OUString::number(aSel
.GetEnd().GetPara()+1) +
1105 OUString( IDEResId( RID_STR_COLUMN
) ) +
1107 OUString::number(aSel
.GetEnd().GetIndex()+1);
1108 SfxStringItem
aItem( SID_BASICIDE_STAT_POS
, aPos
);
1113 case SID_BASICIDE_STAT_TITLE
:
1115 // search for current procedure name (Sub or Function)
1116 TextView
* pView
= GetEditView();
1121 bool bFound
= false;
1123 TextSelection aSel
= pView
->GetSelection();
1124 long nLine
= aSel
.GetStart().GetPara();
1126 for (long i
= nLine
; i
>= 0 && !bFound
; --i
)
1128 OUString aCurrLine
= GetEditEngine()->GetText( i
);
1130 bFound
= GetEditorWindow().GetProcedureName(aCurrLine
, sProcType
, sProcName
);
1133 OUString aTitle
= CreateQualifiedName();
1134 if (!sProcName
.isEmpty())
1135 aTitle
+= "." + sProcName
;
1137 SfxStringItem
aTitleItem( SID_BASICIDE_STAT_TITLE
, aTitle
);
1138 rSet
.Put( aTitleItem
);
1142 case SID_ATTR_INSERT
:
1144 TextView
* pView
= GetEditView();
1147 SfxBoolItem
aItem( SID_ATTR_INSERT
, pView
->IsInsertMode() );
1154 rSet
.Put(SfxBoolItem(nWh
, bSourceLinesEnabled
));
1159 if ( !GetEditView() )
1160 rSet
.DisableItem( nWh
);
1167 void ModulWindow::DoScroll( ScrollBar
* pCurScrollBar
)
1169 if ( ( pCurScrollBar
== GetHScrollBar() ) && GetEditView() )
1171 // don't scroll with the value but rather use the Thumb-Pos for the VisArea:
1172 long nDiff
= GetEditView()->GetStartDocPos().X() - pCurScrollBar
->GetThumbPos();
1173 GetEditView()->Scroll( nDiff
, 0 );
1174 GetEditView()->ShowCursor( false, true );
1175 pCurScrollBar
->SetThumbPos( GetEditView()->GetStartDocPos().X() );
1180 bool ModulWindow::IsModified()
1182 return GetEditEngine() && GetEditEngine()->IsModified();
1185 void ModulWindow::GoOnTop()
1187 GetShell()->GetViewFrame()->ToTop();
1190 OUString
ModulWindow::GetSbModuleName()
1192 OUString aModuleName
;
1193 if ( XModule().Is() )
1194 aModuleName
= xModule
->GetName();
1198 OUString
ModulWindow::GetTitle()
1200 return GetSbModuleName();
1203 void ModulWindow::ShowCursor( bool bOn
)
1205 if ( GetEditEngine() )
1207 TextView
* pView
= GetEditEngine()->GetActiveView();
1211 pView
->ShowCursor();
1213 pView
->HideCursor();
1218 void ModulWindow::AssertValidEditEngine()
1220 if ( !GetEditEngine() )
1221 GetEditorWindow().CreateEditEngine();
1224 void ModulWindow::Activating ()
1226 aXEditorWindow
->SetLineNumberDisplay(bSourceLinesEnabled
);
1230 void ModulWindow::Deactivating()
1233 if ( GetEditView() )
1234 GetEditView()->EraseVirtualDevice();
1237 sal_uInt16
ModulWindow::StartSearchAndReplace( const SvxSearchItem
& rSearchItem
, bool bFromStart
)
1242 // one could also relinquish syntaxhighlighting/formatting instead of the stupid replace-everything...
1243 AssertValidEditEngine();
1244 ExtTextView
* pView
= GetEditView();
1248 aSel
= pView
->GetSelection();
1249 if ( !rSearchItem
.GetBackward() )
1250 pView
->SetSelection( TextSelection() );
1252 pView
->SetSelection( TextSelection( TextPaM( 0xFFFFFFFF, 0xFFFF ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
1255 bool const bForward
= !rSearchItem
.GetBackward();
1256 sal_uInt16 nFound
= 0;
1257 if ( ( rSearchItem
.GetCommand() == SvxSearchCmd::FIND
) ||
1258 ( rSearchItem
.GetCommand() == SvxSearchCmd::FIND_ALL
) )
1260 nFound
= pView
->Search( rSearchItem
.GetSearchOptions() , bForward
) ? 1 : 0;
1262 else if ( ( rSearchItem
.GetCommand() == SvxSearchCmd::REPLACE
) ||
1263 ( rSearchItem
.GetCommand() == SvxSearchCmd::REPLACE_ALL
) )
1265 if ( !IsReadOnly() )
1267 bool const bAll
= rSearchItem
.GetCommand() == SvxSearchCmd::REPLACE_ALL
;
1268 nFound
= pView
->Replace( rSearchItem
.GetSearchOptions() , bAll
, bForward
);
1272 if ( bFromStart
&& !nFound
)
1273 pView
->SetSelection( aSel
);
1278 svl::IUndoManager
* ModulWindow::GetUndoManager()
1280 if ( GetEditEngine() )
1281 return &GetEditEngine()->GetUndoManager();
1285 SearchOptionFlags
ModulWindow::GetSearchOptions()
1287 SearchOptionFlags nOptions
= SearchOptionFlags::SEARCH
|
1288 SearchOptionFlags::WHOLE_WORDS
|
1289 SearchOptionFlags::BACKWARDS
|
1290 SearchOptionFlags::REG_EXP
|
1291 SearchOptionFlags::EXACT
|
1292 SearchOptionFlags::SELECTION
|
1293 SearchOptionFlags::SIMILARITY
;
1295 if ( !IsReadOnly() )
1297 nOptions
|= SearchOptionFlags::REPLACE
;
1298 nOptions
|= SearchOptionFlags::REPLACE_ALL
;
1304 void ModulWindow::BasicStarted()
1306 if ( XModule().Is() )
1308 aStatus
.bIsRunning
= true;
1309 BreakPointList
& rList
= GetBreakPoints();
1312 rList
.ResetHitCount();
1313 rList
.SetBreakPointsInBasic( xModule
);
1314 for ( sal_uInt16 nMethod
= 0; nMethod
< xModule
->GetMethods()->Count(); nMethod
++ )
1316 SbMethod
* pMethod
= static_cast<SbMethod
*>(xModule
->GetMethods()->Get( nMethod
));
1317 DBG_ASSERT( pMethod
, "Methode nicht gefunden! (NULL)" );
1318 pMethod
->SetDebugFlags( pMethod
->GetDebugFlags() | SbDEBUG_BREAK
);
1324 void ModulWindow::BasicStopped()
1326 aStatus
.bIsRunning
= false;
1327 GetBreakPointWindow().SetNoMarker();
1330 EntryDescriptor
ModulWindow::CreateEntryDescriptor()
1332 ScriptDocument
aDocument( GetDocument() );
1333 OUString
aLibName( GetLibName() );
1334 LibraryLocation eLocation
= aDocument
.getLibraryLocation( aLibName
);
1335 OUString
aModName( GetName() );
1336 OUString aLibSubName
;
1337 if( xBasic
.Is() && aDocument
.isInVBAMode() && XModule().Is() )
1339 switch( xModule
->GetModuleType() )
1341 case script::ModuleType::DOCUMENT
:
1343 aLibSubName
= OUString( IDEResId( RID_STR_DOCUMENT_OBJECTS
) );
1344 uno::Reference
< container::XNameContainer
> xLib
= aDocument
.getOrCreateLibrary( E_SCRIPTS
, aLibName
);
1348 ModuleInfoHelper::getObjectName( xLib
, aModName
, sObjName
);
1349 if( !sObjName
.isEmpty() )
1351 aModName
+= " (" + sObjName
+ ")";
1356 case script::ModuleType::FORM
:
1357 aLibSubName
= OUString( IDEResId( RID_STR_USERFORMS
) );
1359 case script::ModuleType::NORMAL
:
1360 aLibSubName
= OUString( IDEResId( RID_STR_NORMAL_MODULES
) );
1362 case script::ModuleType::CLASS
:
1363 aLibSubName
= OUString( IDEResId( RID_STR_CLASS_MODULES
) );
1367 return EntryDescriptor( aDocument
, eLocation
, aLibName
, aLibSubName
, aModName
, OBJ_TYPE_MODULE
);
1370 void ModulWindow::SetReadOnly (bool b
)
1372 if ( GetEditView() )
1373 GetEditView()->SetReadOnly( b
);
1376 bool ModulWindow::IsReadOnly()
1378 return GetEditView() && GetEditView()->IsReadOnly();
1381 bool ModulWindow::IsPasteAllowed()
1383 bool bPaste
= false;
1386 Reference
< datatransfer::clipboard::XClipboard
> xClipboard
= GetClipboard();
1387 if ( xClipboard
.is() )
1390 Reference
< datatransfer::XTransferable
> xTransf
;
1392 SolarMutexReleaser aReleaser
;
1393 // get clipboard content
1394 xTransf
= xClipboard
->getContents();
1398 datatransfer::DataFlavor aFlavor
;
1399 SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING
, aFlavor
);
1400 if ( xTransf
->isDataFlavorSupported( aFlavor
) )
1408 void ModulWindow::OnNewDocument ()
1410 aXEditorWindow
->SetLineNumberDisplay(bSourceLinesEnabled
);
1413 char const* ModulWindow::GetHid () const
1415 return HID_BASICIDE_MODULWINDOW
;
1417 ItemType
ModulWindow::GetType () const
1422 bool ModulWindow::HasActiveEditor () const
1424 return !IsSuspended();
1428 void ModulWindow::UpdateModule ()
1430 OUString
const aModule
= getTextEngineText(*GetEditEngine());
1432 // update module in basic
1435 // update module in module window
1438 // update module in library
1439 OSL_VERIFY(m_aDocument
.updateModule(m_aLibName
, m_aName
, aModule
));
1441 GetEditEngine()->SetModified(false);
1442 MarkDocumentModified(m_aDocument
);
1445 ModulWindowLayout::ModulWindowLayout (vcl::Window
* pParent
, ObjectCatalog
& rObjectCatalog_
) :
1448 aWatchWindow(VclPtr
<WatchWindow
>::Create(this)),
1449 aStackWindow(VclPtr
<StackWindow
>::Create(this)),
1450 rObjectCatalog(rObjectCatalog_
)
1453 ModulWindowLayout::~ModulWindowLayout()
1458 void ModulWindowLayout::dispose()
1460 aWatchWindow
.disposeAndClear();
1461 aStackWindow
.disposeAndClear();
1466 void ModulWindowLayout::UpdateDebug (bool bBasicStopped
)
1468 aWatchWindow
->UpdateWatches(bBasicStopped
);
1469 aStackWindow
->UpdateCalls();
1472 void ModulWindowLayout::Paint (vcl::RenderContext
& rRenderContext
, Rectangle
const&)
1474 rRenderContext
.DrawText(Point(), IDEResId(RID_STR_NOMODULE
).toString());
1478 void ModulWindowLayout::DataChanged (DataChangedEvent
const& rDCEvt
)
1480 Layout::DataChanged(rDCEvt
);
1481 if (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
&& (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))
1482 aSyntaxColors
.SettingsChanged();
1485 void ModulWindowLayout::Activating (BaseWindow
& rChild
)
1487 assert(dynamic_cast<ModulWindow
*>(&rChild
));
1488 pChild
= &static_cast<ModulWindow
&>(rChild
);
1489 aWatchWindow
->Show();
1490 aStackWindow
->Show();
1491 rObjectCatalog
.Show();
1492 rObjectCatalog
.SetLayoutWindow(this);
1493 rObjectCatalog
.UpdateEntries();
1494 Layout::Activating(rChild
);
1495 aSyntaxColors
.SetActiveEditor(&pChild
->GetEditorWindow());
1498 void ModulWindowLayout::Deactivating ()
1500 aSyntaxColors
.SetActiveEditor(0);
1501 Layout::Deactivating();
1502 aWatchWindow
->Hide();
1503 aStackWindow
->Hide();
1504 rObjectCatalog
.Hide();
1508 void ModulWindowLayout::GetState (SfxItemSet
&rSet
, unsigned nWhich
)
1512 case SID_SHOW_PROPERTYBROWSER
:
1513 rSet
.Put(SfxVisibilityItem(nWhich
, false));
1516 case SID_BASICIDE_CHOOSEMACRO
:
1517 rSet
.Put(SfxVisibilityItem(nWhich
, true));
1522 void ModulWindowLayout::BasicAddWatch (OUString
const& rWatchStr
)
1524 aWatchWindow
->AddWatch(rWatchStr
);
1527 void ModulWindowLayout::BasicRemoveWatch ()
1529 aWatchWindow
->RemoveSelectedWatch();
1532 void ModulWindowLayout::OnFirstSize (long const nWidth
, long const nHeight
)
1534 AddToLeft(&rObjectCatalog
, Size(nWidth
* 0.20, nHeight
* 0.75));
1535 AddToBottom(aWatchWindow
.get(), Size(nWidth
* 0.67, nHeight
* 0.25));
1536 AddToBottom(aStackWindow
.get(), Size(nWidth
* 0.33, nHeight
* 0.25));
1539 ModulWindowLayout::SyntaxColors::SyntaxColors () :
1542 aConfig
.AddListener(this);
1544 aColors
[TT_UNKNOWN
] =
1545 aColors
[TT_WHITESPACE
] =
1547 Application::GetSettings().GetStyleSettings().GetFieldTextColor();
1552 ModulWindowLayout::SyntaxColors::~SyntaxColors ()
1554 aConfig
.RemoveListener(this);
1557 void ModulWindowLayout::SyntaxColors::SettingsChanged ()
1559 Color
const aColor
= Application::GetSettings().GetStyleSettings().GetFieldTextColor();
1560 if (aColor
!= aColors
[TT_UNKNOWN
])
1562 aColors
[TT_UNKNOWN
] =
1563 aColors
[TT_WHITESPACE
] =
1567 pEditor
->UpdateSyntaxHighlighting();
1572 void ModulWindowLayout::SyntaxColors::ConfigurationChanged (utl::ConfigurationBroadcaster
*, sal_uInt32
)
1577 // when a new configuration has to be set
1578 void ModulWindowLayout::SyntaxColors::NewConfig (bool bFirst
)
1582 TokenTypes eTokenType
;
1583 svtools::ColorConfigEntry eEntry
;
1587 { TT_IDENTIFIER
, svtools::BASICIDENTIFIER
},
1588 { TT_NUMBER
, svtools::BASICNUMBER
},
1589 { TT_STRING
, svtools::BASICSTRING
},
1590 { TT_COMMENT
, svtools::BASICCOMMENT
},
1591 { TT_ERROR
, svtools::BASICERROR
},
1592 { TT_OPERATOR
, svtools::BASICOPERATOR
},
1593 { TT_KEYWORDS
, svtools::BASICKEYWORD
},
1596 bool bChanged
= false;
1597 for (unsigned i
= 0; i
!= sizeof vIds
/ sizeof vIds
[0]; ++i
)
1599 Color
const aColor
= aConfig
.GetColorValue(vIds
[i
].eEntry
).nColor
;
1600 Color
& rMyColor
= aColors
[vIds
[i
].eTokenType
];
1601 if (bFirst
|| aColor
!= rMyColor
)
1607 if (bChanged
&& !bFirst
&& pEditor
)
1608 pEditor
->UpdateSyntaxHighlighting();
1612 } // namespace basctl
1614 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */