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 .
23 #include "baside2.hrc"
25 #include "baside2.hxx"
27 #include "iderdll.hxx"
29 #include <basic/sbmeth.hxx>
30 #include <basic/sbuno.hxx>
31 #include <com/sun/star/beans/XMultiPropertySet.hpp>
32 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
33 #include <com/sun/star/script/XLibraryContainer2.hpp>
34 #include <comphelper/string.hxx>
35 #include <officecfg/Office/Common.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <vcl/msgbox.hxx>
38 #include <svl/urihelper.hxx>
39 #include <vcl/xtextedt.hxx>
40 #include <vcl/txtattr.hxx>
41 #include <vcl/settings.hxx>
42 #include <svtools/textwindowpeer.hxx>
43 #include <svtools/treelistentry.hxx>
44 #include <vcl/taskpanelist.hxx>
45 #include <vcl/help.hxx>
48 #include <com/sun/star/reflection/theCoreReflection.hpp>
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
59 sal_uInt16
const NoMarker
= 0xFFFF;
60 long const nBasePad
= 2;
61 long const nCursorPad
= 5;
63 long nVirtToolBoxHeight
; // inited in WatchWindow, used in Stackwindow
64 long nHeaderBarHeight
;
66 // Returns pBase converted to SbxVariable if valid and is not an SbxMethod.
67 SbxVariable
* IsSbxVariable (SbxBase
* pBase
)
69 if (SbxVariable
* pVar
= dynamic_cast<SbxVariable
*>(pBase
))
70 if (!dynamic_cast<SbxMethod
*>(pVar
))
75 Image
GetImage (unsigned nId
)
77 static ImageList
const aImagesNormal(IDEResId(RID_IMGLST_LAYOUT
));
78 return aImagesNormal
.GetImage(nId
);
81 int const nScrollLine
= 12;
82 int const nScrollPage
= 60;
83 int const DWBORDER
= 3;
85 char const cSuffixes
[] = "%&!#@$";
91 * Helper functions to get/set text in TextEngine using
92 * the stream interface.
94 * get/setText() only supports tools Strings limited to 64K).
96 OUString
getTextEngineText (ExtTextEngine
& rEngine
)
98 SvMemoryStream aMemStream
;
99 aMemStream
.SetStreamCharSet( RTL_TEXTENCODING_UTF8
);
100 aMemStream
.SetLineDelimiter( LINEEND_LF
);
101 rEngine
.Write( aMemStream
);
102 sal_Size nSize
= aMemStream
.Tell();
103 OUString
aText( static_cast<const sal_Char
*>(aMemStream
.GetData()),
104 nSize
, RTL_TEXTENCODING_UTF8
);
108 void setTextEngineText (ExtTextEngine
& rEngine
, OUString
const& aStr
)
110 rEngine
.SetText(OUString());
111 OString aUTF8Str
= OUStringToOString( aStr
, RTL_TEXTENCODING_UTF8
);
112 SvMemoryStream
aMemStream( (void*)aUTF8Str
.getStr(), aUTF8Str
.getLength(),
114 aMemStream
.SetStreamCharSet( RTL_TEXTENCODING_UTF8
);
115 aMemStream
.SetLineDelimiter( LINEEND_LF
);
116 rEngine
.Read(aMemStream
);
122 void lcl_DrawIDEWindowFrame(DockingWindow
* pWin
, vcl::RenderContext
& rRenderContext
)
124 if (pWin
->IsFloatingMode())
127 Size aSz
= rRenderContext
.GetOutputSizePixel();
128 const Color
aOldLineColor(rRenderContext
.GetLineColor());
129 rRenderContext
.SetLineColor(Color(COL_WHITE
));
131 rRenderContext
.DrawLine(Point(0, 0), Point(aSz
.Width(), 0));
132 // Black line at bottom
133 rRenderContext
.SetLineColor(Color(COL_BLACK
));
134 rRenderContext
.DrawLine(Point(0, aSz
.Height() - 1),
135 Point(aSz
.Width(), aSz
.Height() - 1));
136 rRenderContext
.SetLineColor(aOldLineColor
);
139 void lcl_SeparateNameAndIndex( const OUString
& rVName
, OUString
& rVar
, OUString
& rIndex
)
143 sal_Int32 nIndexStart
= rVar
.indexOf( '(' );
144 if ( nIndexStart
!= -1 )
146 sal_Int32 nIndexEnd
= rVar
.indexOf( ')', nIndexStart
);
147 if ( nIndexStart
!= -1 )
149 rIndex
= rVar
.copy( nIndexStart
+1, nIndexEnd
-nIndexStart
-1 );
150 rVar
= rVar
.copy( 0, nIndexStart
);
151 rVar
= comphelper::string::stripEnd(rVar
, ' ');
152 rIndex
= comphelper::string::strip(rIndex
, ' ');
156 if ( !rVar
.isEmpty() )
158 sal_uInt16 nLastChar
= rVar
.getLength()-1;
159 if ( strchr( cSuffixes
, rVar
[ nLastChar
] ) )
160 rVar
= rVar
.replaceAt( nLastChar
, 1, "" );
162 if ( !rIndex
.isEmpty() )
164 sal_uInt16 nLastChar
= rIndex
.getLength()-1;
165 if ( strchr( cSuffixes
, rIndex
[ nLastChar
] ) )
166 rIndex
= rIndex
.replaceAt( nLastChar
, 1, "" );
178 class EditorWindow::ChangesListener
:
179 public cppu::WeakImplHelper1
< beans::XPropertiesChangeListener
>
182 explicit ChangesListener(EditorWindow
& editor
): editor_(editor
) {}
185 virtual ~ChangesListener() {}
187 virtual void SAL_CALL
disposing(lang::EventObject
const &) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
189 osl::MutexGuard
g(editor_
.mutex_
);
190 editor_
.notifier_
.clear();
193 virtual void SAL_CALL
propertiesChange(
194 Sequence
< beans::PropertyChangeEvent
> const &) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
197 editor_
.ImplSetFont();
200 EditorWindow
& editor_
;
203 class EditorWindow::ProgressInfo
: public SfxProgress
206 ProgressInfo (SfxObjectShell
* pObjSh
, OUString
const& rText
, sal_uLong nRange
) :
207 SfxProgress(pObjSh
, rText
, nRange
),
213 SetState(++nCurState
);
220 EditorWindow::EditorWindow (vcl::Window
* pParent
, ModulWindow
* pModulWindow
) :
221 Window(pParent
, WB_BORDER
),
224 rModulWindow(*pModulWindow
),
226 aHighlighter(HIGHLIGHT_BASIC
),
227 bHighlightning(false),
228 bDoSyntaxHighlight(true),
229 bDelayHighlight(true),
230 pCodeCompleteWnd(VclPtr
<CodeCompleteWindow
>::Create(this))
232 SetBackground(Wallpaper(GetSettings().GetStyleSettings().GetFieldColor()));
233 SetPointer( Pointer( PointerStyle::Text
) );
234 SetHelpId( HID_BASICIDE_EDITORWINDOW
);
236 listener_
= new ChangesListener(*this);
237 Reference
< beans::XMultiPropertySet
> n(
238 officecfg::Office::Common::Font::SourceViewFont::get(),
241 osl::MutexGuard
g(mutex_
);
244 Sequence
< OUString
> s(2);
247 n
->addPropertiesChangeListener(s
, listener_
.get());
251 EditorWindow::~EditorWindow()
256 void EditorWindow::dispose()
258 Reference
< beans::XMultiPropertySet
> n
;
260 osl::MutexGuard
g(mutex_
);
264 n
->removePropertiesChangeListener(listener_
.get());
271 EndListening( *pEditEngine
);
272 pEditEngine
->RemoveView(pEditView
.get());
274 pCodeCompleteWnd
.disposeAndClear();
275 vcl::Window::dispose();
278 OUString
EditorWindow::GetWordAtCursor()
284 TextEngine
* pTextEngine
= pEditView
->GetTextEngine();
287 // check first, if the cursor is at a help URL
288 const TextSelection
& rSelection
= pEditView
->GetSelection();
289 const TextPaM
& rSelStart
= rSelection
.GetStart();
290 const TextPaM
& rSelEnd
= rSelection
.GetEnd();
291 OUString aText
= pTextEngine
->GetText( rSelEnd
.GetPara() );
292 CharClass
aClass( ::comphelper::getProcessComponentContext() , Application::GetSettings().GetLanguageTag() );
293 sal_Int32 nSelStart
= rSelStart
.GetIndex();
294 sal_Int32 nSelEnd
= rSelEnd
.GetIndex();
295 sal_Int32 nLength
= aText
.getLength();
296 sal_Int32 nStart
= 0;
297 sal_Int32 nEnd
= nLength
;
298 while ( nStart
< nLength
)
300 OUString
aURL( URIHelper::FindFirstURLInText( aText
, nStart
, nEnd
, aClass
) );
301 INetURLObject
aURLObj( aURL
);
302 if ( aURLObj
.GetProtocol() == INetProtocol::VndSunStarHelp
303 && nSelStart
>= nStart
&& nSelStart
<= nEnd
&& nSelEnd
>= nStart
&& nSelEnd
<= nEnd
)
312 // Not the selected range, but at the CursorPosition,
313 // if a word is partially selected.
314 if ( aWord
.isEmpty() )
315 aWord
= pTextEngine
->GetWord( rSelEnd
);
317 // Can be empty when full word selected, as Cursor behing it
318 if ( aWord
.isEmpty() && pEditView
->HasSelection() )
319 aWord
= pTextEngine
->GetWord( rSelStart
);
326 void EditorWindow::RequestHelp( const HelpEvent
& rHEvt
)
330 // Should have been activated at some point
333 if ( rHEvt
.GetMode() & HelpEventMode::CONTEXT
)
335 OUString aKeyword
= GetWordAtCursor();
336 Application::GetHelp()->SearchKeyword( aKeyword
);
339 else if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
343 if ( StarBASIC::IsRunning() )
345 Point aWindowPos
= rHEvt
.GetMousePosPixel();
346 aWindowPos
= ScreenToOutputPixel( aWindowPos
);
347 Point aDocPos
= GetEditView()->GetDocPos( aWindowPos
);
348 TextPaM aCursor
= GetEditView()->GetTextEngine()->GetPaM(aDocPos
, false);
349 TextPaM aStartOfWord
;
350 OUString aWord
= GetEditView()->GetTextEngine()->GetWord( aCursor
, &aStartOfWord
);
351 if ( !aWord
.isEmpty() && !comphelper::string::isdigitAsciiString(aWord
) )
353 sal_uInt16 nLastChar
= aWord
.getLength() - 1;
354 if ( strchr( cSuffixes
, aWord
[ nLastChar
] ) )
355 aWord
= aWord
.replaceAt( nLastChar
, 1, "" );
356 SbxBase
* pSBX
= StarBASIC::FindSBXInCurrentScope( aWord
);
357 if (SbxVariable
const* pVar
= IsSbxVariable(pSBX
))
359 SbxDataType eType
= pVar
->GetType();
360 if ( (sal_uInt8
)eType
== (sal_uInt8
)SbxOBJECT
)
361 // might cause a crash e. g. at the selections-object
362 // Type == Object does not mean pVar == Object!
363 ; // aHelpText = ((SbxObject*)pVar)->GetClassName();
364 else if ( eType
& SbxARRAY
)
365 ; // aHelpText = "{...}";
366 else if ( (sal_uInt8
)eType
!= (sal_uInt8
)SbxEMPTY
)
368 aHelpText
= pVar
->GetName();
369 if ( aHelpText
.isEmpty() ) // name is not copied with the passed parameters
372 aHelpText
+= pVar
->GetOUString();
375 if ( !aHelpText
.isEmpty() )
377 aTopLeft
= GetEditView()->GetTextEngine()->PaMtoEditCursor( aStartOfWord
).BottomLeft();
378 aTopLeft
= GetEditView()->GetWindowPos( aTopLeft
);
381 aTopLeft
= OutputToScreenPixel( aTopLeft
);
385 Help::ShowQuickHelp( this, Rectangle( aTopLeft
, Size( 1, 1 ) ), aHelpText
, QuickHelpFlags::Top
|QuickHelpFlags::Left
);
391 Window::RequestHelp( rHEvt
);
395 void EditorWindow::Resize()
397 // ScrollBars, etc. happens in Adjust...
400 long nVisY
= pEditView
->GetStartDocPos().Y();
402 pEditView
->ShowCursor();
403 Size
aOutSz( GetOutputSizePixel() );
404 long nMaxVisAreaStart
= pEditView
->GetTextEngine()->GetTextHeight() - aOutSz
.Height();
405 if ( nMaxVisAreaStart
< 0 )
406 nMaxVisAreaStart
= 0;
407 if ( pEditView
->GetStartDocPos().Y() > nMaxVisAreaStart
)
409 Point
aStartDocPos( pEditView
->GetStartDocPos() );
410 aStartDocPos
.Y() = nMaxVisAreaStart
;
411 pEditView
->SetStartDocPos( aStartDocPos
);
412 pEditView
->ShowCursor();
413 rModulWindow
.GetBreakPointWindow().GetCurYOffset() = aStartDocPos
.Y();
414 rModulWindow
.GetLineNumberWindow().GetCurYOffset() = aStartDocPos
.Y();
417 if ( nVisY
!= pEditView
->GetStartDocPos().Y() )
423 void EditorWindow::MouseMove( const MouseEvent
&rEvt
)
426 pEditView
->MouseMove( rEvt
);
430 void EditorWindow::MouseButtonUp( const MouseEvent
&rEvt
)
434 pEditView
->MouseButtonUp( rEvt
);
435 if (SfxBindings
* pBindings
= GetBindingsPtr())
437 pBindings
->Invalidate( SID_BASICIDE_STAT_POS
);
438 pBindings
->Invalidate( SID_BASICIDE_STAT_TITLE
);
443 void EditorWindow::MouseButtonDown( const MouseEvent
&rEvt
)
447 pEditView
->MouseButtonDown( rEvt
);
448 if( pCodeCompleteWnd
->IsVisible() )
450 if( pEditView
->GetSelection() != pCodeCompleteWnd
->GetTextSelection() )
451 {//selection changed, code complete window should be hidden
452 pCodeCompleteWnd
->GetListBox()->HideAndRestoreFocus();
457 void EditorWindow::Command( const CommandEvent
& rCEvt
)
461 pEditView
->Command( rCEvt
);
462 if ( ( rCEvt
.GetCommand() == CommandEventId::Wheel
) ||
463 ( rCEvt
.GetCommand() == CommandEventId::StartAutoScroll
) ||
464 ( rCEvt
.GetCommand() == CommandEventId::AutoScroll
) )
466 HandleScrollCommand( rCEvt
, rModulWindow
.GetHScrollBar(), &rModulWindow
.GetEditVScrollBar() );
467 } else if ( rCEvt
.GetCommand() == CommandEventId::ContextMenu
) {
468 SfxDispatcher
* pDispatcher
= GetDispatcher();
471 SfxDispatcher::ExecutePopup();
473 if( pCodeCompleteWnd
->IsVisible() ) // hide the code complete window
474 pCodeCompleteWnd
->ClearAndHide();
479 bool EditorWindow::ImpCanModify()
481 bool bCanModify
= true;
482 if ( StarBASIC::IsRunning() && rModulWindow
.GetBasicStatus().bIsRunning
)
484 // If in Trace-mode, abort the trace or refuse input
485 // Remove markers in the modules in Notify at Basic::Stoped
486 if ( QueryBox( 0, WB_OK_CANCEL
, IDEResId(RID_STR_WILLSTOPPRG
).toString() ).Execute() == RET_OK
)
488 rModulWindow
.GetBasicStatus().bIsRunning
= false;
497 void EditorWindow::KeyInput( const KeyEvent
& rKEvt
)
499 if ( !pEditView
) // Happens in Win95
502 #if OSL_DEBUG_LEVEL > 1
503 Range aRange
= rModulWindow
.GetHScrollBar()->GetRange(); (void)aRange
;
504 long nVisSz
= rModulWindow
.GetHScrollBar()->GetVisibleSize(); (void)nVisSz
;
505 long nPapSz
= rModulWindow
.GetHScrollBar()->GetPageSize(); (void)nPapSz
;
506 long nLinSz
= rModulWindow
.GetHScrollBar()->GetLineSize(); (void)nLinSz
;
507 long nThumb
= rModulWindow
.GetHScrollBar()->GetThumbPos(); (void)nThumb
;
509 bool const bWasModified
= pEditEngine
->IsModified();
510 // see if there is an accelerator to be processed first
511 bool bDone
= SfxViewShell::Current()->KeyInput( rKEvt
);
513 if( pCodeCompleteWnd
->IsVisible() && CodeCompleteOptions::IsCodeCompleteOn() )
515 pCodeCompleteWnd
->GetListBox()->KeyInput(rKEvt
);
516 if( rKEvt
.GetKeyCode().GetCode() == KEY_UP
517 || rKEvt
.GetKeyCode().GetCode() == KEY_DOWN
518 || rKEvt
.GetKeyCode().GetCode() == KEY_TAB
519 || rKEvt
.GetKeyCode().GetCode() == KEY_POINT
)
523 if( (rKEvt
.GetKeyCode().GetCode() == KEY_SPACE
||
524 rKEvt
.GetKeyCode().GetCode() == KEY_TAB
||
525 rKEvt
.GetKeyCode().GetCode() == KEY_RETURN
) && CodeCompleteOptions::IsAutoCorrectOn() )
530 if( rKEvt
.GetCharCode() == '"' && CodeCompleteOptions::IsAutoCloseQuotesOn() )
531 {//autoclose double quotes
532 HandleAutoCloseDoubleQuotes();
535 if( rKEvt
.GetCharCode() == '(' && CodeCompleteOptions::IsAutoCloseParenthesisOn() )
536 {//autoclose parenthesis
537 HandleAutoCloseParen();
540 if( rKEvt
.GetKeyCode().GetCode() == KEY_RETURN
&& CodeCompleteOptions::IsProcedureAutoCompleteOn() )
541 {//autoclose implementation
542 HandleProcedureCompletion();
545 if( rKEvt
.GetKeyCode().GetCode() == KEY_POINT
&& CodeCompleteOptions::IsCodeCompleteOn() )
547 HandleCodeCompletion();
549 if ( !bDone
&& ( !TextEngine::DoesKeyChangeText( rKEvt
) || ImpCanModify() ) )
551 if ( ( rKEvt
.GetKeyCode().GetCode() == KEY_TAB
) && !rKEvt
.GetKeyCode().IsMod1() &&
552 !rKEvt
.GetKeyCode().IsMod2() && !GetEditView()->IsReadOnly() )
554 TextSelection
aSel( pEditView
->GetSelection() );
555 if ( aSel
.GetStart().GetPara() != aSel
.GetEnd().GetPara() )
557 bDelayHighlight
= false;
558 if ( !rKEvt
.GetKeyCode().IsShift() )
559 pEditView
->IndentBlock();
561 pEditView
->UnindentBlock();
562 bDelayHighlight
= true;
567 bDone
= pEditView
->KeyInput( rKEvt
);
571 Window::KeyInput( rKEvt
);
575 if (SfxBindings
* pBindings
= GetBindingsPtr())
577 pBindings
->Invalidate( SID_BASICIDE_STAT_POS
);
578 pBindings
->Invalidate( SID_BASICIDE_STAT_TITLE
);
579 if ( rKEvt
.GetKeyCode().GetGroup() == KEYGROUP_CURSOR
)
581 pBindings
->Update( SID_BASICIDE_STAT_POS
);
582 pBindings
->Update( SID_BASICIDE_STAT_TITLE
);
584 if ( !bWasModified
&& pEditEngine
->IsModified() )
586 pBindings
->Invalidate( SID_SAVEDOC
);
587 pBindings
->Invalidate( SID_DOC_MODIFIED
);
588 pBindings
->Invalidate( SID_UNDO
);
590 if ( rKEvt
.GetKeyCode().GetCode() == KEY_INSERT
)
591 pBindings
->Invalidate( SID_ATTR_INSERT
);
596 void EditorWindow::HandleAutoCorrect()
598 TextSelection aSel
= GetEditView()->GetSelection();
599 sal_uLong nLine
= aSel
.GetStart().GetPara();
600 sal_uInt16 nIndex
= aSel
.GetStart().GetIndex();
601 OUString
aLine( pEditEngine
->GetText( nLine
) ); // the line being modified
602 const OUString
& sActSubName
= GetActualSubName( nLine
); // the actual procedure
604 std::vector
<HighlightPortion
> aPortions
;
605 aHighlighter
.getHighlightPortions( aLine
, aPortions
);
607 if( aPortions
.empty() )
610 HighlightPortion
& r
= aPortions
.back();
611 if( nIndex
!= aPortions
.size()-1 )
612 {//cursor is not standing at the end of the line
613 for (std::vector
<HighlightPortion
>::iterator
i(aPortions
.begin());
614 i
!= aPortions
.end(); ++i
)
616 if( i
->nEnd
== nIndex
)
624 OUString sStr
= aLine
.copy( r
.nBegin
, r
.nEnd
- r
.nBegin
);
625 //if WS or empty string: stop, nothing to do
626 if( ( r
.tokenType
== TT_WHITESPACE
) || sStr
.isEmpty() )
628 //create the appropriate TextSelection, and update the cache
629 TextPaM
aStart( nLine
, r
.nBegin
);
630 TextPaM
aEnd( nLine
, r
.nBegin
+ sStr
.getLength() );
631 TextSelection
sTextSelection( aStart
, aEnd
);
632 rModulWindow
.UpdateModule();
633 rModulWindow
.GetSbModule()->GetCodeCompleteDataFromParse( aCodeCompleteCache
);
634 // correct the last entered keyword
635 if( r
.tokenType
== TT_KEYWORDS
)
637 sStr
= sStr
.toAsciiLowerCase();
638 if( !SbModule::GetKeywordCase(sStr
).isEmpty() )
639 // if it is a keyword, get its correct case
640 sStr
= SbModule::GetKeywordCase(sStr
);
642 // else capitalize first letter/select the correct one, and replace
643 sStr
= sStr
.replaceAt( 0, 1, OUString(sStr
[0]).toAsciiUpperCase() );
645 pEditEngine
->ReplaceText( sTextSelection
, sStr
);
646 pEditView
->SetSelection( aSel
);
648 if( r
.tokenType
== TT_IDENTIFIER
)
649 {// correct variables
650 if( !aCodeCompleteCache
.GetCorrectCaseVarName( sStr
, sActSubName
).isEmpty() )
652 sStr
= aCodeCompleteCache
.GetCorrectCaseVarName( sStr
, sActSubName
);
653 pEditEngine
->ReplaceText( sTextSelection
, sStr
);
654 pEditView
->SetSelection( aSel
);
658 //autocorrect procedures
659 SbxArray
* pArr
= rModulWindow
.GetSbModule()->GetMethods();
660 for( sal_uInt32 i
=0; i
< pArr
->Count32(); ++i
)
662 if( pArr
->Get32(i
)->GetName().equalsIgnoreAsciiCase( sStr
) )
664 sStr
= pArr
->Get32(i
)->GetName(); //if found, get the correct case
665 pEditEngine
->ReplaceText( sTextSelection
, sStr
);
666 pEditView
->SetSelection( aSel
);
674 TextSelection
EditorWindow::GetLastHighlightPortionTextSelection()
675 {//creates a text selection from the highlight portion on the cursor
676 sal_uLong nLine
= GetEditView()->GetSelection().GetStart().GetPara();
677 sal_uInt16 nIndex
= GetEditView()->GetSelection().GetStart().GetIndex();
678 OUString
aLine( pEditEngine
->GetText( nLine
) ); // the line being modified
679 std::vector
<HighlightPortion
> aPortions
;
680 aHighlighter
.getHighlightPortions( aLine
, aPortions
);
682 assert(!aPortions
.empty());
683 HighlightPortion
& r
= aPortions
.back();
684 if( nIndex
!= aPortions
.size()-1 )
685 {//cursor is not standing at the end of the line
686 for (std::vector
<HighlightPortion
>::iterator
i(aPortions
.begin());
687 i
!= aPortions
.end(); ++i
)
689 if( i
->nEnd
== nIndex
)
697 if( aPortions
.size() == 0 )
698 return TextSelection();
700 OUString sStr
= aLine
.copy( r
.nBegin
, r
.nEnd
- r
.nBegin
);
701 TextPaM
aStart( nLine
, r
.nBegin
);
702 TextPaM
aEnd( nLine
, r
.nBegin
+ sStr
.getLength() );
703 return TextSelection( aStart
, aEnd
);
706 void EditorWindow::HandleAutoCloseParen()
708 TextSelection aSel
= GetEditView()->GetSelection();
709 sal_uLong nLine
= aSel
.GetStart().GetPara();
710 OUString
aLine( pEditEngine
->GetText( nLine
) ); // the line being modified
712 if( aLine
.getLength() > 0 && aLine
[aSel
.GetEnd().GetIndex()-1] != '(' )
714 GetEditView()->InsertText(OUString(")"));
715 //leave the cursor on it's place: inside the parenthesis
716 TextPaM
aEnd(nLine
, aSel
.GetEnd().GetIndex());
717 GetEditView()->SetSelection( TextSelection( aEnd
, aEnd
) );
721 void EditorWindow::HandleAutoCloseDoubleQuotes()
723 TextSelection aSel
= GetEditView()->GetSelection();
724 sal_uLong nLine
= aSel
.GetStart().GetPara();
725 OUString
aLine( pEditEngine
->GetText( nLine
) ); // the line being modified
727 std::vector
<HighlightPortion
> aPortions
;
728 aHighlighter
.getHighlightPortions( aLine
, aPortions
);
730 if( aPortions
.empty() )
733 if( aLine
.getLength() > 0 && !aLine
.endsWith("\"") && (aPortions
.back().tokenType
!= TT_STRING
) )
735 GetEditView()->InsertText(OUString("\""));
736 //leave the cursor on it's place: inside the two double quotes
737 TextPaM
aEnd(nLine
, aSel
.GetEnd().GetIndex());
738 GetEditView()->SetSelection( TextSelection( aEnd
, aEnd
) );
742 void EditorWindow::HandleProcedureCompletion()
745 TextSelection aSel
= GetEditView()->GetSelection();
746 sal_uLong nLine
= aSel
.GetStart().GetPara();
747 OUString
aLine( pEditEngine
->GetText( nLine
) );
749 bool bFoundName
= false;
753 bFoundName
= GetProcedureName(aLine
, sProcType
, sProcName
);
758 OUString
sText("\nEnd ");
759 aSel
= GetEditView()->GetSelection();
760 if( sProcType
.equalsIgnoreAsciiCase("function") )
761 sText
+= "Function\n";
762 if( sProcType
.equalsIgnoreAsciiCase("sub") )
765 if( nLine
+1 == pEditEngine
->GetParagraphCount() )
767 pEditView
->InsertText( sText
);//append to the end
768 GetEditView()->SetSelection(aSel
);
772 for( sal_uLong i
= nLine
+1; i
< pEditEngine
->GetParagraphCount(); ++i
)
773 {//searching forward for end token, or another sub/function definition
774 OUString aCurrLine
= pEditEngine
->GetText( i
);
775 std::vector
<HighlightPortion
> aCurrPortions
;
776 aHighlighter
.getHighlightPortions( aCurrLine
, aCurrPortions
);
778 if( aCurrPortions
.size() >= 3 )
779 {//at least 3 tokens: (sub|function) whitespace idetifier ....
780 HighlightPortion
& r
= aCurrPortions
.front();
781 OUString sStr
= aCurrLine
.copy(r
.nBegin
, r
.nEnd
- r
.nBegin
);
783 if( r
.tokenType
== 9 )
785 if( sStr
.equalsIgnoreAsciiCase("sub") || sStr
.equalsIgnoreAsciiCase("function") )
787 pEditView
->InsertText( sText
);//append to the end
788 GetEditView()->SetSelection(aSel
);
791 if( sStr
.equalsIgnoreAsciiCase("end") )
799 bool EditorWindow::GetProcedureName(OUString
& rLine
, OUString
& rProcType
, OUString
& rProcName
) const
801 std::vector
<HighlightPortion
> aPortions
;
802 aHighlighter
.getHighlightPortions(rLine
, aPortions
);
804 if( aPortions
.empty() )
807 bool bFoundType
= false;
808 bool bFoundName
= false;
810 for (std::vector
<HighlightPortion
>::iterator
i(aPortions
.begin());
811 i
!= aPortions
.end(); ++i
)
813 OUString sTokStr
= rLine
.copy(i
->nBegin
, i
->nEnd
- i
->nBegin
);
815 if( i
->tokenType
== 9 && ( sTokStr
.equalsIgnoreAsciiCase("sub")
816 || sTokStr
.equalsIgnoreAsciiCase("function")) )
821 if( i
->tokenType
== 1 && bFoundType
)
829 if( !bFoundType
|| !bFoundName
)
830 return false;// no sub/function keyword or there is no identifier
836 void EditorWindow::HandleCodeCompletion()
838 rModulWindow
.UpdateModule();
839 rModulWindow
.GetSbModule()->GetCodeCompleteDataFromParse(aCodeCompleteCache
);
840 TextSelection aSel
= GetEditView()->GetSelection();
841 sal_uLong nLine
= aSel
.GetStart().GetPara();
842 OUString
aLine( pEditEngine
->GetText( nLine
) ); // the line being modified
843 std::vector
< OUString
> aVect
; //vector to hold the base variable+methods for the nested reflection
845 std::vector
<HighlightPortion
> aPortions
;
846 aLine
= aLine
.copy(0, aSel
.GetEnd().GetIndex());
847 aHighlighter
.getHighlightPortions( aLine
, aPortions
);
848 if( !aPortions
.empty() )
849 {//use the syntax highlighter to grab out nested reflection calls, eg. aVar.aMethod("aa").aOtherMethod ..
850 for( std::vector
<HighlightPortion
>::reverse_iterator
i(
852 i
!= aPortions
.rend(); ++i
)
854 if( i
->tokenType
== TT_WHITESPACE
) // a whitespace: stop; if there is no ws, it goes to the beginning of the line
856 if( i
->tokenType
== TT_IDENTIFIER
|| i
->tokenType
== TT_KEYWORDS
) // extract the identifiers(methods, base variable)
857 /* an example: Dim aLocVar2 as com.sun.star.beans.PropertyValue
858 * here, aLocVar2.Name, and PropertyValue's Name field is treated as a keyword(?!)
860 aVect
.insert( aVect
.begin(), aLine
.copy(i
->nBegin
, i
->nEnd
- i
->nBegin
) );
863 if( aVect
.size() == 0 )//nothing to do
865 OUString sBaseName
= aVect
[0];//variable name
866 OUString sVarType
= aCodeCompleteCache
.GetVarType( sBaseName
);
867 if( !sVarType
.isEmpty() && CodeCompleteOptions::IsAutoCorrectOn() )
868 {//correct variable name, if autocorrection on
869 const OUString
& sStr
= aCodeCompleteCache
.GetCorrectCaseVarName( sBaseName
, GetActualSubName(nLine
) );
870 if( !sStr
.isEmpty() )
872 TextPaM
aStart(nLine
, aSel
.GetStart().GetIndex() - sStr
.getLength() );
873 TextSelection
sTextSelection(aStart
, TextPaM(nLine
, aSel
.GetStart().GetIndex()));
874 pEditEngine
->ReplaceText( sTextSelection
, sStr
);
875 pEditView
->SetSelection( aSel
);
879 UnoTypeCodeCompletetor
aTypeCompletor( aVect
, sVarType
);
881 if( aTypeCompletor
.CanCodeComplete() )
883 std::vector
< OUString
> aEntryVect
;//entries to be inserted into the list
884 std::vector
< OUString
> aFieldVect
= aTypeCompletor
.GetXIdlClassFields();//fields
885 aEntryVect
.insert(aEntryVect
.end(), aFieldVect
.begin(), aFieldVect
.end() );
886 if( CodeCompleteOptions::IsExtendedTypeDeclaration() )
887 {// if extended types on, reflect classes, else just the structs (XIdlClass without methods)
888 std::vector
< OUString
> aMethVect
= aTypeCompletor
.GetXIdlClassMethods();//methods
889 aEntryVect
.insert(aEntryVect
.end(), aMethVect
.begin(), aMethVect
.end() );
891 if( aEntryVect
.size() > 0 )
892 SetupAndShowCodeCompleteWnd( aEntryVect
, aSel
);
897 void EditorWindow::SetupAndShowCodeCompleteWnd( const std::vector
< OUString
>& aEntryVect
, TextSelection aSel
)
900 pCodeCompleteWnd
->ClearListBox();
902 for(unsigned int l
= 0; l
< aEntryVect
.size(); ++l
)
904 pCodeCompleteWnd
->InsertEntry( aEntryVect
[l
] );
907 pCodeCompleteWnd
->Show();
908 pCodeCompleteWnd
->ResizeAndPositionListBox();
909 pCodeCompleteWnd
->SelectFirstEntry();
910 // correct text selection, and set it
911 aSel
.GetStart().GetIndex() += 1;
912 aSel
.GetEnd().GetIndex() += 1;
913 pCodeCompleteWnd
->SetTextSelection( aSel
);
914 //give the focus to the EditView
915 pEditView
->GetWindow()->GrabFocus();
918 void EditorWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
920 if (!pEditEngine
) // We need it now at latest
923 pEditView
->Paint(rRenderContext
, rRect
);
926 void EditorWindow::LoseFocus()
932 bool EditorWindow::SetSourceInBasic()
934 bool bChanged
= false;
935 if ( pEditEngine
&& pEditEngine
->IsModified()
936 && !GetEditView()->IsReadOnly() ) // Added for #i60626, otherwise
937 // any read only bug in the text engine could lead to a crash later
939 if ( !StarBASIC::IsRunning() ) // Not at runtime!
941 rModulWindow
.UpdateModule();
948 // Returns the position of the last character of any of the following
949 // EOL char combinations: CR, CR/LF, LF, return -1 if no EOL is found
950 sal_Int32
searchEOL( const OUString
& rStr
, sal_Int32 fromIndex
)
952 sal_Int32 iRetPos
= -1;
954 sal_Int32 iLF
= rStr
.indexOf( LINE_SEP
, fromIndex
);
961 iRetPos
= rStr
.indexOf( LINE_SEP_CR
, fromIndex
);
966 void EditorWindow::CreateEditEngine()
971 pEditEngine
.reset(new ExtTextEngine
);
972 pEditView
.reset(new ExtTextView(pEditEngine
.get(), this));
973 pEditView
->SetAutoIndentMode(true);
974 pEditEngine
->SetUpdateMode(false);
975 pEditEngine
->InsertView(pEditView
.get());
979 aSyntaxIdle
.SetPriority( SchedulerPriority::LOWER
);
980 aSyntaxIdle
.SetIdleHdl( LINK( this, EditorWindow
, SyntaxTimerHdl
) );
982 bool bWasDoSyntaxHighlight
= bDoSyntaxHighlight
;
983 bDoSyntaxHighlight
= false; // too slow for large texts...
984 OUString
aOUSource(rModulWindow
.GetModule());
985 sal_Int32 nLines
= 0;
986 sal_Int32 nIndex
= -1;
990 nIndex
= searchEOL( aOUSource
, nIndex
+1 );
994 // nLines*4: SetText+Formatting+DoHighlight+Formatting
995 // it could be cut down on one formatting but you would wait even longer
996 // for the text then if the source code is long...
997 pProgress
.reset(new ProgressInfo(GetShell()->GetViewFrame()->GetObjectShell(),
998 IDEResId(RID_STR_GENERATESOURCE
).toString(),
1000 setTextEngineText(*pEditEngine
, aOUSource
);
1002 pEditView
->SetStartDocPos(Point(0, 0));
1003 pEditView
->SetSelection(TextSelection());
1004 rModulWindow
.GetBreakPointWindow().GetCurYOffset() = 0;
1005 rModulWindow
.GetLineNumberWindow().GetCurYOffset() = 0;
1006 pEditEngine
->SetUpdateMode(true);
1007 rModulWindow
.Update(); // has only been invalidated at UpdateMode = true
1009 pEditView
->ShowCursor(true, true);
1011 StartListening(*pEditEngine
);
1014 bDoSyntaxHighlight
= bWasDoSyntaxHighlight
;
1016 for (sal_uInt16 nLine
= 0; nLine
< nLines
; nLine
++)
1017 aSyntaxLineTable
.insert(nLine
);
1018 ForceSyntaxTimeout();
1022 pEditView
->EraseVirtualDevice();
1023 pEditEngine
->SetModified( false );
1024 pEditEngine
->EnableUndo( true );
1028 if (SfxBindings
* pBindings
= GetBindingsPtr())
1030 pBindings
->Invalidate(SID_BASICIDE_STAT_POS
);
1031 pBindings
->Invalidate(SID_BASICIDE_STAT_TITLE
);
1034 DBG_ASSERT(rModulWindow
.GetBreakPointWindow().GetCurYOffset() == 0, "CreateEditEngine: Brechpunkte verschoben?");
1036 // set readonly mode for readonly libraries
1037 ScriptDocument
aDocument(rModulWindow
.GetDocument());
1038 OUString
aOULibName(rModulWindow
.GetLibName());
1039 Reference
< script::XLibraryContainer2
> xModLibContainer( aDocument
.getLibraryContainer( E_SCRIPTS
), UNO_QUERY
);
1040 if (xModLibContainer
.is()
1041 && xModLibContainer
->hasByName(aOULibName
)
1042 && xModLibContainer
->isLibraryReadOnly(aOULibName
))
1044 rModulWindow
.SetReadOnly(true);
1047 if (aDocument
.isDocument() && aDocument
.isReadOnly())
1048 rModulWindow
.SetReadOnly(true);
1052 void EditorWindow::DataChanged(DataChangedEvent
const & rDCEvt
)
1054 Window::DataChanged(rDCEvt
);
1055 if (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
1056 && (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))
1058 Color
aColor(GetSettings().GetStyleSettings().GetFieldColor());
1059 const AllSettings
* pOldSettings
= rDCEvt
.GetOldSettings();
1060 if (!pOldSettings
|| aColor
!= pOldSettings
->GetStyleSettings().GetFieldColor())
1062 SetBackground(Wallpaper(aColor
));
1065 if (pEditEngine
!= 0)
1067 aColor
= GetSettings().GetStyleSettings().GetFieldTextColor();
1068 if (!pOldSettings
|| aColor
!=
1069 pOldSettings
-> GetStyleSettings().GetFieldTextColor())
1071 vcl::Font
aFont(pEditEngine
->GetFont());
1072 aFont
.SetColor(aColor
);
1073 pEditEngine
->SetFont(aFont
);
1079 void EditorWindow::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
1081 if (TextHint
const* pTextHint
= dynamic_cast<TextHint
const*>(&rHint
))
1083 TextHint
const& rTextHint
= *pTextHint
;
1084 if( rTextHint
.GetId() == TEXT_HINT_VIEWSCROLLED
)
1086 if ( rModulWindow
.GetHScrollBar() )
1087 rModulWindow
.GetHScrollBar()->SetThumbPos( pEditView
->GetStartDocPos().X() );
1088 rModulWindow
.GetEditVScrollBar().SetThumbPos( pEditView
->GetStartDocPos().Y() );
1089 rModulWindow
.GetBreakPointWindow().DoScroll
1090 ( 0, rModulWindow
.GetBreakPointWindow().GetCurYOffset() - pEditView
->GetStartDocPos().Y() );
1091 rModulWindow
.GetLineNumberWindow().DoScroll
1092 ( 0, rModulWindow
.GetLineNumberWindow().GetCurYOffset() - pEditView
->GetStartDocPos().Y() );
1094 else if( rTextHint
.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED
)
1096 if ( pEditView
->GetStartDocPos().Y() )
1098 long nOutHeight
= GetOutputSizePixel().Height();
1099 long nTextHeight
= pEditEngine
->GetTextHeight();
1100 if ( nTextHeight
< nOutHeight
)
1101 pEditView
->Scroll( 0, pEditView
->GetStartDocPos().Y() );
1103 rModulWindow
.GetLineNumberWindow().Invalidate();
1106 SetScrollBarRanges();
1108 else if( rTextHint
.GetId() == TEXT_HINT_TEXTFORMATTED
)
1110 if ( rModulWindow
.GetHScrollBar() )
1112 sal_uLong nWidth
= pEditEngine
->CalcTextWidth();
1113 if ( (long)nWidth
!= nCurTextWidth
)
1115 nCurTextWidth
= nWidth
;
1116 rModulWindow
.GetHScrollBar()->SetRange( Range( 0, (long)nCurTextWidth
-1) );
1117 rModulWindow
.GetHScrollBar()->SetThumbPos( pEditView
->GetStartDocPos().X() );
1120 long nPrevTextWidth
= nCurTextWidth
;
1121 nCurTextWidth
= pEditEngine
->CalcTextWidth();
1122 if ( nCurTextWidth
!= nPrevTextWidth
)
1123 SetScrollBarRanges();
1125 else if( rTextHint
.GetId() == TEXT_HINT_PARAINSERTED
)
1127 ParagraphInsertedDeleted( rTextHint
.GetValue(), true );
1128 DoDelayedSyntaxHighlight( rTextHint
.GetValue() );
1130 else if( rTextHint
.GetId() == TEXT_HINT_PARAREMOVED
)
1132 ParagraphInsertedDeleted( rTextHint
.GetValue(), false );
1134 else if( rTextHint
.GetId() == TEXT_HINT_PARACONTENTCHANGED
)
1136 DoDelayedSyntaxHighlight( rTextHint
.GetValue() );
1138 else if( rTextHint
.GetId() == TEXT_HINT_VIEWSELECTIONCHANGED
)
1140 if (SfxBindings
* pBindings
= GetBindingsPtr())
1142 pBindings
->Invalidate( SID_CUT
);
1143 pBindings
->Invalidate( SID_COPY
);
1149 OUString
EditorWindow::GetActualSubName( sal_uLong nLine
)
1151 SbxArrayRef pMethods
= rModulWindow
.GetSbModule()->GetMethods();
1152 for( sal_uInt16 i
=0; i
< pMethods
->Count(); i
++ )
1154 SbxVariable
* p
= PTR_CAST( SbMethod
, pMethods
->Get( i
) );
1155 SbMethod
* pMeth
= PTR_CAST( SbMethod
, p
);
1159 pMeth
->GetLineRange(l1
,l2
);
1160 if( (l1
<= nLine
+1) && (nLine
+1 <= l2
) )
1162 return pMeth
->GetName();
1166 return OUString("");
1169 void EditorWindow::SetScrollBarRanges()
1171 // extra method, not InitScrollBars, because for EditEngine events too
1175 if ( rModulWindow
.GetHScrollBar() )
1176 rModulWindow
.GetHScrollBar()->SetRange( Range( 0, nCurTextWidth
-1 ) );
1178 rModulWindow
.GetEditVScrollBar().SetRange( Range( 0, pEditEngine
->GetTextHeight()-1 ) );
1181 void EditorWindow::InitScrollBars()
1186 SetScrollBarRanges();
1187 Size
aOutSz(GetOutputSizePixel());
1188 rModulWindow
.GetEditVScrollBar().SetVisibleSize(aOutSz
.Height());
1189 rModulWindow
.GetEditVScrollBar().SetPageSize(aOutSz
.Height() * 8 / 10);
1190 rModulWindow
.GetEditVScrollBar().SetLineSize(GetTextHeight());
1191 rModulWindow
.GetEditVScrollBar().SetThumbPos(pEditView
->GetStartDocPos().Y());
1192 rModulWindow
.GetEditVScrollBar().Show();
1194 if (rModulWindow
.GetHScrollBar())
1196 rModulWindow
.GetHScrollBar()->SetVisibleSize(aOutSz
.Width());
1197 rModulWindow
.GetHScrollBar()->SetPageSize(aOutSz
.Width() * 8 / 10);
1198 rModulWindow
.GetHScrollBar()->SetLineSize(GetTextWidth( "x" ) );
1199 rModulWindow
.GetHScrollBar()->SetThumbPos(pEditView
->GetStartDocPos().X());
1200 rModulWindow
.GetHScrollBar()->Show();
1204 void EditorWindow::ImpDoHighlight( sal_uLong nLine
)
1206 if ( bDoSyntaxHighlight
)
1208 OUString
aLine( pEditEngine
->GetText( nLine
) );
1209 bool const bWasModified
= pEditEngine
->IsModified();
1210 pEditEngine
->RemoveAttribs( nLine
, true );
1211 std::vector
<HighlightPortion
> aPortions
;
1212 aHighlighter
.getHighlightPortions( aLine
, aPortions
);
1214 for (std::vector
<HighlightPortion
>::iterator
i(aPortions
.begin());
1215 i
!= aPortions
.end(); ++i
)
1217 Color
const aColor
= rModulWindow
.GetLayout().GetSyntaxColor(i
->tokenType
);
1218 pEditEngine
->SetAttrib(TextAttribFontColor(aColor
), nLine
, i
->nBegin
, i
->nEnd
, true);
1221 pEditEngine
->SetModified(bWasModified
);
1225 void EditorWindow::UpdateSyntaxHighlighting ()
1227 unsigned nCount
= pEditEngine
->GetParagraphCount();
1228 for (unsigned i
= 0; i
< nCount
; ++i
)
1229 DoDelayedSyntaxHighlight(i
);
1232 void EditorWindow::ImplSetFont()
1234 OUString
sFontName(officecfg::Office::Common::Font::SourceViewFont::FontName::get().get_value_or(OUString()));
1235 if (sFontName
.isEmpty())
1237 vcl::Font
aTmpFont(OutputDevice::GetDefaultFont(DefaultFontType::FIXED
,
1238 Application::GetSettings().GetUILanguageTag().getLanguageType(),
1239 GetDefaultFontFlags::NONE
, this));
1240 sFontName
= aTmpFont
.GetName();
1242 Size
aFontSize(0, officecfg::Office::Common::Font::SourceViewFont::FontHeight::get());
1243 vcl::Font
aFont(sFontName
, aFontSize
);
1244 aFont
.SetColor(Application::GetSettings().GetStyleSettings().GetFieldTextColor());
1245 SetPointFont(*this, aFont
); // FIXME RenderContext
1248 rModulWindow
.GetBreakPointWindow().SetFont(aFont
);
1249 rModulWindow
.GetLineNumberWindow().SetFont(aFont
);
1253 bool const bModified
= pEditEngine
->IsModified();
1254 pEditEngine
->SetFont(aFont
);
1255 pEditEngine
->SetModified(bModified
);
1259 void EditorWindow::DoSyntaxHighlight( sal_uLong nPara
)
1261 // because of the DelayedSyntaxHighlight it's possible
1262 // that this line does not exist anymore!
1263 if ( nPara
< pEditEngine
->GetParagraphCount() )
1265 // unfortunately I'm not sure that excactly this line does Modified() ...
1267 pProgress
->StepProgress();
1268 ImpDoHighlight( nPara
);
1272 void EditorWindow::DoDelayedSyntaxHighlight( sal_uLong nPara
)
1274 // line is only added to 'Liste' (list), processed in TimerHdl
1275 // => don't manipulate breaks while EditEngine is formatting
1277 pProgress
->StepProgress();
1279 if ( !bHighlightning
&& bDoSyntaxHighlight
)
1281 if ( bDelayHighlight
)
1283 aSyntaxLineTable
.insert( nPara
);
1284 aSyntaxIdle
.Start();
1287 DoSyntaxHighlight( nPara
);
1291 IMPL_LINK_NOARG_TYPED(EditorWindow
, SyntaxTimerHdl
, Idle
*, void)
1293 DBG_ASSERT( pEditView
, "Noch keine View, aber Syntax-Highlight ?!" );
1295 bool const bWasModified
= pEditEngine
->IsModified();
1296 //pEditEngine->SetUpdateMode(false);
1298 bHighlightning
= true;
1299 for ( SyntaxLineSet::const_iterator it
= aSyntaxLineTable
.begin();
1300 it
!= aSyntaxLineTable
.end(); ++it
)
1302 sal_uInt16 nLine
= *it
;
1303 DoSyntaxHighlight( nLine
);
1308 pEditView
->ShowCursor( false, true );
1310 pEditEngine
->SetModified( bWasModified
);
1312 aSyntaxLineTable
.clear();
1313 bHighlightning
= false;
1316 void EditorWindow::ParagraphInsertedDeleted( sal_uLong nPara
, bool bInserted
)
1319 pProgress
->StepProgress();
1321 if ( !bInserted
&& ( nPara
== TEXT_PARA_ALL
) )
1323 rModulWindow
.GetBreakPoints().reset();
1324 rModulWindow
.GetBreakPointWindow().Invalidate();
1325 rModulWindow
.GetLineNumberWindow().Invalidate();
1329 rModulWindow
.GetBreakPoints().AdjustBreakPoints( (sal_uInt16
)nPara
+1, bInserted
);
1331 long nLineHeight
= GetTextHeight();
1332 Size aSz
= rModulWindow
.GetBreakPointWindow().GetOutputSize();
1333 Rectangle
aInvRect( Point( 0, 0 ), aSz
);
1334 long nY
= nPara
*nLineHeight
- rModulWindow
.GetBreakPointWindow().GetCurYOffset();
1335 aInvRect
.Top() = nY
;
1336 rModulWindow
.GetBreakPointWindow().Invalidate( aInvRect
);
1338 Size
aLnSz(rModulWindow
.GetLineNumberWindow().GetWidth(),
1339 GetOutputSizePixel().Height() - 2 * DWBORDER
);
1340 rModulWindow
.GetLineNumberWindow().SetPosSizePixel(Point(DWBORDER
+ 19, DWBORDER
), aLnSz
);
1341 rModulWindow
.GetLineNumberWindow().Invalidate();
1345 void EditorWindow::CreateProgress( const OUString
& rText
, sal_uLong nRange
)
1347 DBG_ASSERT( !pProgress
, "ProgressInfo existiert schon" );
1348 pProgress
.reset(new ProgressInfo(
1349 GetShell()->GetViewFrame()->GetObjectShell(),
1355 void EditorWindow::DestroyProgress()
1360 void EditorWindow::ForceSyntaxTimeout()
1363 aSyntaxIdle
.GetIdleHdl().Call(&aSyntaxIdle
);
1368 BreakPointWindow::BreakPointWindow (vcl::Window
* pParent
, ModulWindow
* pModulWindow
)
1369 : Window(pParent
, WB_BORDER
)
1370 , rModulWindow(*pModulWindow
)
1371 , nCurYOffset(0) // memorize nCurYOffset and not take it from EditEngine
1372 , nMarkerPos(NoMarker
)
1373 , bErrorMarker(false)
1375 setBackgroundColor(GetSettings().GetStyleSettings().GetFieldColor());
1376 SetHelpId(HID_BASICIDE_BREAKPOINTWINDOW
);
1379 void BreakPointWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
&)
1384 Size
const aOutSz
= rRenderContext
.GetOutputSize();
1385 long const nLineHeight
= rRenderContext
.GetTextHeight();
1387 Image
const aBrk
[2] =
1389 GetImage(IMGID_BRKDISABLED
),
1390 GetImage(IMGID_BRKENABLED
)
1393 Size
const aBmpSz
= rRenderContext
.PixelToLogic(aBrk
[1].GetSizePixel());
1394 Point
const aBmpOff((aOutSz
.Width() - aBmpSz
.Width()) / 2,
1395 (nLineHeight
- aBmpSz
.Height()) / 2);
1397 for (size_t i
= 0, n
= GetBreakPoints().size(); i
< n
; ++i
)
1399 BreakPoint
& rBrk
= *GetBreakPoints().at(i
);
1400 size_t const nLine
= rBrk
.nLine
- 1;
1401 size_t const nY
= nLine
*nLineHeight
- nCurYOffset
;
1402 rRenderContext
.DrawImage(Point(0, nY
) + aBmpOff
, aBrk
[rBrk
.bEnabled
]);
1405 ShowMarker(rRenderContext
);
1408 void BreakPointWindow::ShowMarker(vcl::RenderContext
& rRenderContext
)
1410 if (nMarkerPos
== NoMarker
)
1413 Size
const aOutSz
= GetOutputSize();
1414 long const nLineHeight
= GetTextHeight();
1416 Image aMarker
= GetImage(bErrorMarker
? IMGID_ERRORMARKER
: IMGID_STEPMARKER
);
1418 Size
aMarkerSz(aMarker
.GetSizePixel());
1419 aMarkerSz
= rRenderContext
.PixelToLogic(aMarkerSz
);
1420 Point
aMarkerOff(0, 0);
1421 aMarkerOff
.X() = (aOutSz
.Width() - aMarkerSz
.Width()) / 2;
1422 aMarkerOff
.Y() = (nLineHeight
- aMarkerSz
.Height()) / 2;
1424 sal_uLong nY
= nMarkerPos
* nLineHeight
- nCurYOffset
;
1428 rRenderContext
.DrawImage(aPos
, aMarker
);
1431 void BreakPointWindow::DoScroll( long nHorzScroll
, long nVertScroll
)
1433 nCurYOffset
-= nVertScroll
;
1434 Window::Scroll( nHorzScroll
, nVertScroll
);
1437 void BreakPointWindow::SetMarkerPos( sal_uInt16 nLine
, bool bError
)
1439 if ( SyncYOffset() )
1443 bErrorMarker
= bError
;
1447 void BreakPointWindow::SetNoMarker ()
1449 SetMarkerPos(NoMarker
);
1452 BreakPoint
* BreakPointWindow::FindBreakPoint( const Point
& rMousePos
)
1454 size_t nLineHeight
= GetTextHeight();
1455 nLineHeight
= nLineHeight
> 0 ? nLineHeight
: 1;
1456 size_t nYPos
= rMousePos
.Y() + nCurYOffset
;
1458 for ( size_t i
= 0, n
= GetBreakPoints().size(); i
< n
; ++i
)
1460 BreakPoint
* pBrk
= GetBreakPoints().at( i
);
1461 size_t nLine
= pBrk
->nLine
-1;
1462 size_t nY
= nLine
*nLineHeight
;
1463 if ( ( nYPos
> nY
) && ( nYPos
< ( nY
+ nLineHeight
) ) )
1469 void BreakPointWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
1471 if ( rMEvt
.GetClicks() == 2 )
1473 Point
aMousePos( PixelToLogic( rMEvt
.GetPosPixel() ) );
1474 long nLineHeight
= GetTextHeight();
1477 long nYPos
= aMousePos
.Y() + nCurYOffset
;
1478 long nLine
= nYPos
/ nLineHeight
+ 1;
1479 rModulWindow
.ToggleBreakPoint( (sal_uLong
)nLine
);
1485 void BreakPointWindow::Command( const CommandEvent
& rCEvt
)
1487 if ( rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
1489 Point
aPos( rCEvt
.IsMouseEvent() ? rCEvt
.GetMousePosPixel() : Point(1,1) );
1490 Point
aEventPos( PixelToLogic( aPos
) );
1491 BreakPoint
* pBrk
= rCEvt
.IsMouseEvent() ? FindBreakPoint( aEventPos
) : 0;
1494 // test if break point is enabled...
1495 PopupMenu
aBrkPropMenu( IDEResId( RID_POPUP_BRKPROPS
) );
1496 aBrkPropMenu
.CheckItem( RID_ACTIV
, pBrk
->bEnabled
);
1497 switch ( aBrkPropMenu
.Execute( this, aPos
) )
1501 pBrk
->bEnabled
= !pBrk
->bEnabled
;
1502 rModulWindow
.UpdateBreakPoint( *pBrk
);
1508 ScopedVclPtrInstance
< BreakPointDialog
> aBrkDlg( this, GetBreakPoints() );
1509 aBrkDlg
->SetCurrentBreakPoint( pBrk
);
1518 PopupMenu
aBrkListMenu( IDEResId( RID_POPUP_BRKDLG
) );
1519 switch ( aBrkListMenu
.Execute( this, aPos
) )
1523 ScopedVclPtrInstance
< BreakPointDialog
> aBrkDlg( this, GetBreakPoints() );
1533 bool BreakPointWindow::SyncYOffset()
1535 TextView
* pView
= rModulWindow
.GetEditView();
1538 long nViewYOffset
= pView
->GetStartDocPos().Y();
1539 if ( nCurYOffset
!= nViewYOffset
)
1541 nCurYOffset
= nViewYOffset
;
1550 void BreakPointWindow::DataChanged(DataChangedEvent
const & rDCEvt
)
1552 Window::DataChanged(rDCEvt
);
1553 if (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
1554 && (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))
1556 Color
aColor(GetSettings().GetStyleSettings().GetFieldColor());
1557 const AllSettings
* pOldSettings
= rDCEvt
.GetOldSettings();
1558 if (!pOldSettings
|| aColor
!= pOldSettings
->GetStyleSettings().GetFieldColor())
1560 setBackgroundColor(aColor
);
1566 void BreakPointWindow::setBackgroundColor(Color aColor
)
1568 SetBackground(Wallpaper(aColor
));
1573 const sal_uInt16 ITEM_ID_VARIABLE
= 1;
1574 const sal_uInt16 ITEM_ID_VALUE
= 2;
1575 const sal_uInt16 ITEM_ID_TYPE
= 3;
1578 WatchWindow::WatchWindow (Layout
* pParent
) :
1579 DockingWindow(pParent
),
1580 aWatchStr( IDEResId( RID_STR_REMOVEWATCH
) ),
1581 aXEdit( VclPtr
<ExtendedEdit
>::Create(this, IDEResId( RID_EDT_WATCHEDIT
)) ),
1582 aRemoveWatchButton( VclPtr
<ImageButton
>::Create(this, IDEResId( RID_IMGBTN_REMOVEWATCH
)) ),
1583 aTreeListBox( VclPtr
<WatchTreeListBox
>::Create(this, WB_BORDER
| WB_3DLOOK
| WB_HASBUTTONS
| WB_HASLINES
| WB_HSCROLL
| WB_TABSTOP
1584 | WB_HASLINESATROOT
| WB_HASBUTTONSATROOT
) ),
1585 aHeaderBar( VclPtr
<HeaderBar
>::Create( this, WB_BUTTONSTYLE
| WB_BORDER
) )
1587 aXEdit
->SetAccessibleName(IDEResId(RID_STR_WATCHNAME
).toString());
1588 aTreeListBox
->SetAccessibleName(IDEResId(RID_STR_WATCHNAME
).toString());
1590 long nTextLen
= GetTextWidth( aWatchStr
) + DWBORDER
+ 3;
1591 aXEdit
->SetPosPixel( Point( nTextLen
, 3 ) );
1592 aXEdit
->SetAccHdl( LINK( this, WatchWindow
, EditAccHdl
) );
1593 aXEdit
->GetAccelerator().InsertItem( 1, vcl::KeyCode( KEY_RETURN
) );
1594 aXEdit
->GetAccelerator().InsertItem( 2, vcl::KeyCode( KEY_ESCAPE
) );
1597 aRemoveWatchButton
->Disable();
1598 aRemoveWatchButton
->SetClickHdl( LINK( this, WatchWindow
, ButtonHdl
) );
1599 aRemoveWatchButton
->SetPosPixel( Point( nTextLen
+ aXEdit
->GetSizePixel().Width() + 4, 2 ) );
1600 Size
aSz( aRemoveWatchButton
->GetModeImage().GetSizePixel() );
1603 aRemoveWatchButton
->SetSizePixel( aSz
);
1604 aRemoveWatchButton
->Show();
1606 long nRWBtnSize
= aRemoveWatchButton
->GetModeImage().GetSizePixel().Height() + 10;
1607 nVirtToolBoxHeight
= aXEdit
->GetSizePixel().Height() + 7;
1609 if ( nRWBtnSize
> nVirtToolBoxHeight
)
1610 nVirtToolBoxHeight
= nRWBtnSize
;
1612 nHeaderBarHeight
= 16;
1614 aTreeListBox
->SetHelpId(HID_BASICIDE_WATCHWINDOW_LIST
);
1615 aTreeListBox
->EnableInplaceEditing(true);
1616 aTreeListBox
->SetSelectHdl( LINK( this, WatchWindow
, TreeListHdl
) );
1617 aTreeListBox
->SetPosPixel( Point( DWBORDER
, nVirtToolBoxHeight
+ nHeaderBarHeight
) );
1618 aTreeListBox
->SetHighlightRange( 1, 5 );
1620 Point
aPnt( DWBORDER
, nVirtToolBoxHeight
+ 1 );
1621 aHeaderBar
->SetPosPixel( aPnt
);
1622 aHeaderBar
->SetEndDragHdl( LINK( this, WatchWindow
, implEndDragHdl
) );
1624 long nVarTabWidth
= 220;
1625 long nValueTabWidth
= 100;
1626 long nTypeTabWidth
= 1250;
1627 aHeaderBar
->InsertItem( ITEM_ID_VARIABLE
, IDEResId(RID_STR_WATCHVARIABLE
).toString(), nVarTabWidth
);
1628 aHeaderBar
->InsertItem( ITEM_ID_VALUE
, IDEResId(RID_STR_WATCHVALUE
).toString(), nValueTabWidth
);
1629 aHeaderBar
->InsertItem( ITEM_ID_TYPE
, IDEResId(RID_STR_WATCHTYPE
).toString(), nTypeTabWidth
);
1632 tabs
[ 0 ] = 3; // two tabs
1634 tabs
[ 2 ] = nVarTabWidth
;
1635 tabs
[ 3 ] = nVarTabWidth
+ nValueTabWidth
;
1636 aTreeListBox
->SvHeaderTabListBox::SetTabs( tabs
, MAP_PIXEL
);
1637 aTreeListBox
->InitHeaderBar( aHeaderBar
.get() );
1639 aTreeListBox
->SetNodeDefaultImages( );
1643 aTreeListBox
->Show();
1645 SetText(IDEResId(RID_STR_WATCHNAME
).toString());
1647 SetHelpId( HID_BASICIDE_WATCHWINDOW
);
1649 // make watch window keyboard accessible
1650 GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
1655 WatchWindow::~WatchWindow()
1660 void WatchWindow::dispose()
1662 aXEdit
.disposeAndClear();
1663 aRemoveWatchButton
.disposeAndClear();
1664 aHeaderBar
.disposeAndClear();
1665 aTreeListBox
.disposeAndClear();
1667 GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
1668 DockingWindow::dispose();
1671 void WatchWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
&)
1673 rRenderContext
.DrawText(Point(DWBORDER
, 7), aWatchStr
);
1674 lcl_DrawIDEWindowFrame(this, rRenderContext
);
1677 void WatchWindow::Resize()
1679 Size aSz
= GetOutputSizePixel();
1680 Size
aBoxSz( aSz
.Width() - 2*DWBORDER
, aSz
.Height() - nVirtToolBoxHeight
- DWBORDER
);
1682 if ( aBoxSz
.Width() < 4 )
1684 if ( aBoxSz
.Height() < 4 )
1685 aBoxSz
.Height() = 0;
1687 aBoxSz
.Height() -= nHeaderBarHeight
;
1688 aTreeListBox
->SetSizePixel( aBoxSz
);
1689 aTreeListBox
->GetHScroll()->SetPageSize( aTreeListBox
->GetHScroll()->GetVisibleSize() );
1691 aBoxSz
.Height() = nHeaderBarHeight
;
1692 aHeaderBar
->SetSizePixel( aBoxSz
);
1700 OUString maDisplayName
;
1701 SbxObjectRef mpObject
;
1702 std::vector
<OUString
> maMemberList
;
1704 SbxDimArrayRef mpArray
;
1705 int nDimLevel
; // 0 = Root
1707 std::vector
<short> vIndices
;
1709 WatchItem
* mpArrayParentItem
;
1711 explicit WatchItem (OUString
const& rName
):
1715 mpArrayParentItem(0)
1718 void clearWatchItem ()
1720 maMemberList
.clear();
1723 WatchItem
* GetRootItem();
1724 SbxDimArray
* GetRootArray();
1727 WatchItem
* WatchItem::GetRootItem()
1729 WatchItem
* pItem
= mpArrayParentItem
;
1732 if( pItem
->mpArray
.Is() )
1734 pItem
= pItem
->mpArrayParentItem
;
1739 SbxDimArray
* WatchItem::GetRootArray()
1741 WatchItem
* pRootItem
= GetRootItem();
1742 SbxDimArray
* pRet
= NULL
;
1744 pRet
= pRootItem
->mpArray
;
1748 void WatchWindow::AddWatch( const OUString
& rVName
)
1750 OUString aVar
, aIndex
;
1751 lcl_SeparateNameAndIndex( rVName
, aVar
, aIndex
);
1752 WatchItem
* pWatchItem
= new WatchItem(aVar
);
1754 OUString
aWatchStr_( aVar
);
1755 aWatchStr_
+= "\t\t";
1756 SvTreeListEntry
* pNewEntry
= aTreeListBox
->InsertEntry( aWatchStr_
, 0, true, TREELIST_APPEND
);
1757 pNewEntry
->SetUserData( pWatchItem
);
1759 aTreeListBox
->Select(pNewEntry
, true);
1760 aTreeListBox
->MakeVisible(pNewEntry
);
1761 aRemoveWatchButton
->Enable();
1766 bool WatchWindow::RemoveSelectedWatch()
1768 SvTreeListEntry
* pEntry
= aTreeListBox
->GetCurEntry();
1771 aTreeListBox
->GetModel()->Remove( pEntry
);
1772 pEntry
= aTreeListBox
->GetCurEntry();
1774 aXEdit
->SetText( static_cast<WatchItem
*>(pEntry
->GetUserData())->maName
);
1776 aXEdit
->SetText( OUString() );
1777 if ( !aTreeListBox
->GetEntryCount() )
1778 aRemoveWatchButton
->Disable();
1786 IMPL_LINK( WatchWindow
, ButtonHdl
, ImageButton
*, pButton
)
1788 if (pButton
== aRemoveWatchButton
.get())
1789 if (SfxDispatcher
* pDispatcher
= GetDispatcher())
1790 pDispatcher
->Execute(SID_BASICIDE_REMOVEWATCH
);
1794 IMPL_LINK_NOARG(WatchWindow
, TreeListHdl
)
1796 SvTreeListEntry
* pCurEntry
= aTreeListBox
->GetCurEntry();
1797 if ( pCurEntry
&& pCurEntry
->GetUserData() )
1798 aXEdit
->SetText( static_cast<WatchItem
*>(pCurEntry
->GetUserData())->maName
);
1803 IMPL_LINK( WatchWindow
, implEndDragHdl
, HeaderBar
*, pBar
)
1807 const sal_Int32 TAB_WIDTH_MIN
= 10;
1808 sal_Int32 nMaxWidth
=
1809 aHeaderBar
->GetSizePixel().getWidth() - 2 * TAB_WIDTH_MIN
;
1811 sal_Int32 nVariableWith
= aHeaderBar
->GetItemSize( ITEM_ID_VARIABLE
);
1812 if( nVariableWith
< TAB_WIDTH_MIN
)
1813 aHeaderBar
->SetItemSize( ITEM_ID_VARIABLE
, TAB_WIDTH_MIN
);
1814 else if( nVariableWith
> nMaxWidth
)
1815 aHeaderBar
->SetItemSize( ITEM_ID_VARIABLE
, nMaxWidth
);
1817 sal_Int32 nValueWith
= aHeaderBar
->GetItemSize( ITEM_ID_VALUE
);
1818 if( nValueWith
< TAB_WIDTH_MIN
)
1819 aHeaderBar
->SetItemSize( ITEM_ID_VALUE
, TAB_WIDTH_MIN
);
1820 else if( nValueWith
> nMaxWidth
)
1821 aHeaderBar
->SetItemSize( ITEM_ID_VALUE
, nMaxWidth
);
1823 if (aHeaderBar
->GetItemSize( ITEM_ID_TYPE
) < TAB_WIDTH_MIN
)
1824 aHeaderBar
->SetItemSize( ITEM_ID_TYPE
, TAB_WIDTH_MIN
);
1827 sal_uInt16 nTabs
= aHeaderBar
->GetItemCount();
1828 for( sal_uInt16 i
= 1 ; i
< nTabs
; ++i
)
1830 nPos
+= aHeaderBar
->GetItemSize( i
);
1831 aTreeListBox
->SetTab( i
, nPos
, MAP_PIXEL
);
1836 IMPL_LINK_TYPED( WatchWindow
, EditAccHdl
, Accelerator
*, pAcc
, void )
1838 switch ( pAcc
->GetCurKeyCode().GetCode() )
1842 OUString
aCurText( aXEdit
->GetText() );
1843 if ( !aCurText
.isEmpty() )
1845 AddWatch( aCurText
);
1846 aXEdit
->SetSelection( Selection( 0, 0xFFFF ) );
1852 aXEdit
->SetText( OUString() );
1858 void WatchWindow::UpdateWatches( bool bBasicStopped
)
1860 aTreeListBox
->UpdateWatches( bBasicStopped
);
1869 StackWindow::StackWindow (Layout
* pParent
) :
1870 DockingWindow(pParent
),
1871 aTreeListBox( VclPtr
<SvTreeListBox
>::Create(this, WB_BORDER
| WB_3DLOOK
| WB_HSCROLL
| WB_TABSTOP
) ),
1872 aStackStr( IDEResId( RID_STR_STACK
) )
1874 aTreeListBox
->SetHelpId(HID_BASICIDE_STACKWINDOW_LIST
);
1875 aTreeListBox
->SetAccessibleName(IDEResId(RID_STR_STACKNAME
).toString());
1876 aTreeListBox
->SetPosPixel( Point( DWBORDER
, nVirtToolBoxHeight
) );
1877 aTreeListBox
->SetHighlightRange();
1878 aTreeListBox
->SetSelectionMode( NO_SELECTION
);
1879 aTreeListBox
->InsertEntry( OUString(), 0, false, TREELIST_APPEND
);
1880 aTreeListBox
->Show();
1882 SetText(IDEResId(RID_STR_STACKNAME
).toString());
1884 SetHelpId( HID_BASICIDE_STACKWINDOW
);
1886 // make stack window keyboard accessible
1887 GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
1892 StackWindow::~StackWindow()
1897 void StackWindow::dispose()
1900 GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
1901 aTreeListBox
.disposeAndClear();
1902 DockingWindow::dispose();
1905 void StackWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
&)
1907 rRenderContext
.DrawText(Point(DWBORDER
, 7), aStackStr
);
1908 lcl_DrawIDEWindowFrame(this, rRenderContext
);
1911 void StackWindow::Resize()
1913 Size aSz
= GetOutputSizePixel();
1914 Size
aBoxSz(aSz
.Width() - 2*DWBORDER
, aSz
.Height() - nVirtToolBoxHeight
- DWBORDER
);
1916 if ( aBoxSz
.Width() < 4 )
1918 if ( aBoxSz
.Height() < 4 )
1919 aBoxSz
.Height() = 0;
1921 aTreeListBox
->SetSizePixel( aBoxSz
);
1926 void StackWindow::UpdateCalls()
1928 aTreeListBox
->SetUpdateMode(false);
1929 aTreeListBox
->Clear();
1931 if (StarBASIC::IsRunning())
1933 SbxError eOld
= SbxBase::GetError();
1934 aTreeListBox
->SetSelectionMode( SINGLE_SELECTION
);
1936 sal_Int32 nScope
= 0;
1937 SbMethod
* pMethod
= StarBASIC::GetActiveMethod( nScope
);
1940 OUString
aEntry( OUString::number(nScope
));
1941 if ( aEntry
.getLength() < 2 )
1942 aEntry
= " " + aEntry
;
1943 aEntry
+= ": " + pMethod
->GetName();
1944 SbxArray
* pParams
= pMethod
->GetParameters();
1945 SbxInfo
* pInfo
= pMethod
->GetInfo();
1949 // 0 is the sub's name...
1950 for ( sal_uInt16 nParam
= 1; nParam
< pParams
->Count(); nParam
++ )
1952 SbxVariable
* pVar
= pParams
->Get( nParam
);
1953 assert(pVar
&& "Parameter?!");
1954 if ( !pVar
->GetName().isEmpty() )
1956 aEntry
+= pVar
->GetName();
1960 const SbxParamInfo
* pParam
= pInfo
->GetParam( nParam
);
1963 aEntry
+= pParam
->aName
;
1967 SbxDataType eType
= pVar
->GetType();
1968 if( eType
& SbxARRAY
)
1972 else if( eType
!= SbxOBJECT
)
1974 aEntry
+= pVar
->GetOUString();
1976 if ( nParam
< ( pParams
->Count() - 1 ) )
1983 aTreeListBox
->InsertEntry( aEntry
, 0, false, TREELIST_APPEND
);
1985 pMethod
= StarBASIC::GetActiveMethod( nScope
);
1988 SbxBase::ResetError();
1989 if( eOld
!= SbxERR_OK
)
1990 SbxBase::SetError( eOld
);
1994 aTreeListBox
->SetSelectionMode( NO_SELECTION
);
1995 aTreeListBox
->InsertEntry( OUString(), 0, false, TREELIST_APPEND
);
1998 aTreeListBox
->SetUpdateMode(true);
2001 ComplexEditorWindow::ComplexEditorWindow( ModulWindow
* pParent
) :
2002 Window( pParent
, WB_3DLOOK
| WB_CLIPCHILDREN
),
2003 aBrkWindow(VclPtr
<BreakPointWindow
>::Create(this, pParent
)),
2004 aLineNumberWindow(VclPtr
<LineNumberWindow
>::Create(this, pParent
)),
2005 aEdtWindow(VclPtr
<EditorWindow
>::Create(this, pParent
)),
2006 aEWVScrollBar( VclPtr
<ScrollBar
>::Create(this, WB_VSCROLL
| WB_DRAG
) )
2011 aEWVScrollBar
->SetLineSize(nScrollLine
);
2012 aEWVScrollBar
->SetPageSize(nScrollPage
);
2013 aEWVScrollBar
->SetScrollHdl( LINK( this, ComplexEditorWindow
, ScrollHdl
) );
2014 aEWVScrollBar
->Show();
2017 ComplexEditorWindow::~ComplexEditorWindow()
2022 void ComplexEditorWindow::dispose()
2024 aBrkWindow
.disposeAndClear();
2025 aLineNumberWindow
.disposeAndClear();
2026 aEdtWindow
.disposeAndClear();
2027 aEWVScrollBar
.disposeAndClear();
2028 vcl::Window::dispose();
2031 void ComplexEditorWindow::Resize()
2033 Size aOutSz
= GetOutputSizePixel();
2035 aSz
.Width() -= 2*DWBORDER
;
2036 aSz
.Height() -= 2*DWBORDER
;
2037 long nBrkWidth
= 20;
2038 long nSBWidth
= aEWVScrollBar
->GetSizePixel().Width();
2040 Size
aBrkSz(nBrkWidth
, aSz
.Height());
2042 Size
aLnSz(aLineNumberWindow
->GetWidth(), aSz
.Height());
2044 if (aLineNumberWindow
->IsVisible())
2046 aBrkWindow
->SetPosSizePixel( Point( DWBORDER
, DWBORDER
), aBrkSz
);
2047 aLineNumberWindow
->SetPosSizePixel(Point(DWBORDER
+ aBrkSz
.Width() - 1, DWBORDER
), aLnSz
);
2048 Size
aEWSz(aSz
.Width() - nBrkWidth
- aLineNumberWindow
->GetWidth() - nSBWidth
+ 2, aSz
.Height());
2049 aEdtWindow
->SetPosSizePixel( Point( DWBORDER
+ aBrkSz
.Width() + aLnSz
.Width() - 1, DWBORDER
), aEWSz
);
2053 aBrkWindow
->SetPosSizePixel( Point( DWBORDER
, DWBORDER
), aBrkSz
);
2054 Size
aEWSz(aSz
.Width() - nBrkWidth
- nSBWidth
+ 2, aSz
.Height());
2055 aEdtWindow
->SetPosSizePixel(Point(DWBORDER
+ aBrkSz
.Width() - 1, DWBORDER
), aEWSz
);
2058 aEWVScrollBar
->SetPosSizePixel( Point( aOutSz
.Width() - DWBORDER
- nSBWidth
, DWBORDER
), Size( nSBWidth
, aSz
.Height() ) );
2061 IMPL_LINK(ComplexEditorWindow
, ScrollHdl
, ScrollBar
*, pCurScrollBar
)
2063 if (aEdtWindow
->GetEditView())
2065 DBG_ASSERT( pCurScrollBar
== aEWVScrollBar
.get(), "Wer scrollt hier ?" );
2066 long nDiff
= aEdtWindow
->GetEditView()->GetStartDocPos().Y() - pCurScrollBar
->GetThumbPos();
2067 aEdtWindow
->GetEditView()->Scroll( 0, nDiff
);
2068 aBrkWindow
->DoScroll( 0, nDiff
);
2069 aLineNumberWindow
->DoScroll(0, nDiff
);
2070 aEdtWindow
->GetEditView()->ShowCursor(false, true);
2071 pCurScrollBar
->SetThumbPos( aEdtWindow
->GetEditView()->GetStartDocPos().Y() );
2077 void ComplexEditorWindow::DataChanged(DataChangedEvent
const & rDCEvt
)
2079 Window::DataChanged(rDCEvt
);
2080 if (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
2081 && (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))
2083 Color
aColor(GetSettings().GetStyleSettings().GetFaceColor());
2084 const AllSettings
* pOldSettings
= rDCEvt
.GetOldSettings();
2085 if (!pOldSettings
|| aColor
!= pOldSettings
->GetStyleSettings().GetFaceColor())
2087 SetBackground(Wallpaper(aColor
));
2093 void ComplexEditorWindow::SetLineNumberDisplay(bool b
)
2095 aLineNumberWindow
->Show(b
);
2099 uno::Reference
< awt::XWindowPeer
>
2100 EditorWindow::GetComponentInterface(bool bCreate
)
2102 uno::Reference
< awt::XWindowPeer
> xPeer(
2103 Window::GetComponentInterface(false));
2104 if (!xPeer
.is() && bCreate
)
2106 // Make sure edit engine and view are available:
2110 xPeer
= svt::createTextWindowPeer(*GetEditView());
2111 SetComponentInterface(xPeer
);
2122 WatchTreeListBox::WatchTreeListBox( vcl::Window
* pParent
, WinBits nWinBits
)
2123 : SvHeaderTabListBox( pParent
, nWinBits
)
2126 WatchTreeListBox::~WatchTreeListBox()
2131 void WatchTreeListBox::dispose()
2133 // Destroy user data
2134 SvTreeListEntry
* pEntry
= First();
2137 delete static_cast<WatchItem
*>(pEntry
->GetUserData());
2138 pEntry
->SetUserData(NULL
);
2139 pEntry
= Next( pEntry
);
2141 SvHeaderTabListBox::dispose();
2144 void WatchTreeListBox::SetTabs()
2146 SvHeaderTabListBox::SetTabs();
2147 sal_uInt16 nTabCount_
= aTabs
.size();
2148 for( sal_uInt16 i
= 0 ; i
< nTabCount_
; i
++ )
2150 SvLBoxTab
* pTab
= aTabs
[i
];
2152 pTab
->nFlags
|= SvLBoxTabFlags::EDITABLE
;
2154 pTab
->nFlags
&= ~SvLBoxTabFlags::EDITABLE
;
2158 void WatchTreeListBox::RequestingChildren( SvTreeListEntry
* pParent
)
2160 if( !StarBASIC::IsRunning() )
2163 if( GetChildCount( pParent
) > 0 )
2166 SvTreeListEntry
* pEntry
= pParent
;
2167 WatchItem
* pItem
= static_cast<WatchItem
*>(pEntry
->GetUserData());
2169 SbxDimArray
* pArray
= pItem
->mpArray
;
2170 SbxDimArray
* pRootArray
= pItem
->GetRootArray();
2171 bool bArrayIsRootArray
= false;
2172 if( !pArray
&& pRootArray
)
2174 pArray
= pRootArray
;
2175 bArrayIsRootArray
= true;
2178 SbxObject
* pObj
= pItem
->mpObject
;
2181 createAllObjectProperties( pObj
);
2182 SbxArray
* pProps
= pObj
->GetProperties();
2183 sal_uInt16 nPropCount
= pProps
->Count();
2184 if ( nPropCount
>= 3 &&
2185 pProps
->Get( nPropCount
-1 )->GetName().equalsIgnoreAsciiCase( "Dbg_Methods" ) &&
2186 pProps
->Get( nPropCount
-2 )->GetName().equalsIgnoreAsciiCase( "Dbg_Properties" ) &&
2187 pProps
->Get( nPropCount
-3 )->GetName().equalsIgnoreAsciiCase( "Dbg_SupportedInterfaces" ) )
2191 pItem
->maMemberList
.reserve(nPropCount
);
2193 for( sal_uInt16 i
= 0 ; i
< nPropCount
; ++i
)
2195 SbxVariable
* pVar
= pProps
->Get( i
);
2197 pItem
->maMemberList
.push_back(pVar
->GetName());
2198 OUString
const& rName
= pItem
->maMemberList
.back();
2199 SvTreeListEntry
* pChildEntry
= SvTreeListBox::InsertEntry( rName
, pEntry
);
2200 pChildEntry
->SetUserData(new WatchItem(rName
));
2202 if( nPropCount
> 0 )
2209 sal_uInt16 nElementCount
= 0;
2211 // Loop through indices of current level
2212 int nParentLevel
= bArrayIsRootArray
? pItem
->nDimLevel
: 0;
2213 int nThisLevel
= nParentLevel
+ 1;
2214 sal_Int32 nMin
, nMax
;
2215 pArray
->GetDim32( nThisLevel
, nMin
, nMax
);
2216 for( sal_Int32 i
= nMin
; i
<= nMax
; i
++ )
2218 WatchItem
* pChildItem
= new WatchItem(pItem
->maName
);
2220 // Copy data and create name
2222 OUString aIndexStr
= "(";
2223 pChildItem
->mpArrayParentItem
= pItem
;
2224 pChildItem
->nDimLevel
= nThisLevel
;
2225 pChildItem
->nDimCount
= pItem
->nDimCount
;
2226 pChildItem
->vIndices
.resize(pChildItem
->nDimCount
);
2228 for( j
= 0 ; j
< nParentLevel
; j
++ )
2230 short n
= pChildItem
->vIndices
[j
] = pItem
->vIndices
[j
];
2231 aIndexStr
+= OUString::number( n
) + ",";
2233 pChildItem
->vIndices
[nParentLevel
] = sal::static_int_cast
<short>( i
);
2234 aIndexStr
+= OUString::number( i
) + ")";
2236 OUString aDisplayName
;
2237 WatchItem
* pArrayRootItem
= pChildItem
->GetRootItem();
2238 if( pArrayRootItem
&& pArrayRootItem
->mpArrayParentItem
)
2239 aDisplayName
= pItem
->maDisplayName
;
2241 aDisplayName
= pItem
->maName
;
2242 aDisplayName
+= aIndexStr
;
2243 pChildItem
->maDisplayName
= aDisplayName
;
2245 SvTreeListEntry
* pChildEntry
= SvTreeListBox::InsertEntry( aDisplayName
, pEntry
);
2247 pChildEntry
->SetUserData( pChildItem
);
2249 if( nElementCount
> 0 )
2256 SbxBase
* WatchTreeListBox::ImplGetSBXForEntry( SvTreeListEntry
* pEntry
, bool& rbArrayElement
)
2258 SbxBase
* pSBX
= NULL
;
2259 rbArrayElement
= false;
2261 WatchItem
* pItem
= static_cast<WatchItem
*>(pEntry
->GetUserData());
2262 OUString
aVName( pItem
->maName
);
2264 SvTreeListEntry
* pParentEntry
= GetParent( pEntry
);
2265 WatchItem
* pParentItem
= pParentEntry
? static_cast<WatchItem
*>(pParentEntry
->GetUserData()) : NULL
;
2268 SbxObject
* pObj
= pParentItem
->mpObject
;
2269 SbxDimArray
* pArray
;
2272 pSBX
= pObj
->Find( aVName
, SbxCLASS_DONTCARE
);
2273 if (SbxVariable
const* pVar
= IsSbxVariable(pSBX
))
2275 // Force getting value
2277 aRes
.eType
= SbxVOID
;
2282 else if( (pArray
= pItem
->GetRootArray()) != NULL
)
2284 rbArrayElement
= true;
2285 if( pParentItem
->nDimLevel
+ 1 == pParentItem
->nDimCount
)
2286 pSBX
= pArray
->Get(pItem
->vIndices
.empty() ? 0 : &*pItem
->vIndices
.begin());
2291 pSBX
= StarBASIC::FindSBXInCurrentScope( aVName
);
2296 bool WatchTreeListBox::EditingEntry( SvTreeListEntry
* pEntry
, Selection
& )
2298 WatchItem
* pItem
= static_cast<WatchItem
*>(pEntry
->GetUserData());
2301 if ( StarBASIC::IsRunning() && StarBASIC::GetActiveMethod() && !SbxBase::IsError() )
2303 // No out of scope entries
2305 SbxBase
* pSbx
= ImplGetSBXForEntry( pEntry
, bArrayElement
);
2306 if (IsSbxVariable(pSbx
) || bArrayElement
)
2308 // Accept no objects and only end nodes of arrays for editing
2309 if( !pItem
->mpObject
&& (pItem
->mpArray
== NULL
|| pItem
->nDimLevel
== pItem
->nDimCount
) )
2311 aEditingRes
= SvHeaderTabListBox::GetEntryText( pEntry
, ITEM_ID_VALUE
-1 );
2312 aEditingRes
= comphelper::string::strip(aEditingRes
, ' ');
2321 bool WatchTreeListBox::EditedEntry( SvTreeListEntry
* pEntry
, const OUString
& rNewText
)
2323 OUString aResult
= comphelper::string::strip(rNewText
, ' ');
2325 sal_uInt16 nResultLen
= aResult
.getLength();
2326 sal_Unicode cFirst
= aResult
[0];
2327 sal_Unicode cLast
= aResult
[ nResultLen
- 1 ];
2328 if( cFirst
== '\"' && cLast
== '\"' )
2329 aResult
= aResult
.copy( 1, nResultLen
- 2 );
2331 return aResult
!= aEditingRes
&& ImplBasicEntryEdited(pEntry
, aResult
);
2334 bool WatchTreeListBox::ImplBasicEntryEdited( SvTreeListEntry
* pEntry
, const OUString
& rResult
)
2337 SbxBase
* pSBX
= ImplGetSBXForEntry( pEntry
, bArrayElement
);
2339 if (SbxVariable
* pVar
= IsSbxVariable(pSBX
))
2341 SbxDataType eType
= pVar
->GetType();
2342 if ( (sal_uInt8
)eType
!= (sal_uInt8
)SbxOBJECT
2343 && ( eType
& SbxARRAY
) == 0 )
2345 // If the type is variable, the conversion of the SBX does not matter,
2346 // else the string is converted.
2347 pVar
->PutStringExt( rResult
);
2351 if ( SbxBase::IsError() )
2353 SbxBase::ResetError();
2358 // The text should never be taken/copied 1:1,
2359 // as the UpdateWatches will be lost
2367 void implCollapseModifiedObjectEntry( SvTreeListEntry
* pParent
, WatchTreeListBox
* pThis
)
2369 pThis
->Collapse( pParent
);
2371 SvTreeList
* pModel
= pThis
->GetModel();
2372 SvTreeListEntry
* pDeleteEntry
;
2373 while( (pDeleteEntry
= pThis
->SvTreeListBox::GetEntry( pParent
, 0 )) != NULL
)
2375 implCollapseModifiedObjectEntry( pDeleteEntry
, pThis
);
2377 delete static_cast<WatchItem
*>(pDeleteEntry
->GetUserData());
2378 pModel
->Remove( pDeleteEntry
);
2382 OUString
implCreateTypeStringForDimArray( WatchItem
* pItem
, SbxDataType eType
)
2384 OUString aRetStr
= getBasicTypeName( eType
);
2386 SbxDimArray
* pArray
= pItem
->mpArray
;
2388 pArray
= pItem
->GetRootArray();
2391 int nDimLevel
= pItem
->nDimLevel
;
2392 int nDims
= pItem
->nDimCount
;
2393 if( nDimLevel
< nDims
)
2396 for( int i
= nDimLevel
; i
< nDims
; i
++ )
2399 pArray
->GetDim( sal::static_int_cast
<short>( i
+1 ), nMin
, nMax
);
2400 aRetStr
+= OUString::number(nMin
) + " to " + OUString::number(nMax
);
2410 void implEnableChildren( SvTreeListEntry
* pEntry
, bool bEnable
)
2415 (pEntry
->GetFlags() & ~SvTLEntryFlags(SvTLEntryFlags::NO_NODEBMP
| SvTLEntryFlags::HAD_CHILDREN
))
2416 | SvTLEntryFlags::CHILDREN_ON_DEMAND
);
2420 pEntry
->SetFlags( pEntry
->GetFlags() & ~SvTLEntryFlags::CHILDREN_ON_DEMAND
);
2426 void WatchTreeListBox::UpdateWatches( bool bBasicStopped
)
2428 SbMethod
* pCurMethod
= StarBASIC::GetActiveMethod();
2430 SbxError eOld
= SbxBase::GetError();
2431 setBasicWatchMode( true );
2433 SvTreeListEntry
* pEntry
= First();
2436 WatchItem
* pItem
= static_cast<WatchItem
*>(pEntry
->GetUserData());
2437 DBG_ASSERT( !pItem
->maName
.isEmpty(), "Var? - Must not be empty!" );
2443 SbxBase
* pSBX
= ImplGetSBXForEntry( pEntry
, bArrayElement
);
2445 // Array? If no end node create type string
2446 if( bArrayElement
&& pItem
->nDimLevel
< pItem
->nDimCount
)
2448 SbxDimArray
* pRootArray
= pItem
->GetRootArray();
2449 SbxDataType eType
= pRootArray
->GetType();
2450 aTypeStr
= implCreateTypeStringForDimArray( pItem
, eType
);
2451 implEnableChildren( pEntry
, true );
2454 bool bCollapse
= false;
2455 if (SbxVariable
const* pVar
= IsSbxVariable(pSBX
))
2457 // extra treatment of arrays
2458 SbxDataType eType
= pVar
->GetType();
2459 if ( eType
& SbxARRAY
)
2461 // consider multidimensinal arrays!
2462 if (SbxDimArray
* pNewArray
= dynamic_cast<SbxDimArray
*>(pVar
->GetObject()))
2464 SbxDimArray
* pOldArray
= pItem
->mpArray
;
2466 bool bArrayChanged
= false;
2467 if( pNewArray
!= NULL
&& pOldArray
!= NULL
)
2469 // Compare Array dimensions to see if array has changed
2470 // Can be a copy, so comparing pointers does not work
2471 sal_uInt16 nOldDims
= pOldArray
->GetDims();
2472 sal_uInt16 nNewDims
= pNewArray
->GetDims();
2473 if( nOldDims
!= nNewDims
)
2475 bArrayChanged
= true;
2479 for( int i
= 0 ; i
< nOldDims
; i
++ )
2481 short nOldMin
, nOldMax
;
2482 short nNewMin
, nNewMax
;
2484 pOldArray
->GetDim( sal::static_int_cast
<short>( i
+1 ), nOldMin
, nOldMax
);
2485 pNewArray
->GetDim( sal::static_int_cast
<short>( i
+1 ), nNewMin
, nNewMax
);
2486 if( nOldMin
!= nNewMin
|| nOldMax
!= nNewMax
)
2488 bArrayChanged
= true;
2494 else if( pNewArray
== NULL
|| pOldArray
== NULL
)
2496 bArrayChanged
= true;
2500 implEnableChildren( pEntry
, true );
2502 // #i37227 Clear always and replace array
2503 if( pNewArray
!= pOldArray
)
2505 pItem
->clearWatchItem();
2508 implEnableChildren( pEntry
, true );
2510 pItem
->mpArray
= pNewArray
;
2511 sal_uInt16 nDims
= pNewArray
->GetDims();
2512 pItem
->nDimLevel
= 0;
2513 pItem
->nDimCount
= nDims
;
2516 if( bArrayChanged
&& pOldArray
!= NULL
)
2520 aTypeStr
= implCreateTypeStringForDimArray( pItem
, eType
);
2527 else if ( (sal_uInt8
)eType
== (sal_uInt8
)SbxOBJECT
)
2529 if (SbxObject
* pObj
= dynamic_cast<SbxObject
*>(pVar
->GetObject()))
2531 if (pItem
->mpObject
&& !pItem
->maMemberList
.empty())
2533 bool bObjChanged
= false; // Check if member list has changed
2534 SbxArray
* pProps
= pObj
->GetProperties();
2535 sal_uInt16 nPropCount
= pProps
->Count();
2536 for( sal_uInt16 i
= 0 ; i
< nPropCount
- 3 ; i
++ )
2538 SbxVariable
* pVar_
= pProps
->Get( i
);
2539 OUString
aName( pVar_
->GetName() );
2540 if( pItem
->maMemberList
[i
] != aName
)
2552 pItem
->mpObject
= pObj
;
2553 implEnableChildren( pEntry
, true );
2554 aTypeStr
= getBasicObjectTypeName( pObj
);
2559 if( pItem
->mpObject
!= NULL
)
2562 pItem
->clearWatchItem();
2564 implEnableChildren( pEntry
, false );
2570 if( pItem
->mpObject
!= NULL
)
2573 pItem
->clearWatchItem();
2575 implEnableChildren( pEntry
, false );
2578 bool bString
= ((sal_uInt8
)eType
== (sal_uInt8
)SbxSTRING
);
2579 OUString
aStrStr( "\"" );
2582 aWatchStr
+= aStrStr
;
2584 aWatchStr
+= pVar
->GetOUString();
2587 aWatchStr
+= aStrStr
;
2590 if( aTypeStr
.isEmpty() )
2592 if( !pVar
->IsFixed() )
2594 aTypeStr
= "Variant/";
2596 aTypeStr
+= getBasicTypeName( pVar
->GetType() );
2599 else if( !bArrayElement
)
2601 aWatchStr
+= "<Out of Scope>";
2606 implCollapseModifiedObjectEntry( pEntry
, this );
2610 else if( bBasicStopped
)
2612 if( pItem
->mpObject
|| pItem
->mpArray
)
2614 implCollapseModifiedObjectEntry( pEntry
, this );
2615 pItem
->mpObject
= NULL
;
2619 SvHeaderTabListBox::SetEntryText( aWatchStr
, pEntry
, ITEM_ID_VALUE
-1 );
2620 SvHeaderTabListBox::SetEntryText( aTypeStr
, pEntry
, ITEM_ID_TYPE
-1 );
2622 pEntry
= Next( pEntry
);
2628 SbxBase::ResetError();
2629 if( eOld
!= SbxERR_OK
)
2630 SbxBase::SetError( eOld
);
2631 setBasicWatchMode( false );
2634 CodeCompleteListBox::CodeCompleteListBox( CodeCompleteWindow
* pPar
)
2635 : ListBox(pPar
, WB_SORT
| WB_BORDER
),
2636 pCodeCompleteWindow( pPar
)
2638 SetDoubleClickHdl(LINK(this, CodeCompleteListBox
, ImplDoubleClickHdl
));
2639 SetSelectHdl(LINK(this, CodeCompleteListBox
, ImplSelectHdl
));
2642 CodeCompleteListBox::~CodeCompleteListBox()
2647 void CodeCompleteListBox::dispose()
2649 pCodeCompleteWindow
.clear();
2653 IMPL_LINK_NOARG(CodeCompleteListBox
, ImplDoubleClickHdl
)
2655 InsertSelectedEntry();
2659 IMPL_LINK_NOARG(CodeCompleteListBox
, ImplSelectHdl
)
2660 {//give back the focus to the parent
2661 pCodeCompleteWindow
->pParent
->GrabFocus();
2665 ExtTextView
* CodeCompleteListBox::GetParentEditView()
2667 return pCodeCompleteWindow
->pParent
->GetEditView();
2670 void CodeCompleteListBox::InsertSelectedEntry()
2672 if( !aFuncBuffer
.toString().isEmpty() )
2674 // if the user typed in something: remove, and insert
2675 GetParentEditView()->SetSelection( pCodeCompleteWindow
->pParent
->GetLastHighlightPortionTextSelection() );
2676 GetParentEditView()->DeleteSelected();
2678 if( !GetSelectEntry().isEmpty() )
2679 {//if the user selected something
2680 GetParentEditView()->InsertText( GetSelectEntry(), false );
2685 if( !GetSelectEntry().isEmpty() )
2686 {//if the user selected something
2687 GetParentEditView()->InsertText( GetSelectEntry(), false );
2690 HideAndRestoreFocus();
2693 void CodeCompleteListBox::SetMatchingEntries()
2695 for(sal_uInt16 i
=0; i
< GetEntryCount(); ++i
)
2697 OUString sEntry
= GetEntry(i
);
2698 if( sEntry
.startsWithIgnoreAsciiCase( aFuncBuffer
.toString() ) )
2700 SelectEntry(sEntry
);
2706 void CodeCompleteListBox::KeyInput( const KeyEvent
& rKeyEvt
)
2708 sal_Unicode aChar
= rKeyEvt
.GetKeyCode().GetCode();
2709 if( (( aChar
>= KEY_A
) && ( aChar
<= KEY_Z
))
2710 || ((aChar
>= KEY_0
) && (aChar
<= KEY_9
)) )
2712 aFuncBuffer
.append(rKeyEvt
.GetCharCode());
2713 SetMatchingEntries();
2719 case KEY_ESCAPE
: // hide, do nothing
2720 HideAndRestoreFocus();
2724 TextSelection
aTextSelection( GetParentEditView()->GetSelection() );
2725 if( aTextSelection
.GetEnd().GetPara() != pCodeCompleteWindow
->GetTextSelection().GetEnd().GetPara()-1 )
2727 HideAndRestoreFocus();
2733 TextSelection
aTextSelection( GetParentEditView()->GetSelection() );
2734 if( aTextSelection
.GetStart().GetIndex()-1 < pCodeCompleteWindow
->GetTextSelection().GetStart().GetIndex() )
2735 {//leave the cursor where it is
2736 HideAndRestoreFocus();
2742 TextSelection aTextSelection
= pCodeCompleteWindow
->pParent
->GetLastHighlightPortionTextSelection();
2743 OUString sTypedText
= pCodeCompleteWindow
->pParent
->GetEditEngine()->GetText(aTextSelection
);
2744 if( !aFuncBuffer
.isEmpty() )
2746 sal_Int32 nInd
= GetSelectEntryPos();
2747 if( nInd
!= LISTBOX_ENTRY_NOTFOUND
)
2748 {//if there is something selected
2749 bool bFound
= false;
2750 if( nInd
== GetEntryCount() )
2752 for( sal_Int32 i
= nInd
; i
!= GetEntryCount(); ++i
)
2754 OUString sEntry
= GetEntry(i
);
2755 if( sEntry
.startsWithIgnoreAsciiCase( aFuncBuffer
.toString() )
2756 && (aFuncBuffer
.toString() != sTypedText
) && (i
!= nInd
) )
2758 SelectEntry( sEntry
);
2764 SetMatchingEntries();
2766 GetParentEditView()->SetSelection( aTextSelection
);
2767 GetParentEditView()->DeleteSelected();
2768 GetParentEditView()->InsertText( GetSelectEntry(), false );
2774 HideAndRestoreFocus();
2776 case KEY_BACKSPACE
: case KEY_DELETE
:
2777 if( !aFuncBuffer
.toString().isEmpty() )
2779 //if there was something inserted by tab: add it to aFuncBuffer
2780 TextSelection
aSel( GetParentEditView()->GetSelection() );
2781 TextPaM
aEnd( GetParentEditView()->CursorEndOfLine(pCodeCompleteWindow
->GetTextSelection().GetEnd()) );
2782 GetParentEditView()->SetSelection(TextSelection(pCodeCompleteWindow
->GetTextSelection().GetStart(), aEnd
) );
2783 OUString
aTabInsertedStr( GetParentEditView()->GetSelected() );
2784 GetParentEditView()->SetSelection( aSel
);
2786 if( !aTabInsertedStr
.isEmpty() && aTabInsertedStr
!= aFuncBuffer
.toString() )
2788 aFuncBuffer
.makeStringAndClear();
2789 aFuncBuffer
= aFuncBuffer
.append(aTabInsertedStr
);
2791 aFuncBuffer
= aFuncBuffer
.remove(aFuncBuffer
.getLength()-1, 1);
2792 SetMatchingEntries();
2795 pCodeCompleteWindow
->ClearAndHide();
2798 InsertSelectedEntry();
2800 case KEY_UP
: case KEY_DOWN
:
2801 NotifyEvent
nEvt( MouseNotifyEvent::KEYINPUT
, NULL
, &rKeyEvt
);
2806 ListBox::KeyInput(rKeyEvt
);
2809 void CodeCompleteListBox::HideAndRestoreFocus()
2811 pCodeCompleteWindow
->Hide();
2812 pCodeCompleteWindow
->pParent
->GrabFocus();
2815 CodeCompleteWindow::CodeCompleteWindow( EditorWindow
* pPar
)
2818 pListBox( VclPtr
<CodeCompleteListBox
>::Create(this) )
2820 SetSizePixel( Size(151,151) ); //default, later it changes
2824 CodeCompleteWindow::~CodeCompleteWindow()
2829 void CodeCompleteWindow::dispose()
2831 pListBox
.disposeAndClear();
2833 vcl::Window::dispose();
2836 void CodeCompleteWindow::InitListBox()
2838 pListBox
->SetSizePixel( Size(150,150) ); //default, this will adopt the line length
2840 pListBox
->EnableQuickSelection( false );
2843 void CodeCompleteWindow::InsertEntry( const OUString
& aStr
)
2845 pListBox
->InsertEntry( aStr
);
2848 void CodeCompleteWindow::ClearListBox()
2851 pListBox
->aFuncBuffer
.makeStringAndClear();
2854 void CodeCompleteWindow::SetTextSelection( const TextSelection
& aSel
)
2856 aTextSelection
= aSel
;
2860 void CodeCompleteWindow::ResizeAndPositionListBox()
2862 if( pListBox
->GetEntryCount() >= 1 )
2863 {// if there is at least one element inside
2864 // calculate basic position: under the current line
2865 Rectangle aRect
= ( (TextEngine
*) pParent
->GetEditEngine() )->PaMtoEditCursor( pParent
->GetEditView()->GetSelection().GetEnd() , false );
2866 long nViewYOffset
= pParent
->GetEditView()->GetStartDocPos().Y();
2867 Point aPos
= aRect
.BottomRight();// this variable will be used later (if needed)
2868 aPos
.Y() = (aPos
.Y() - nViewYOffset
) + nBasePad
;
2870 OUString aLongestEntry
= pListBox
->GetEntry( 0 );// grab the longest one: max search
2871 for( sal_Int32 i
=1; i
< pListBox
->GetEntryCount(); ++i
)
2873 if( pListBox
->GetEntry( i
).getLength() > aLongestEntry
.getLength() )
2874 aLongestEntry
= pListBox
->GetEntry( i
);
2876 // get column/line count
2877 const sal_uInt16
& nColumns
= aLongestEntry
.getLength();
2878 const sal_uInt16 nLines
= static_cast<sal_uInt16
>( std::min( (sal_Int32
) 6, pListBox
->GetEntryCount() ));
2880 Size aSize
= pListBox
->CalcBlockSize( nColumns
, nLines
);
2882 SetSizePixel( aSize
);
2883 //1 px smaller, to see the border
2884 aSize
.setWidth( aSize
.getWidth() - 1 );
2885 aSize
.setHeight( aSize
.getHeight() - 1 );
2886 pListBox
->SetSizePixel( aSize
);
2888 //calculate position
2889 const Rectangle
aVisArea( pParent
->GetEditView()->GetStartDocPos(), pParent
->GetOutputSizePixel() );//the visible area
2890 const Point
& aBottomPoint
= aVisArea
.BottomRight();
2892 if( aVisArea
.TopRight().getY() + aPos
.getY() + aSize
.getHeight() > aBottomPoint
.getY() )
2893 {//clipped at the bottom: move it up
2894 const long& nParentFontHeight
= pParent
->GetEditEngine()->GetFont().GetHeight();//parent's font (in the IDE): needed for height
2895 aPos
.Y() -= aSize
.getHeight() + nParentFontHeight
+ nCursorPad
;
2898 if( aVisArea
.TopLeft().getX() + aPos
.getX() + aSize
.getWidth() > aBottomPoint
.getX() )
2899 {//clipped at the right side, move it a bit left
2900 aPos
.X() -= aSize
.getWidth() + aVisArea
.TopLeft().getX();
2903 SetPosPixel( aPos
);
2907 void CodeCompleteWindow::SelectFirstEntry()
2909 if( pListBox
->GetEntryCount() > 0 )
2911 pListBox
->SelectEntryPos( 0 );
2915 void CodeCompleteWindow::ClearAndHide()
2918 pListBox
->HideAndRestoreFocus();
2921 UnoTypeCodeCompletetor::UnoTypeCodeCompletetor( const std::vector
< OUString
>& aVect
, const OUString
& sVarType
)
2922 : bCanComplete( true )
2924 if( aVect
.size() == 0 || sVarType
.isEmpty() )
2926 bCanComplete
= false;//invalid parameters, nothing to code complete
2932 // Get the base class for reflection:
2933 xClass
= css::reflection::theCoreReflection::get(
2934 comphelper::getProcessComponentContext())->forName(sVarType
);
2936 catch( const Exception
& )
2938 bCanComplete
= false;
2942 unsigned int j
= 1;//start from aVect[1]: aVect[0] is the variable name
2945 while( j
!= aVect
.size() )
2947 sMethName
= aVect
[j
];
2949 if( CodeCompleteOptions::IsExtendedTypeDeclaration() )
2951 if( !CheckMethod(sMethName
) && !CheckField(sMethName
) )
2953 bCanComplete
= false;
2959 if( !CheckField(sMethName
) )
2961 bCanComplete
= false;
2970 std::vector
< OUString
> UnoTypeCodeCompletetor::GetXIdlClassMethods() const
2972 std::vector
< OUString
> aRetVect
;
2973 if( bCanComplete
&& ( xClass
!= NULL
) )
2975 Sequence
< Reference
< reflection::XIdlMethod
> > aMethods
= xClass
->getMethods();
2976 if( aMethods
.getLength() != 0 )
2978 for(sal_Int32 l
= 0; l
< aMethods
.getLength(); ++l
)
2980 aRetVect
.push_back( OUString(aMethods
[l
]->getName()) );
2984 return aRetVect
;//this is empty when cannot code complete
2987 std::vector
< OUString
> UnoTypeCodeCompletetor::GetXIdlClassFields() const
2989 std::vector
< OUString
> aRetVect
;
2990 if( bCanComplete
&& ( xClass
!= NULL
) )
2992 Sequence
< Reference
< reflection::XIdlField
> > aFields
= xClass
->getFields();
2993 if( aFields
.getLength() != 0 )
2995 for(sal_Int32 l
= 0; l
< aFields
.getLength(); ++l
)
2997 aRetVect
.push_back( OUString(aFields
[l
]->getName()) );
3001 return aRetVect
;//this is empty when cannot code complete
3005 bool UnoTypeCodeCompletetor::CheckField( const OUString
& sFieldName
)
3006 {// modifies xClass!!!
3007 Reference
< reflection::XIdlField
> xField
= xClass
->getField( sFieldName
);
3008 if( xField
!= NULL
)
3010 xClass
= xField
->getType();
3011 if( xClass
!= NULL
)
3019 bool UnoTypeCodeCompletetor::CheckMethod( const OUString
& sMethName
)
3020 {// modifies xClass!!!
3021 Reference
< reflection::XIdlMethod
> xMethod
= xClass
->getMethod( sMethName
);
3022 if( xMethod
!= NULL
) //method OK, check return type
3024 xClass
= xMethod
->getReturnType();
3025 if( xClass
!= NULL
)
3033 } // namespace basctl
3035 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */