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 <sal/config.h>
22 #include <hintids.hxx>
25 #include <com/sun/star/beans/XMultiPropertySet.hpp>
26 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
27 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
28 #include <cppuhelper/implbase.hxx>
29 #include <officecfg/Office/Common.hxx>
30 #include <rtl/ustring.hxx>
31 #include <sal/log.hxx>
32 #include <vcl/commandevent.hxx>
33 #include <vcl/event.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/textview.hxx>
36 #include <vcl/ptrstyle.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <sfx2/viewfrm.hxx>
39 #include <svtools/htmltokn.h>
40 #include <vcl/txtattr.hxx>
41 #include <vcl/settings.hxx>
42 #include <svtools/colorcfg.hxx>
43 #include <editeng/flstitem.hxx>
44 #include <vcl/metric.hxx>
45 #include <svtools/ctrltool.hxx>
46 #include <svtools/scrolladaptor.hxx>
47 #include <tools/time.hxx>
48 #include <swmodule.hxx>
50 #include <srcview.hxx>
59 sal_uInt16 nStart
, nEnd
;
60 svtools::ColorConfigEntry eType
;
65 #define MAX_SYNTAX_HIGHLIGHT 20
66 #define MAX_HIGHLIGHTTIME 200
68 typedef std::vector
<TextPortion
> TextPortions
;
70 static void lcl_Highlight(std::u16string_view aSource
, TextPortions
& aPortionList
)
72 const sal_Unicode cOpenBracket
= '<';
73 const sal_Unicode cCloseBracket
= '>';
74 const sal_Unicode cSlash
= '/';
75 const sal_Unicode cExclamation
= '!';
76 const sal_Unicode cMinus
= '-';
77 const sal_Unicode cSpace
= ' ';
78 const sal_Unicode cTab
= 0x09;
79 const sal_Unicode cLF
= 0x0a;
80 const sal_Unicode cCR
= 0x0d;
82 const sal_Int32 nStrLen
= aSource
.size();
83 sal_Int32 nInsert
= 0; // number of inserted portions
84 sal_Int32 nActPos
= 0; // position, where '<' was found
85 sal_Int32 nPortStart
= SAL_MAX_INT32
; // for the TextPortion
86 sal_Int32 nPortEnd
= 0;
88 while(nActPos
< nStrLen
)
90 if((nActPos
< nStrLen
- 2) && (aSource
[nActPos
] == cOpenBracket
))
92 svtools::ColorConfigEntry eFoundType
= svtools::HTMLUNKNOWN
;
93 // insert 'empty' portion
94 if(nPortEnd
< nActPos
- 1 )
96 // don't move at the beginning
97 aText
.nStart
= nPortEnd
;
100 aText
.nEnd
= nActPos
- 1;
101 aText
.eType
= svtools::HTMLUNKNOWN
;
102 aPortionList
.push_back( aText
);
105 sal_Unicode cFollowFirst
= aSource
[nActPos
+ 1];
106 sal_Unicode cFollowNext
= aSource
[nActPos
+ 2];
107 if(cExclamation
== cFollowFirst
)
109 // "<!" SGML or comment
110 if(cMinus
== cFollowNext
&&
111 nActPos
< nStrLen
- 3 && cMinus
== aSource
[nActPos
+ 3])
113 eFoundType
= svtools::HTMLCOMMENT
;
116 eFoundType
= svtools::HTMLSGML
;
117 nPortStart
= nActPos
;
118 nPortEnd
= nActPos
+ 1;
120 else if(cSlash
== cFollowFirst
)
123 nPortStart
= nActPos
;
126 if(svtools::HTMLUNKNOWN
== eFoundType
)
128 // now here a keyword could follow
129 sal_uInt16 nSrchPos
= nActPos
;
130 while(++nSrchPos
< nStrLen
- 1)
132 sal_Unicode cNext
= aSource
[nSrchPos
];
133 if( cNext
== cSpace
||
138 else if(cNext
== cCloseBracket
)
143 if(nSrchPos
> nActPos
+ 1)
145 // some string was found
146 OUString
sToken( aSource
.substr(nActPos
+ 1, nSrchPos
- nActPos
- 1 ) );
147 sToken
= sToken
.toAsciiUpperCase();
148 HtmlTokenId nToken
= ::GetHTMLToken(sToken
);
149 if(nToken
!= HtmlTokenId::NONE
)
151 eFoundType
= svtools::HTMLKEYWORD
;
153 nPortStart
= nActPos
;
156 SAL_WARN("sw", "HTML token " << sToken
<< " not recognised!");
159 // now we still have to look for '>'
160 if(svtools::HTMLUNKNOWN
!= eFoundType
)
163 for(sal_Int32 i
= nPortEnd
; i
< nStrLen
; i
++)
164 if(cCloseBracket
== aSource
[i
])
170 if(!bFound
&& (eFoundType
== svtools::HTMLCOMMENT
))
172 // comment without ending in this line
174 nPortEnd
= nStrLen
- 1;
177 if(bFound
||(eFoundType
== svtools::HTMLCOMMENT
))
179 TextPortion aTextPortion
;
180 aTextPortion
.nStart
= nPortStart
+ 1;
181 aTextPortion
.nEnd
= nPortEnd
;
182 aTextPortion
.eType
= eFoundType
;
183 aPortionList
.push_back( aTextPortion
);
191 if(nInsert
&& nPortEnd
< nActPos
- 1)
193 aText
.nStart
= nPortEnd
+ 1;
194 aText
.nEnd
= nActPos
- 1;
195 aText
.eType
= svtools::HTMLUNKNOWN
;
196 aPortionList
.push_back( aText
);
201 class SwSrcEditWindow::ChangesListener
:
202 public cppu::WeakImplHelper
< css::beans::XPropertiesChangeListener
>
205 explicit ChangesListener(SwSrcEditWindow
& editor
): m_Editor(editor
) {}
208 virtual ~ChangesListener() override
{}
210 virtual void SAL_CALL
disposing(css::lang::EventObject
const &) override
212 std::unique_lock
g(m_Editor
.mutex_
);
213 m_Editor
.m_xNotifier
.clear();
216 virtual void SAL_CALL
propertiesChange(
217 css::uno::Sequence
< css::beans::PropertyChangeEvent
> const &) override
223 SwSrcEditWindow
& m_Editor
;
226 SwSrcEditWindow::SwSrcEditWindow( vcl::Window
* pParent
, SwSrcView
* pParentView
) :
227 Window( pParent
, WB_BORDER
|WB_CLIPCHILDREN
),
230 m_pHScrollbar(nullptr),
231 m_pVScrollbar(nullptr),
233 m_pSrcView(pParentView
),
236 m_nStartLine(USHRT_MAX
),
237 m_eSourceEncoding(osl_getThreadTextEncoding()),
239 m_bHighlighting(false),
240 m_aSyntaxIdle("sw uibase SwSrcEditWindow Syntax")
242 SetHelpId(HID_SOURCE_EDITWIN
);
245 // Using "this" in ctor is a little fishy, but should work here at least as
246 // long as there are no derivations:
247 m_xListener
= new ChangesListener(*this);
248 css::uno::Reference
< css::beans::XMultiPropertySet
> n(
249 officecfg::Office::Common::Font::SourceViewFont::get(),
250 css::uno::UNO_QUERY_THROW
);
252 std::unique_lock
g(mutex_
);
255 n
->addPropertiesChangeListener({ "FontHeight", "FontName" }, m_xListener
);
258 SwSrcEditWindow::~SwSrcEditWindow()
263 void SwSrcEditWindow::dispose()
265 css::uno::Reference
< css::beans::XMultiPropertySet
> n
;
267 std::unique_lock
g(mutex_
);
271 n
->removePropertiesChangeListener(m_xListener
);
273 m_aSyntaxIdle
.Stop();
275 m_pOutWin
->SetTextView( nullptr );
279 EndListening( *m_pTextEngine
);
280 m_pTextEngine
->RemoveView( m_pTextView
.get() );
283 m_pTextEngine
.reset();
285 m_pHScrollbar
.disposeAndClear();
286 m_pVScrollbar
.disposeAndClear();
287 m_pOutWin
.disposeAndClear();
288 vcl::Window::dispose();
291 void SwSrcEditWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
293 Window::DataChanged( rDCEvt
);
295 switch ( rDCEvt
.GetType() )
297 case DataChangedEventType::SETTINGS
:
298 // newly rearrange ScrollBars or trigger Resize, because
299 // ScrollBar size could have changed. For this, in the
300 // Resize handler the size of ScrollBars has to be queried
301 // from the settings as well.
302 if( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)
309 void SwSrcEditWindow::Resize()
311 // ScrollBars, etc. happens in Adjust...
315 tools::Long nVisY
= m_pTextView
->GetStartDocPos().Y();
316 m_pTextView
->ShowCursor();
317 Size
aOutSz( GetOutputSizePixel() );
318 tools::Long nMaxVisAreaStart
= m_pTextView
->GetTextEngine()->GetTextHeight() - aOutSz
.Height();
319 if ( nMaxVisAreaStart
< 0 )
320 nMaxVisAreaStart
= 0;
321 if ( m_pTextView
->GetStartDocPos().Y() > nMaxVisAreaStart
)
323 Point
aStartDocPos( m_pTextView
->GetStartDocPos() );
324 aStartDocPos
.setY( nMaxVisAreaStart
);
325 m_pTextView
->SetStartDocPos( aStartDocPos
);
326 m_pTextView
->ShowCursor();
328 tools::Long nScrollStd
= GetSettings().GetStyleSettings().GetScrollBarSize();
329 Size
aScrollSz(aOutSz
.Width() - nScrollStd
, nScrollStd
);
330 Point
aScrollPos(0, aOutSz
.Height() - nScrollStd
);
332 m_pHScrollbar
->SetPosSizePixel( aScrollPos
, aScrollSz
);
334 aScrollSz
.setWidth( aScrollSz
.Height() );
335 aScrollSz
.setHeight( aOutSz
.Height() );
336 aScrollPos
= Point(aOutSz
.Width() - nScrollStd
, 0);
338 m_pVScrollbar
->SetPosSizePixel( aScrollPos
, aScrollSz
);
339 aOutSz
.AdjustWidth( -nScrollStd
);
340 aOutSz
.AdjustHeight( -nScrollStd
);
341 m_pOutWin
->SetOutputSizePixel(aOutSz
);
344 // set line in first Resize
345 if(USHRT_MAX
!= m_nStartLine
)
347 if(m_nStartLine
< m_pTextEngine
->GetParagraphCount())
349 TextSelection
aSel(TextPaM( m_nStartLine
, 0 ), TextPaM( m_nStartLine
, 0x0 ));
350 m_pTextView
->SetSelection(aSel
);
351 m_pTextView
->ShowCursor();
353 m_nStartLine
= USHRT_MAX
;
356 if ( nVisY
!= m_pTextView
->GetStartDocPos().Y() )
362 void TextViewOutWin::DataChanged( const DataChangedEvent
& rDCEvt
)
364 Window::DataChanged( rDCEvt
);
366 switch( rDCEvt
.GetType() )
368 case DataChangedEventType::SETTINGS
:
370 if( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)
372 const Color
&rCol
= GetSettings().GetStyleSettings().GetWindowColor();
373 SetBackground( rCol
);
374 vcl::Font
aFont( m_pTextView
->GetTextEngine()->GetFont() );
375 aFont
.SetFillColor( rCol
);
376 m_pTextView
->GetTextEngine()->SetFont( aFont
);
383 void TextViewOutWin::MouseMove( const MouseEvent
&rEvt
)
386 m_pTextView
->MouseMove( rEvt
);
389 void TextViewOutWin::MouseButtonUp( const MouseEvent
&rEvt
)
393 m_pTextView
->MouseButtonUp( rEvt
);
394 SfxViewFrame
& rFrame
= static_cast<SwSrcEditWindow
*>(GetParent())->GetSrcView()->GetViewFrame();
395 SfxBindings
& rBindings
= rFrame
.GetBindings();
396 rBindings
.Invalidate( SID_TABLE_CELL
);
397 rBindings
.Invalidate( SID_CUT
);
398 rBindings
.Invalidate( SID_COPY
);
402 void TextViewOutWin::MouseButtonDown( const MouseEvent
&rEvt
)
406 m_pTextView
->MouseButtonDown( rEvt
);
409 void TextViewOutWin::Command( const CommandEvent
& rCEvt
)
411 switch(rCEvt
.GetCommand())
413 case CommandEventId::ContextMenu
:
414 SfxDispatcher::ExecutePopup();
416 case CommandEventId::Wheel
:
417 case CommandEventId::StartAutoScroll
:
418 case CommandEventId::AutoScroll
:
420 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
421 if( !pWData
|| CommandWheelMode::ZOOM
!= pWData
->GetMode() )
423 static_cast<SwSrcEditWindow
*>(GetParent())->HandleWheelCommand( rCEvt
);
430 m_pTextView
->Command( rCEvt
);
432 Window::Command(rCEvt
);
436 void TextViewOutWin::KeyInput( const KeyEvent
& rKEvt
)
439 SwSrcEditWindow
* pSrcEditWin
= static_cast<SwSrcEditWindow
*>(GetParent());
440 bool bChange
= !pSrcEditWin
->IsReadonly() || !TextEngine::DoesKeyChangeText( rKEvt
);
442 bDone
= m_pTextView
->KeyInput( rKEvt
);
444 SfxBindings
& rBindings
= static_cast<SwSrcEditWindow
*>(GetParent())->GetSrcView()->GetViewFrame().GetBindings();
447 if ( !SfxViewShell::Current()->KeyInput( rKEvt
) )
448 Window::KeyInput( rKEvt
);
452 rBindings
.Invalidate( SID_TABLE_CELL
);
453 if ( rKEvt
.GetKeyCode().GetGroup() == KEYGROUP_CURSOR
)
454 rBindings
.Update( SID_BASICIDE_STAT_POS
);
455 if (pSrcEditWin
->GetTextEngine()->IsModified() )
457 rBindings
.Invalidate( SID_SAVEDOC
);
458 rBindings
.Invalidate( SID_DOC_MODIFIED
);
460 if( rKEvt
.GetKeyCode().GetCode() == KEY_INSERT
)
461 rBindings
.Invalidate( SID_ATTR_INSERT
);
464 rBindings
.Invalidate( SID_CUT
);
465 rBindings
.Invalidate( SID_COPY
);
467 SwDocShell
* pDocShell
= pSrcEditWin
->GetSrcView()->GetDocShell();
468 if(pSrcEditWin
->GetTextEngine()->IsModified())
470 pDocShell
->SetModified();
474 void TextViewOutWin::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
476 m_pTextView
->Paint(rRenderContext
, rRect
);
479 void SwSrcEditWindow::CreateTextEngine()
481 // FIXME RenderContext
483 const Color
&rCol
= GetSettings().GetStyleSettings().GetWindowColor();
484 m_pOutWin
= VclPtr
<TextViewOutWin
>::Create(this, 0);
485 m_pOutWin
->SetBackground(Wallpaper(rCol
));
486 m_pOutWin
->SetPointer(PointerStyle::Text
);
490 m_pHScrollbar
= VclPtr
<ScrollAdaptor
>::Create(this, true);
491 m_pHScrollbar
->EnableRTL( false );
492 m_pHScrollbar
->SetScrollHdl(LINK(this, SwSrcEditWindow
, HorzScrollHdl
));
493 m_pHScrollbar
->Show();
495 m_pVScrollbar
= VclPtr
<ScrollAdaptor
>::Create(this, false);
496 m_pVScrollbar
->EnableRTL( false );
497 m_pVScrollbar
->SetScrollHdl(LINK(this, SwSrcEditWindow
, VertScrollHdl
));
498 m_pVScrollbar
->Show();
500 m_pTextEngine
.reset(new ExtTextEngine
);
501 m_pTextView
.reset(new TextView( m_pTextEngine
.get(), m_pOutWin
));
502 m_pTextView
->SetAutoIndentMode(true);
503 m_pOutWin
->SetTextView(m_pTextView
.get());
505 m_pTextEngine
->SetUpdateMode( false );
506 m_pTextEngine
->InsertView( m_pTextView
.get() );
509 aFont
.SetTransparent( false );
510 aFont
.SetFillColor( rCol
);
511 SetPointFont(*GetOutDev(), aFont
);
513 aFont
.SetFillColor( rCol
);
514 m_pOutWin
->SetFont( aFont
);
515 m_pTextEngine
->SetFont( aFont
);
517 m_aSyntaxIdle
.SetInvokeHandler( LINK( this, SwSrcEditWindow
, SyntaxTimerHdl
) );
519 m_pTextEngine
->EnableUndo( true );
520 m_pTextEngine
->SetUpdateMode( true );
522 m_pTextView
->ShowCursor();
524 StartListening( *m_pTextEngine
);
526 SfxBindings
& rBind
= GetSrcView()->GetViewFrame().GetBindings();
527 rBind
.Invalidate( SID_TABLE_CELL
);
530 void SwSrcEditWindow::SetScrollBarRanges()
532 // Extra method, not InitScrollBars, because also for TextEngine events.
534 m_pHScrollbar
->SetRange( Range( 0, m_nCurTextWidth
-1 ) );
535 m_pVScrollbar
->SetRange( Range(0, m_pTextEngine
->GetTextHeight()-1) );
538 void SwSrcEditWindow::InitScrollBars()
540 SetScrollBarRanges();
542 Size
aOutSz( m_pOutWin
->GetOutputSizePixel() );
543 m_pVScrollbar
->SetVisibleSize( aOutSz
.Height() );
544 m_pVScrollbar
->SetPageSize( aOutSz
.Height() * 8 / 10 );
545 m_pVScrollbar
->SetLineSize( m_pOutWin
->GetTextHeight() );
546 m_pVScrollbar
->SetThumbPos( m_pTextView
->GetStartDocPos().Y() );
547 m_pHScrollbar
->SetVisibleSize( aOutSz
.Width() );
548 m_pHScrollbar
->SetPageSize( aOutSz
.Width() * 8 / 10 );
549 m_pHScrollbar
->SetLineSize( m_pOutWin
->GetTextWidth(OUString('x')) );
550 m_pHScrollbar
->SetThumbPos( m_pTextView
->GetStartDocPos().X() );
554 IMPL_LINK_NOARG(SwSrcEditWindow
, HorzScrollHdl
, weld::Scrollbar
&, void)
556 tools::Long nDiff
= m_pTextView
->GetStartDocPos().X() - m_pHScrollbar
->GetThumbPos();
557 GetTextView()->Scroll( nDiff
, 0 );
558 m_pTextView
->ShowCursor( false );
559 m_pHScrollbar
->SetThumbPos( m_pTextView
->GetStartDocPos().X() );
560 GetSrcView()->GetViewFrame().GetBindings().Invalidate( SID_TABLE_CELL
);
563 IMPL_LINK_NOARG(SwSrcEditWindow
, VertScrollHdl
, weld::Scrollbar
&, void)
565 tools::Long nDiff
= m_pTextView
->GetStartDocPos().Y() - m_pVScrollbar
->GetThumbPos();
566 GetTextView()->Scroll( 0, nDiff
);
567 m_pTextView
->ShowCursor( false );
568 m_pVScrollbar
->SetThumbPos( m_pTextView
->GetStartDocPos().Y() );
569 GetSrcView()->GetViewFrame().GetBindings().Invalidate( SID_TABLE_CELL
);
572 IMPL_LINK( SwSrcEditWindow
, SyntaxTimerHdl
, Timer
*, pIdle
, void )
574 tools::Time
aSyntaxCheckStart( tools::Time::SYSTEM
);
575 SAL_WARN_IF(m_pTextView
== nullptr, "sw", "No View yet, but syntax highlighting?!");
577 m_bHighlighting
= true;
578 sal_uInt16 nCount
= 0;
579 // at first the region around the cursor is processed
580 TextSelection aSel
= m_pTextView
->GetSelection();
581 sal_uInt16 nCur
= o3tl::narrowing
<sal_uInt16
>(aSel
.GetStart().GetPara());
586 if(!m_aSyntaxLineTable
.empty())
587 for(sal_uInt16 i
= 0; i
< 80 && nCount
< 40; i
++, nCur
++)
589 if(m_aSyntaxLineTable
.find(nCur
) != m_aSyntaxLineTable
.end())
591 DoSyntaxHighlight( nCur
);
592 m_aSyntaxLineTable
.erase( nCur
);
594 if(m_aSyntaxLineTable
.empty())
596 if((tools::Time( tools::Time::SYSTEM
).GetTime() - aSyntaxCheckStart
.GetTime()) > MAX_HIGHLIGHTTIME
)
603 // when there is still anything left by then, go on from the beginning
604 while ( !m_aSyntaxLineTable
.empty() && nCount
< MAX_SYNTAX_HIGHLIGHT
)
606 sal_uInt16 nLine
= *m_aSyntaxLineTable
.begin();
607 DoSyntaxHighlight( nLine
);
608 m_aSyntaxLineTable
.erase(nLine
);
610 if(tools::Time( tools::Time::SYSTEM
).GetTime() - aSyntaxCheckStart
.GetTime() > MAX_HIGHLIGHTTIME
)
616 if(!m_aSyntaxLineTable
.empty() && !pIdle
->IsActive())
618 // SyntaxTimerHdl is called when text changed
619 // => good opportunity to determine text width!
620 tools::Long nPrevTextWidth
= m_nCurTextWidth
;
621 m_nCurTextWidth
= m_pTextEngine
->CalcTextWidth() + 25; // small tolerance
622 if ( m_nCurTextWidth
!= nPrevTextWidth
)
623 SetScrollBarRanges();
624 m_bHighlighting
= false;
627 void SwSrcEditWindow::DoSyntaxHighlight( sal_uInt16 nPara
)
629 // Because of DelayedSyntaxHighlight it could happen,
630 // that the line doesn't exist anymore!
631 if ( nPara
>= m_pTextEngine
->GetParagraphCount() )
634 bool bTempModified
= IsModified();
635 m_pTextEngine
->RemoveAttribs( nPara
);
636 OUString
aSource( m_pTextEngine
->GetText( nPara
) );
637 m_pTextEngine
->SetUpdateMode( false );
638 ImpDoHighlight( aSource
, nPara
);
639 TextView
* pTmp
= m_pTextEngine
->GetActiveView();
640 pTmp
->SetAutoScroll(false);
641 m_pTextEngine
->SetActiveView(nullptr);
642 m_pTextEngine
->SetUpdateMode( true );
643 m_pTextEngine
->SetActiveView(pTmp
);
644 pTmp
->SetAutoScroll(true);
645 pTmp
->ShowCursor( false/*pTmp->IsAutoScroll()*/ );
652 void SwSrcEditWindow::ImpDoHighlight( std::u16string_view aSource
, sal_uInt16 nLineOff
)
654 TextPortions aPortionList
;
655 lcl_Highlight(aSource
, aPortionList
);
657 size_t nCount
= aPortionList
.size();
661 TextPortion
& rLast
= aPortionList
[nCount
-1];
662 if ( rLast
.nStart
> rLast
.nEnd
) // Only until Bug from MD is resolved
665 aPortionList
.pop_back();
671 // Only blanks and tabs have to be attributed along.
672 // When two identical attributes are placed consecutively,
673 // it optimises the TextEngine.
674 sal_uInt16 nLastEnd
= 0;
676 for ( size_t i
= 0; i
< nCount
; i
++ )
678 TextPortion
& r
= aPortionList
[i
];
679 if ( r
.nStart
> r
.nEnd
) // only until Bug from MD is resolved
682 if ( r
.nStart
> nLastEnd
)
684 // Can I rely on the fact that all except blank and tab
685 // are being highlighted?!
689 if ( ( i
== (nCount
-1) ) && ( r
.nEnd
< aSource
.size() ) )
690 r
.nEnd
= aSource
.size();
694 for (TextPortion
& r
: aPortionList
)
696 if ( r
.nStart
> r
.nEnd
) // only until Bug from MD is resolved
698 if(r
.eType
!= svtools::HTMLSGML
&&
699 r
.eType
!= svtools::HTMLCOMMENT
&&
700 r
.eType
!= svtools::HTMLKEYWORD
&&
701 r
.eType
!= svtools::HTMLUNKNOWN
)
702 r
.eType
= svtools::HTMLUNKNOWN
;
703 Color
aColor(SW_MOD()->GetColorConfig().GetColorValue(r
.eType
).nColor
);
704 m_pTextEngine
->SetAttrib( TextAttribFontColor( aColor
), nLineOff
, r
.nStart
, r
.nEnd
+1 );
708 void SwSrcEditWindow::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
710 const TextHint
* pTextHint
= dynamic_cast<const TextHint
*>(&rHint
);
714 switch (pTextHint
->GetId())
716 case SfxHintId::TextViewScrolled
:
717 m_pHScrollbar
->SetThumbPos( m_pTextView
->GetStartDocPos().X() );
718 m_pVScrollbar
->SetThumbPos( m_pTextView
->GetStartDocPos().Y() );
721 case SfxHintId::TextHeightChanged
:
722 if ( m_pTextEngine
->GetTextHeight() < m_pOutWin
->GetOutputSizePixel().Height() )
723 m_pTextView
->Scroll( 0, m_pTextView
->GetStartDocPos().Y() );
724 m_pVScrollbar
->SetThumbPos( m_pTextView
->GetStartDocPos().Y() );
725 SetScrollBarRanges();
728 case SfxHintId::TextParaInserted
:
729 case SfxHintId::TextParaContentChanged
:
730 if ( !m_bHighlighting
)
732 m_aSyntaxLineTable
.insert( o3tl::narrowing
<sal_uInt16
>(pTextHint
->GetValue()) );
733 m_aSyntaxIdle
.Start();
740 void SwSrcEditWindow::Invalidate(InvalidateFlags
)
742 m_pOutWin
->Invalidate();
743 Window::Invalidate();
746 void SwSrcEditWindow::Command( const CommandEvent
& rCEvt
)
748 switch(rCEvt
.GetCommand())
750 case CommandEventId::Wheel
:
751 case CommandEventId::StartAutoScroll
:
752 case CommandEventId::AutoScroll
:
754 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
755 if( !pWData
|| CommandWheelMode::ZOOM
!= pWData
->GetMode() )
756 HandleScrollCommand( rCEvt
, m_pHScrollbar
, m_pVScrollbar
);
760 Window::Command(rCEvt
);
764 void SwSrcEditWindow::HandleWheelCommand( const CommandEvent
& rCEvt
)
766 m_pTextView
->Command(rCEvt
);
767 HandleScrollCommand( rCEvt
, m_pHScrollbar
, m_pVScrollbar
);
770 void SwSrcEditWindow::GetFocus()
773 m_pOutWin
->GrabFocus();
776 static bool lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc
, LanguageType aLanguages
[])
780 case RTL_TEXTENCODING_UTF7
:
781 case RTL_TEXTENCODING_UTF8
:
782 // don#t fill - all LANGUAGE_SYSTEM means unicode font has to be used
785 case RTL_TEXTENCODING_ISO_8859_3
:
786 case RTL_TEXTENCODING_ISO_8859_1
:
787 case RTL_TEXTENCODING_MS_1252
:
788 case RTL_TEXTENCODING_APPLE_ROMAN
:
789 case RTL_TEXTENCODING_IBM_850
:
790 case RTL_TEXTENCODING_ISO_8859_14
:
791 case RTL_TEXTENCODING_ISO_8859_15
:
792 //fill with western languages
793 aLanguages
[0] = LANGUAGE_GERMAN
;
794 aLanguages
[1] = LANGUAGE_FRENCH
;
795 aLanguages
[2] = LANGUAGE_ITALIAN
;
796 aLanguages
[3] = LANGUAGE_SPANISH
;
799 case RTL_TEXTENCODING_IBM_865
:
801 aLanguages
[0] = LANGUAGE_FINNISH
;
802 aLanguages
[1] = LANGUAGE_NORWEGIAN
;
803 aLanguages
[2] = LANGUAGE_SWEDISH
;
804 aLanguages
[3] = LANGUAGE_DANISH
;
807 case RTL_TEXTENCODING_ISO_8859_10
:
808 case RTL_TEXTENCODING_ISO_8859_13
:
809 case RTL_TEXTENCODING_ISO_8859_2
:
810 case RTL_TEXTENCODING_IBM_852
:
811 case RTL_TEXTENCODING_MS_1250
:
812 case RTL_TEXTENCODING_APPLE_CENTEURO
:
813 aLanguages
[0] = LANGUAGE_POLISH
;
814 aLanguages
[1] = LANGUAGE_CZECH
;
815 aLanguages
[2] = LANGUAGE_HUNGARIAN
;
816 aLanguages
[3] = LANGUAGE_SLOVAK
;
819 case RTL_TEXTENCODING_ISO_8859_4
:
820 case RTL_TEXTENCODING_IBM_775
:
821 case RTL_TEXTENCODING_MS_1257
:
822 aLanguages
[0] = LANGUAGE_LATVIAN
;
823 aLanguages
[1] = LANGUAGE_LITHUANIAN
;
824 aLanguages
[2] = LANGUAGE_ESTONIAN
;
827 case RTL_TEXTENCODING_IBM_863
: aLanguages
[0] = LANGUAGE_FRENCH_CANADIAN
; break;
828 case RTL_TEXTENCODING_APPLE_FARSI
: aLanguages
[0] = LANGUAGE_FARSI
; break;
829 case RTL_TEXTENCODING_APPLE_ROMANIAN
:aLanguages
[0] = LANGUAGE_ROMANIAN
; break;
831 case RTL_TEXTENCODING_IBM_861
:
832 case RTL_TEXTENCODING_APPLE_ICELAND
:
833 aLanguages
[0] = LANGUAGE_ICELANDIC
;
836 case RTL_TEXTENCODING_APPLE_CROATIAN
:aLanguages
[0] = LANGUAGE_CROATIAN
; break;
838 case RTL_TEXTENCODING_IBM_437
:
839 case RTL_TEXTENCODING_ASCII_US
: aLanguages
[0] = LANGUAGE_ENGLISH
; break;
841 case RTL_TEXTENCODING_IBM_862
:
842 case RTL_TEXTENCODING_MS_1255
:
843 case RTL_TEXTENCODING_APPLE_HEBREW
:
844 case RTL_TEXTENCODING_ISO_8859_8
:
845 aLanguages
[0] = LANGUAGE_HEBREW
;
848 case RTL_TEXTENCODING_IBM_857
:
849 case RTL_TEXTENCODING_MS_1254
:
850 case RTL_TEXTENCODING_APPLE_TURKISH
:
851 case RTL_TEXTENCODING_ISO_8859_9
:
852 aLanguages
[0] = LANGUAGE_TURKISH
;
855 case RTL_TEXTENCODING_IBM_860
:
856 aLanguages
[0] = LANGUAGE_PORTUGUESE
;
859 case RTL_TEXTENCODING_IBM_869
:
860 case RTL_TEXTENCODING_MS_1253
:
861 case RTL_TEXTENCODING_APPLE_GREEK
:
862 case RTL_TEXTENCODING_ISO_8859_7
:
863 case RTL_TEXTENCODING_IBM_737
:
864 aLanguages
[0] = LANGUAGE_GREEK
;
867 case RTL_TEXTENCODING_KOI8_R
:
868 case RTL_TEXTENCODING_ISO_8859_5
:
869 case RTL_TEXTENCODING_IBM_855
:
870 case RTL_TEXTENCODING_MS_1251
:
871 case RTL_TEXTENCODING_IBM_866
:
872 case RTL_TEXTENCODING_APPLE_CYRILLIC
:
873 aLanguages
[0] = LANGUAGE_RUSSIAN
;
876 case RTL_TEXTENCODING_APPLE_UKRAINIAN
:
877 case RTL_TEXTENCODING_KOI8_U
:
878 aLanguages
[0] = LANGUAGE_UKRAINIAN
;
881 case RTL_TEXTENCODING_IBM_864
:
882 case RTL_TEXTENCODING_MS_1256
:
883 case RTL_TEXTENCODING_ISO_8859_6
:
884 case RTL_TEXTENCODING_APPLE_ARABIC
:
885 aLanguages
[0] = LANGUAGE_ARABIC_SAUDI_ARABIA
;
888 case RTL_TEXTENCODING_APPLE_CHINTRAD
:
889 case RTL_TEXTENCODING_MS_950
:
890 case RTL_TEXTENCODING_GBT_12345
:
891 case RTL_TEXTENCODING_BIG5
:
892 case RTL_TEXTENCODING_EUC_TW
:
893 case RTL_TEXTENCODING_BIG5_HKSCS
:
894 aLanguages
[0] = LANGUAGE_CHINESE_TRADITIONAL
;
897 case RTL_TEXTENCODING_EUC_JP
:
898 case RTL_TEXTENCODING_ISO_2022_JP
:
899 case RTL_TEXTENCODING_JIS_X_0201
:
900 case RTL_TEXTENCODING_JIS_X_0208
:
901 case RTL_TEXTENCODING_JIS_X_0212
:
902 case RTL_TEXTENCODING_APPLE_JAPANESE
:
903 case RTL_TEXTENCODING_MS_932
:
904 case RTL_TEXTENCODING_SHIFT_JIS
:
905 aLanguages
[0] = LANGUAGE_JAPANESE
;
908 case RTL_TEXTENCODING_GB_2312
:
909 case RTL_TEXTENCODING_MS_936
:
910 case RTL_TEXTENCODING_GBK
:
911 case RTL_TEXTENCODING_GB_18030
:
912 case RTL_TEXTENCODING_APPLE_CHINSIMP
:
913 case RTL_TEXTENCODING_EUC_CN
:
914 case RTL_TEXTENCODING_ISO_2022_CN
:
915 aLanguages
[0] = LANGUAGE_CHINESE_SIMPLIFIED
;
918 case RTL_TEXTENCODING_APPLE_KOREAN
:
919 case RTL_TEXTENCODING_MS_949
:
920 case RTL_TEXTENCODING_EUC_KR
:
921 case RTL_TEXTENCODING_ISO_2022_KR
:
922 case RTL_TEXTENCODING_MS_1361
:
923 aLanguages
[0] = LANGUAGE_KOREAN
;
926 case RTL_TEXTENCODING_APPLE_THAI
:
927 case RTL_TEXTENCODING_MS_874
:
928 case RTL_TEXTENCODING_TIS_620
:
929 aLanguages
[0] = LANGUAGE_THAI
;
931 default: aLanguages
[0] = Application::GetSettings().GetUILanguageTag().getLanguageType();
933 return aLanguages
[0] != LANGUAGE_SYSTEM
;
935 void SwSrcEditWindow::SetFont()
938 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
939 value_or(OUString()));
940 if(sFontName
.isEmpty())
942 LanguageType aLanguages
[5] =
944 LANGUAGE_SYSTEM
, LANGUAGE_SYSTEM
, LANGUAGE_SYSTEM
, LANGUAGE_SYSTEM
, LANGUAGE_SYSTEM
947 if(lcl_GetLanguagesForEncoding(m_eSourceEncoding
, aLanguages
))
949 //TODO: check for multiple languages
950 aFont
= OutputDevice::GetDefaultFont(DefaultFontType::FIXED
, aLanguages
[0], GetDefaultFontFlags::NONE
, GetOutDev());
953 aFont
= OutputDevice::GetDefaultFont(DefaultFontType::SANS_UNICODE
,
954 Application::GetSettings().GetLanguageTag().getLanguageType(), GetDefaultFontFlags::NONE
, GetOutDev());
955 sFontName
= aFont
.GetFamilyName();
957 const SvxFontListItem
* pFontListItem
=
958 static_cast<const SvxFontListItem
* >(m_pSrcView
->GetDocShell()->GetItem( SID_ATTR_CHAR_FONTLIST
));
959 const FontList
* pList
= pFontListItem
->GetFontList();
960 FontMetric aFontMetric
= pList
->Get(sFontName
,WEIGHT_NORMAL
, ITALIC_NONE
);
962 const vcl::Font
& rFont
= GetTextEngine()->GetFont();
963 vcl::Font
aFont(aFontMetric
);
964 Size
aSize(rFont
.GetFontSize());
965 //font height is stored in point and set in twip
967 officecfg::Office::Common::Font::SourceViewFont::FontHeight::get() * 20 );
968 aFont
.SetFontSize(m_pOutWin
->LogicToPixel(aSize
, MapMode(MapUnit::MapTwip
)));
969 GetTextEngine()->SetFont( aFont
);
970 m_pOutWin
->SetFont(aFont
);
973 void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding
)
975 m_eSourceEncoding
= eEncoding
;
979 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */