LibreOffice Module sw (master) 1
srcedtw.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <hintids.hxx>
23#include <cmdid.h>
24
25#include <com/sun/star/beans/XMultiPropertySet.hpp>
26#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
27#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
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>
47#include <tools/time.hxx>
48#include <swmodule.hxx>
49#include <docsh.hxx>
50#include <srcview.hxx>
51#include <helpids.h>
52#include <vector>
53
54namespace
55{
56
57struct TextPortion
58{
59 sal_uInt16 nStart, nEnd;
61};
62
63}
64
65#define MAX_SYNTAX_HIGHLIGHT 20
66#define MAX_HIGHLIGHTTIME 200
67
68typedef std::vector<TextPortion> TextPortions;
69
70static void lcl_Highlight(std::u16string_view aSource, TextPortions& aPortionList)
71{
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;
81
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;
87 TextPortion aText;
88 while(nActPos < nStrLen)
89 {
90 if((nActPos < nStrLen - 2) && (aSource[nActPos] == cOpenBracket))
91 {
93 // insert 'empty' portion
94 if(nPortEnd < nActPos - 1 )
95 {
96 // don't move at the beginning
97 aText.nStart = nPortEnd;
98 if(nInsert)
99 aText.nStart += 1;
100 aText.nEnd = nActPos - 1;
101 aText.eType = svtools::HTMLUNKNOWN;
102 aPortionList.push_back( aText );
103 nInsert++;
104 }
105 sal_Unicode cFollowFirst = aSource[nActPos + 1];
106 sal_Unicode cFollowNext = aSource[nActPos + 2];
107 if(cExclamation == cFollowFirst)
108 {
109 // "<!" SGML or comment
110 if(cMinus == cFollowNext &&
111 nActPos < nStrLen - 3 && cMinus == aSource[nActPos + 3])
112 {
113 eFoundType = svtools::HTMLCOMMENT;
114 }
115 else
116 eFoundType = svtools::HTMLSGML;
117 nPortStart = nActPos;
118 nPortEnd = nActPos + 1;
119 }
120 else if(cSlash == cFollowFirst)
121 {
122 // "</" ignore slash
123 nPortStart = nActPos;
124 nActPos++;
125 }
126 if(svtools::HTMLUNKNOWN == eFoundType)
127 {
128 // now here a keyword could follow
129 sal_uInt16 nSrchPos = nActPos;
130 while(++nSrchPos < nStrLen - 1)
131 {
132 sal_Unicode cNext = aSource[nSrchPos];
133 if( cNext == cSpace ||
134 cNext == cTab ||
135 cNext == cLF ||
136 cNext == cCR)
137 break;
138 else if(cNext == cCloseBracket)
139 {
140 break;
141 }
142 }
143 if(nSrchPos > nActPos + 1)
144 {
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)
150 {
151 eFoundType = svtools::HTMLKEYWORD;
152 nPortEnd = nSrchPos;
153 nPortStart = nActPos;
154 }
155 else
156 SAL_WARN("sw", "HTML token " << sToken << " not recognised!");
157 }
158 }
159 // now we still have to look for '>'
160 if(svtools::HTMLUNKNOWN != eFoundType)
161 {
162 bool bFound = false;
163 for(sal_Int32 i = nPortEnd; i < nStrLen; i++)
164 if(cCloseBracket == aSource[i])
165 {
166 bFound = true;
167 nPortEnd = i;
168 break;
169 }
170 if(!bFound && (eFoundType == svtools::HTMLCOMMENT))
171 {
172 // comment without ending in this line
173 bFound = true;
174 nPortEnd = nStrLen - 1;
175 }
176
177 if(bFound ||(eFoundType == svtools::HTMLCOMMENT))
178 {
179 TextPortion aTextPortion;
180 aTextPortion.nStart = nPortStart + 1;
181 aTextPortion.nEnd = nPortEnd;
182 aTextPortion.eType = eFoundType;
183 aPortionList.push_back( aTextPortion );
184 nInsert++;
185 }
186
187 }
188 }
189 nActPos++;
190 }
191 if(nInsert && nPortEnd < nActPos - 1)
192 {
193 aText.nStart = nPortEnd + 1;
194 aText.nEnd = nActPos - 1;
195 aText.eType = svtools::HTMLUNKNOWN;
196 aPortionList.push_back( aText );
197 nInsert++;
198 }
199}
200
202 public cppu::WeakImplHelper< css::beans::XPropertiesChangeListener >
203{
204public:
205 explicit ChangesListener(SwSrcEditWindow & editor): m_Editor(editor) {}
206
207private:
208 virtual ~ChangesListener() override {}
209
210 virtual void SAL_CALL disposing(css::lang::EventObject const &) override
211 {
212 std::unique_lock g(m_Editor.mutex_);
213 m_Editor.m_xNotifier.clear();
214 }
215
216 virtual void SAL_CALL propertiesChange(
217 css::uno::Sequence< css::beans::PropertyChangeEvent > const &) override
218 {
221 }
222
224};
225
227 Window( pParent, WB_BORDER|WB_CLIPCHILDREN ),
228
229 m_pOutWin(nullptr),
230 m_pHScrollbar(nullptr),
231 m_pVScrollbar(nullptr),
232
233 m_pSrcView(pParentView),
234
235 m_nCurTextWidth(0),
236 m_nStartLine(USHRT_MAX),
237 m_eSourceEncoding(osl_getThreadTextEncoding()),
238 m_bReadonly(false),
239 m_bHighlighting(false),
240 m_aSyntaxIdle("sw uibase SwSrcEditWindow Syntax")
241{
244
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(
250 css::uno::UNO_QUERY_THROW);
251 {
252 std::unique_lock g(mutex_);
253 m_xNotifier = n;
254 }
255 n->addPropertiesChangeListener({ "FontHeight", "FontName" }, m_xListener);
256}
257
259{
260 disposeOnce();
261}
262
264{
265 css::uno::Reference< css::beans::XMultiPropertySet > n;
266 {
267 std::unique_lock g(mutex_);
268 n = m_xNotifier;
269 }
270 if (n.is()) {
271 n->removePropertiesChangeListener(m_xListener);
272 }
274 if ( m_pOutWin )
275 m_pOutWin->SetTextView( nullptr );
276
277 if ( m_pTextEngine )
278 {
280 m_pTextEngine->RemoveView( m_pTextView.get() );
281
282 m_pTextView.reset();
283 m_pTextEngine.reset();
284 }
289}
290
292{
293 Window::DataChanged( rDCEvt );
294
295 switch ( rDCEvt.GetType() )
296 {
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 )
303 Resize();
304 break;
305 default: break;
306 }
307}
308
310{
311 // ScrollBars, etc. happens in Adjust...
312 if ( !m_pTextView )
313 return;
314
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 )
322 {
323 Point aStartDocPos( m_pTextView->GetStartDocPos() );
324 aStartDocPos.setY( nMaxVisAreaStart );
325 m_pTextView->SetStartDocPos( aStartDocPos );
326 m_pTextView->ShowCursor();
327 }
329 Size aScrollSz(aOutSz.Width() - nScrollStd, nScrollStd );
330 Point aScrollPos(0, aOutSz.Height() - nScrollStd);
331
332 m_pHScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
333
334 aScrollSz.setWidth( aScrollSz.Height() );
335 aScrollSz.setHeight( aOutSz.Height() );
336 aScrollPos = Point(aOutSz.Width() - nScrollStd, 0);
337
338 m_pVScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
339 aOutSz.AdjustWidth( -nScrollStd );
340 aOutSz.AdjustHeight( -nScrollStd );
341 m_pOutWin->SetOutputSizePixel(aOutSz);
343
344 // set line in first Resize
345 if(USHRT_MAX != m_nStartLine)
346 {
347 if(m_nStartLine < m_pTextEngine->GetParagraphCount())
348 {
350 m_pTextView->SetSelection(aSel);
351 m_pTextView->ShowCursor();
352 }
353 m_nStartLine = USHRT_MAX;
354 }
355
356 if ( nVisY != m_pTextView->GetStartDocPos().Y() )
357 Invalidate();
358
359
360}
361
363{
364 Window::DataChanged( rDCEvt );
365
366 switch( rDCEvt.GetType() )
367 {
368 case DataChangedEventType::SETTINGS:
369 // query settings
370 if( rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
371 {
373 SetBackground( rCol );
375 aFont.SetFillColor( rCol );
376 m_pTextView->GetTextEngine()->SetFont( aFont );
377 }
378 break;
379 default: break;
380 }
381}
382
384{
385 if ( m_pTextView )
386 m_pTextView->MouseMove( rEvt );
387}
388
390{
391 if ( m_pTextView )
392 {
393 m_pTextView->MouseButtonUp( rEvt );
394 SfxViewFrame *pFrame = static_cast<SwSrcEditWindow*>(GetParent())->GetSrcView()->GetViewFrame();
395 if ( pFrame )
396 {
397 SfxBindings& rBindings = pFrame->GetBindings();
398 rBindings.Invalidate( SID_TABLE_CELL );
399 rBindings.Invalidate( SID_CUT );
400 rBindings.Invalidate( SID_COPY );
401 }
402 }
403}
404
406{
407 GrabFocus();
408 if ( m_pTextView )
410}
411
413{
414 switch(rCEvt.GetCommand())
415 {
416 case CommandEventId::ContextMenu:
418 break;
419 case CommandEventId::Wheel:
420 case CommandEventId::StartAutoScroll:
421 case CommandEventId::AutoScroll:
422 {
423 const CommandWheelData* pWData = rCEvt.GetWheelData();
424 if( !pWData || CommandWheelMode::ZOOM != pWData->GetMode() )
425 {
426 static_cast<SwSrcEditWindow*>(GetParent())->HandleWheelCommand( rCEvt );
427 }
428 }
429 break;
430
431 default:
432 if ( m_pTextView )
433 m_pTextView->Command( rCEvt );
434 else
435 Window::Command(rCEvt);
436 }
437}
438
440{
441 bool bDone = false;
442 SwSrcEditWindow* pSrcEditWin = static_cast<SwSrcEditWindow*>(GetParent());
443 bool bChange = !pSrcEditWin->IsReadonly() || !TextEngine::DoesKeyChangeText( rKEvt );
444 if(bChange)
445 bDone = m_pTextView->KeyInput( rKEvt );
446
447 SfxBindings& rBindings = static_cast<SwSrcEditWindow*>(GetParent())->GetSrcView()->GetViewFrame()->GetBindings();
448 if ( !bDone )
449 {
450 if ( !SfxViewShell::Current()->KeyInput( rKEvt ) )
451 Window::KeyInput( rKEvt );
452 }
453 else
454 {
455 rBindings.Invalidate( SID_TABLE_CELL );
456 if ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_CURSOR )
457 rBindings.Update( SID_BASICIDE_STAT_POS );
458 if (pSrcEditWin->GetTextEngine()->IsModified() )
459 {
460 rBindings.Invalidate( SID_SAVEDOC );
461 rBindings.Invalidate( SID_DOC_MODIFIED );
462 }
463 if( rKEvt.GetKeyCode().GetCode() == KEY_INSERT )
464 rBindings.Invalidate( SID_ATTR_INSERT );
465 }
466
467 rBindings.Invalidate( SID_CUT );
468 rBindings.Invalidate( SID_COPY );
469
470 SwDocShell* pDocShell = pSrcEditWin->GetSrcView()->GetDocShell();
471 if(pSrcEditWin->GetTextEngine()->IsModified())
472 {
473 pDocShell->SetModified();
474 }
475}
476
478{
479 m_pTextView->Paint(rRenderContext, rRect);
480}
481
483{
484 // FIXME RenderContext
485
488 m_pOutWin->SetBackground(Wallpaper(rCol));
489 m_pOutWin->SetPointer(PointerStyle::Text);
490 m_pOutWin->Show();
491
492 // create Scrollbars
494 m_pHScrollbar->EnableRTL( false );
495 m_pHScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, HorzScrollHdl));
496 m_pHScrollbar->Show();
497
499 m_pVScrollbar->EnableRTL( false );
500 m_pVScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, VertScrollHdl));
501 m_pVScrollbar->Show();
502
503 m_pTextEngine.reset(new ExtTextEngine);
504 m_pTextView.reset(new TextView( m_pTextEngine.get(), m_pOutWin ));
505 m_pTextView->SetAutoIndentMode(true);
506 m_pOutWin->SetTextView(m_pTextView.get());
507
508 m_pTextEngine->SetUpdateMode( false );
509 m_pTextEngine->InsertView( m_pTextView.get() );
510
511 vcl::Font aFont;
512 aFont.SetTransparent( false );
513 aFont.SetFillColor( rCol );
514 SetPointFont(*GetOutDev(), aFont);
515 aFont = GetFont();
516 aFont.SetFillColor( rCol );
517 m_pOutWin->SetFont( aFont );
518 m_pTextEngine->SetFont( aFont );
519
520 m_aSyntaxIdle.SetInvokeHandler( LINK( this, SwSrcEditWindow, SyntaxTimerHdl ) );
521
522 m_pTextEngine->EnableUndo( true );
523 m_pTextEngine->SetUpdateMode( true );
524
525 m_pTextView->ShowCursor();
528
530 rBind.Invalidate( SID_TABLE_CELL );
531}
532
534{
535 // Extra method, not InitScrollBars, because also for TextEngine events.
536
537 m_pHScrollbar->SetRange( Range( 0, m_nCurTextWidth-1 ) );
538 m_pVScrollbar->SetRange( Range(0, m_pTextEngine->GetTextHeight()-1) );
539}
540
542{
544
545 Size aOutSz( m_pOutWin->GetOutputSizePixel() );
546 m_pVScrollbar->SetVisibleSize( aOutSz.Height() );
547 m_pVScrollbar->SetPageSize( aOutSz.Height() * 8 / 10 );
548 m_pVScrollbar->SetLineSize( m_pOutWin->GetTextHeight() );
549 m_pVScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().Y() );
550 m_pHScrollbar->SetVisibleSize( aOutSz.Width() );
551 m_pHScrollbar->SetPageSize( aOutSz.Width() * 8 / 10 );
552 m_pHScrollbar->SetLineSize( m_pOutWin->GetTextWidth(OUString('x')) );
553 m_pHScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().X() );
554
555}
556
558{
559 tools::Long nDiff = m_pTextView->GetStartDocPos().X() - m_pHScrollbar->GetThumbPos();
560 GetTextView()->Scroll( nDiff, 0 );
561 m_pTextView->ShowCursor( false );
562 m_pHScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().X() );
563 GetSrcView()->GetViewFrame()->GetBindings().Invalidate( SID_TABLE_CELL );
564}
565
567{
568 tools::Long nDiff = m_pTextView->GetStartDocPos().Y() - m_pVScrollbar->GetThumbPos();
569 GetTextView()->Scroll( 0, nDiff );
570 m_pTextView->ShowCursor( false );
571 m_pVScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().Y() );
572 GetSrcView()->GetViewFrame()->GetBindings().Invalidate( SID_TABLE_CELL );
573}
574
575IMPL_LINK( SwSrcEditWindow, SyntaxTimerHdl, Timer*, pIdle, void )
576{
577 tools::Time aSyntaxCheckStart( tools::Time::SYSTEM );
578 SAL_WARN_IF(m_pTextView == nullptr, "sw", "No View yet, but syntax highlighting?!");
579
580 m_bHighlighting = true;
581 sal_uInt16 nCount = 0;
582 // at first the region around the cursor is processed
583 TextSelection aSel = m_pTextView->GetSelection();
584 sal_uInt16 nCur = o3tl::narrowing<sal_uInt16>(aSel.GetStart().GetPara());
585 if(nCur > 40)
586 nCur -= 40;
587 else
588 nCur = 0;
589 if(!m_aSyntaxLineTable.empty())
590 for(sal_uInt16 i = 0; i < 80 && nCount < 40; i++, nCur++)
591 {
592 if(m_aSyntaxLineTable.find(nCur) != m_aSyntaxLineTable.end())
593 {
594 DoSyntaxHighlight( nCur );
595 m_aSyntaxLineTable.erase( nCur );
596 nCount++;
597 if(m_aSyntaxLineTable.empty())
598 break;
599 if((tools::Time( tools::Time::SYSTEM ).GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME )
600 {
601 break;
602 }
603 }
604 }
605
606 // when there is still anything left by then, go on from the beginning
607 while ( !m_aSyntaxLineTable.empty() && nCount < MAX_SYNTAX_HIGHLIGHT)
608 {
609 sal_uInt16 nLine = *m_aSyntaxLineTable.begin();
610 DoSyntaxHighlight( nLine );
611 m_aSyntaxLineTable.erase(nLine);
612 nCount ++;
613 if(tools::Time( tools::Time::SYSTEM ).GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME)
614 {
615 break;
616 }
617 }
618
619 if(!m_aSyntaxLineTable.empty() && !pIdle->IsActive())
620 pIdle->Start();
621 // SyntaxTimerHdl is called when text changed
622 // => good opportunity to determine text width!
623 tools::Long nPrevTextWidth = m_nCurTextWidth;
624 m_nCurTextWidth = m_pTextEngine->CalcTextWidth() + 25; // small tolerance
625 if ( m_nCurTextWidth != nPrevTextWidth )
626 SetScrollBarRanges();
627 m_bHighlighting = false;
628}
629
631{
632 // Because of DelayedSyntaxHighlight it could happen,
633 // that the line doesn't exist anymore!
634 if ( nPara >= m_pTextEngine->GetParagraphCount() )
635 return;
636
637 bool bTempModified = IsModified();
638 m_pTextEngine->RemoveAttribs( nPara );
639 OUString aSource( m_pTextEngine->GetText( nPara ) );
640 m_pTextEngine->SetUpdateMode( false );
641 ImpDoHighlight( aSource, nPara );
642 TextView* pTmp = m_pTextEngine->GetActiveView();
643 pTmp->SetAutoScroll(false);
644 m_pTextEngine->SetActiveView(nullptr);
645 m_pTextEngine->SetUpdateMode( true );
646 m_pTextEngine->SetActiveView(pTmp);
647 pTmp->SetAutoScroll(true);
648 pTmp->ShowCursor( false/*pTmp->IsAutoScroll()*/ );
649
650 if(!bTempModified)
652
653}
654
655void SwSrcEditWindow::ImpDoHighlight( std::u16string_view aSource, sal_uInt16 nLineOff )
656{
657 TextPortions aPortionList;
658 lcl_Highlight(aSource, aPortionList);
659
660 size_t nCount = aPortionList.size();
661 if ( !nCount )
662 return;
663
664 TextPortion& rLast = aPortionList[nCount-1];
665 if ( rLast.nStart > rLast.nEnd ) // Only until Bug from MD is resolved
666 {
667 nCount--;
668 aPortionList.pop_back();
669 if ( !nCount )
670 return;
671 }
672
673 {
674 // Only blanks and tabs have to be attributed along.
675 // When two identical attributes are placed consecutively,
676 // it optimises the TextEngine.
677 sal_uInt16 nLastEnd = 0;
678
679 for ( size_t i = 0; i < nCount; i++ )
680 {
681 TextPortion& r = aPortionList[i];
682 if ( r.nStart > r.nEnd ) // only until Bug from MD is resolved
683 continue;
684
685 if ( r.nStart > nLastEnd )
686 {
687 // Can I rely on the fact that all except blank and tab
688 // are being highlighted?!
689 r.nStart = nLastEnd;
690 }
691 nLastEnd = r.nEnd+1;
692 if ( ( i == (nCount-1) ) && ( r.nEnd < aSource.size() ) )
693 r.nEnd = aSource.size();
694 }
695 }
696
697 for (TextPortion & r : aPortionList)
698 {
699 if ( r.nStart > r.nEnd ) // only until Bug from MD is resolved
700 continue;
701 if(r.eType != svtools::HTMLSGML &&
702 r.eType != svtools::HTMLCOMMENT &&
703 r.eType != svtools::HTMLKEYWORD &&
704 r.eType != svtools::HTMLUNKNOWN)
705 r.eType = svtools::HTMLUNKNOWN;
706 Color aColor(SW_MOD()->GetColorConfig().GetColorValue(r.eType).nColor);
707 m_pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLineOff, r.nStart, r.nEnd+1 );
708 }
709}
710
711void SwSrcEditWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
712{
713 const TextHint* pTextHint = dynamic_cast<const TextHint*>(&rHint);
714 if (!pTextHint)
715 return;
716
717 switch (pTextHint->GetId())
718 {
719 case SfxHintId::TextViewScrolled:
720 m_pHScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().X() );
721 m_pVScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().Y() );
722 break;
723
724 case SfxHintId::TextHeightChanged:
725 if ( m_pTextEngine->GetTextHeight() < m_pOutWin->GetOutputSizePixel().Height() )
726 m_pTextView->Scroll( 0, m_pTextView->GetStartDocPos().Y() );
727 m_pVScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().Y() );
729 break;
730
731 case SfxHintId::TextParaInserted:
732 case SfxHintId::TextParaContentChanged:
733 if ( !m_bHighlighting )
734 {
735 m_aSyntaxLineTable.insert( o3tl::narrowing<sal_uInt16>(pTextHint->GetValue()) );
737 }
738 break;
739 default: break;
740 }
741}
742
744{
745 m_pOutWin->Invalidate();
746 Window::Invalidate();
747}
748
750{
751 switch(rCEvt.GetCommand())
752 {
753 case CommandEventId::Wheel:
754 case CommandEventId::StartAutoScroll:
755 case CommandEventId::AutoScroll:
756 {
757 const CommandWheelData* pWData = rCEvt.GetWheelData();
758 if( !pWData || CommandWheelMode::ZOOM != pWData->GetMode() )
760 }
761 break;
762 default:
763 Window::Command(rCEvt);
764 }
765}
766
768{
769 m_pTextView->Command(rCEvt);
771}
772
774{
775 if (m_pOutWin)
776 m_pOutWin->GrabFocus();
777}
778
779static bool lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc, LanguageType aLanguages[])
780{
781 switch(eEnc)
782 {
783 case RTL_TEXTENCODING_UTF7 :
784 case RTL_TEXTENCODING_UTF8 :
785 // don#t fill - all LANGUAGE_SYSTEM means unicode font has to be used
786 break;
787
788 case RTL_TEXTENCODING_ISO_8859_3:
789 case RTL_TEXTENCODING_ISO_8859_1 :
790 case RTL_TEXTENCODING_MS_1252 :
791 case RTL_TEXTENCODING_APPLE_ROMAN :
792 case RTL_TEXTENCODING_IBM_850 :
793 case RTL_TEXTENCODING_ISO_8859_14 :
794 case RTL_TEXTENCODING_ISO_8859_15 :
795 //fill with western languages
796 aLanguages[0] = LANGUAGE_GERMAN;
797 aLanguages[1] = LANGUAGE_FRENCH;
798 aLanguages[2] = LANGUAGE_ITALIAN;
799 aLanguages[3] = LANGUAGE_SPANISH;
800 break;
801
802 case RTL_TEXTENCODING_IBM_865 :
803 //scandinavian
804 aLanguages[0] = LANGUAGE_FINNISH;
805 aLanguages[1] = LANGUAGE_NORWEGIAN;
806 aLanguages[2] = LANGUAGE_SWEDISH;
807 aLanguages[3] = LANGUAGE_DANISH;
808 break;
809
810 case RTL_TEXTENCODING_ISO_8859_10 :
811 case RTL_TEXTENCODING_ISO_8859_13 :
812 case RTL_TEXTENCODING_ISO_8859_2 :
813 case RTL_TEXTENCODING_IBM_852 :
814 case RTL_TEXTENCODING_MS_1250 :
815 case RTL_TEXTENCODING_APPLE_CENTEURO :
816 aLanguages[0] = LANGUAGE_POLISH;
817 aLanguages[1] = LANGUAGE_CZECH;
818 aLanguages[2] = LANGUAGE_HUNGARIAN;
819 aLanguages[3] = LANGUAGE_SLOVAK;
820 break;
821
822 case RTL_TEXTENCODING_ISO_8859_4 :
823 case RTL_TEXTENCODING_IBM_775 :
824 case RTL_TEXTENCODING_MS_1257 :
825 aLanguages[0] = LANGUAGE_LATVIAN ;
826 aLanguages[1] = LANGUAGE_LITHUANIAN;
827 aLanguages[2] = LANGUAGE_ESTONIAN ;
828 break;
829
830 case RTL_TEXTENCODING_IBM_863 : aLanguages[0] = LANGUAGE_FRENCH_CANADIAN; break;
831 case RTL_TEXTENCODING_APPLE_FARSI : aLanguages[0] = LANGUAGE_FARSI; break;
832 case RTL_TEXTENCODING_APPLE_ROMANIAN:aLanguages[0] = LANGUAGE_ROMANIAN; break;
833
834 case RTL_TEXTENCODING_IBM_861 :
835 case RTL_TEXTENCODING_APPLE_ICELAND :
836 aLanguages[0] = LANGUAGE_ICELANDIC;
837 break;
838
839 case RTL_TEXTENCODING_APPLE_CROATIAN:aLanguages[0] = LANGUAGE_CROATIAN; break;
840
841 case RTL_TEXTENCODING_IBM_437 :
842 case RTL_TEXTENCODING_ASCII_US : aLanguages[0] = LANGUAGE_ENGLISH; break;
843
844 case RTL_TEXTENCODING_IBM_862 :
845 case RTL_TEXTENCODING_MS_1255 :
846 case RTL_TEXTENCODING_APPLE_HEBREW :
847 case RTL_TEXTENCODING_ISO_8859_8 :
848 aLanguages[0] = LANGUAGE_HEBREW;
849 break;
850
851 case RTL_TEXTENCODING_IBM_857 :
852 case RTL_TEXTENCODING_MS_1254 :
853 case RTL_TEXTENCODING_APPLE_TURKISH:
854 case RTL_TEXTENCODING_ISO_8859_9 :
855 aLanguages[0] = LANGUAGE_TURKISH;
856 break;
857
858 case RTL_TEXTENCODING_IBM_860 :
859 aLanguages[0] = LANGUAGE_PORTUGUESE;
860 break;
861
862 case RTL_TEXTENCODING_IBM_869 :
863 case RTL_TEXTENCODING_MS_1253 :
864 case RTL_TEXTENCODING_APPLE_GREEK :
865 case RTL_TEXTENCODING_ISO_8859_7 :
866 case RTL_TEXTENCODING_IBM_737 :
867 aLanguages[0] = LANGUAGE_GREEK;
868 break;
869
870 case RTL_TEXTENCODING_KOI8_R :
871 case RTL_TEXTENCODING_ISO_8859_5 :
872 case RTL_TEXTENCODING_IBM_855 :
873 case RTL_TEXTENCODING_MS_1251 :
874 case RTL_TEXTENCODING_IBM_866 :
875 case RTL_TEXTENCODING_APPLE_CYRILLIC :
876 aLanguages[0] = LANGUAGE_RUSSIAN;
877 break;
878
879 case RTL_TEXTENCODING_APPLE_UKRAINIAN:
880 case RTL_TEXTENCODING_KOI8_U:
881 aLanguages[0] = LANGUAGE_UKRAINIAN;
882 break;
883
884 case RTL_TEXTENCODING_IBM_864 :
885 case RTL_TEXTENCODING_MS_1256 :
886 case RTL_TEXTENCODING_ISO_8859_6 :
887 case RTL_TEXTENCODING_APPLE_ARABIC :
888 aLanguages[0] = LANGUAGE_ARABIC_SAUDI_ARABIA;
889 break;
890
891 case RTL_TEXTENCODING_APPLE_CHINTRAD :
892 case RTL_TEXTENCODING_MS_950 :
893 case RTL_TEXTENCODING_GBT_12345 :
894 case RTL_TEXTENCODING_BIG5 :
895 case RTL_TEXTENCODING_EUC_TW :
896 case RTL_TEXTENCODING_BIG5_HKSCS :
897 aLanguages[0] = LANGUAGE_CHINESE_TRADITIONAL;
898 break;
899
900 case RTL_TEXTENCODING_EUC_JP :
901 case RTL_TEXTENCODING_ISO_2022_JP :
902 case RTL_TEXTENCODING_JIS_X_0201 :
903 case RTL_TEXTENCODING_JIS_X_0208 :
904 case RTL_TEXTENCODING_JIS_X_0212 :
905 case RTL_TEXTENCODING_APPLE_JAPANESE :
906 case RTL_TEXTENCODING_MS_932 :
907 case RTL_TEXTENCODING_SHIFT_JIS :
908 aLanguages[0] = LANGUAGE_JAPANESE;
909 break;
910
911 case RTL_TEXTENCODING_GB_2312 :
912 case RTL_TEXTENCODING_MS_936 :
913 case RTL_TEXTENCODING_GBK :
914 case RTL_TEXTENCODING_GB_18030 :
915 case RTL_TEXTENCODING_APPLE_CHINSIMP :
916 case RTL_TEXTENCODING_EUC_CN :
917 case RTL_TEXTENCODING_ISO_2022_CN :
918 aLanguages[0] = LANGUAGE_CHINESE_SIMPLIFIED;
919 break;
920
921 case RTL_TEXTENCODING_APPLE_KOREAN :
922 case RTL_TEXTENCODING_MS_949 :
923 case RTL_TEXTENCODING_EUC_KR :
924 case RTL_TEXTENCODING_ISO_2022_KR :
925 case RTL_TEXTENCODING_MS_1361 :
926 aLanguages[0] = LANGUAGE_KOREAN;
927 break;
928
929 case RTL_TEXTENCODING_APPLE_THAI :
930 case RTL_TEXTENCODING_MS_874 :
931 case RTL_TEXTENCODING_TIS_620 :
932 aLanguages[0] = LANGUAGE_THAI;
933 break;
934 default: aLanguages[0] = Application::GetSettings().GetUILanguageTag().getLanguageType();
935 }
936 return aLanguages[0] != LANGUAGE_SYSTEM;
937}
939{
940 OUString sFontName(
942 value_or(OUString()));
943 if(sFontName.isEmpty())
944 {
945 LanguageType aLanguages[5] =
946 {
948 };
949 vcl::Font aFont;
951 {
952 //TODO: check for multiple languages
953 aFont = OutputDevice::GetDefaultFont(DefaultFontType::FIXED, aLanguages[0], GetDefaultFontFlags::NONE, GetOutDev());
954 }
955 else
956 aFont = OutputDevice::GetDefaultFont(DefaultFontType::SANS_UNICODE,
957 Application::GetSettings().GetLanguageTag().getLanguageType(), GetDefaultFontFlags::NONE, GetOutDev());
958 sFontName = aFont.GetFamilyName();
959 }
960 const SvxFontListItem* pFontListItem =
961 static_cast<const SvxFontListItem* >(m_pSrcView->GetDocShell()->GetItem( SID_ATTR_CHAR_FONTLIST ));
962 const FontList* pList = pFontListItem->GetFontList();
963 FontMetric aFontMetric = pList->Get(sFontName,WEIGHT_NORMAL, ITALIC_NONE);
964
965 const vcl::Font& rFont = GetTextEngine()->GetFont();
966 vcl::Font aFont(aFontMetric);
967 Size aSize(rFont.GetFontSize());
968 //font height is stored in point and set in twip
969 aSize.setHeight(
971 aFont.SetFontSize(m_pOutWin->LogicToPixel(aSize, MapMode(MapUnit::MapTwip)));
972 GetTextEngine()->SetFont( aFont );
973 m_pOutWin->SetFont(aFont);
974}
975
976void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding)
977{
978 m_eSourceEncoding = eEncoding;
979 SetFont();
980}
981
982/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const LanguageTag & GetUILanguageTag() const
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
CommandEventId GetCommand() const
const CommandWheelData * GetWheelData() const
CommandWheelMode GetMode() const
DataChangedEventType GetType() const
AllSettingsFlags GetFlags() const
FontMetric Get(const OUString &rName, const OUString &rStyleName) const
virtual void Start(bool bStartTimer=true) override
const vcl::KeyCode & GetKeyCode() const
LanguageType getLanguageType(bool bResolveSystem=true) const
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
void Update(sal_uInt16 nId)
void Invalidate(sal_uInt16 nId)
void ExecutePopup(const OUString &rResName, vcl::Window *pWin=nullptr, const Point *pPos=nullptr)
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
SfxBindings & GetBindings()
SfxViewFrame * GetViewFrame() const
static SfxViewShell * Current()
virtual bool KeyInput(const KeyEvent &rKeyEvent)
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
void setWidth(tools::Long nWidth)
tools::Long AdjustWidth(tools::Long n)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
sal_Int32 GetScrollBarSize() const
const Color & GetWindowColor() const
const FontList * GetFontList() const
virtual void SetModified(bool=true) override
Definition: docsh2.cxx:1429
virtual ~ChangesListener() override
Definition: srcedtw.cxx:208
ChangesListener(SwSrcEditWindow &editor)
Definition: srcedtw.cxx:205
SwSrcEditWindow & m_Editor
Definition: srcedtw.cxx:223
virtual void SAL_CALL propertiesChange(css::uno::Sequence< css::beans::PropertyChangeEvent > const &) override
Definition: srcedtw.cxx:216
virtual void SAL_CALL disposing(css::lang::EventObject const &) override
Definition: srcedtw.cxx:210
void ClearModifyFlag()
Definition: srcedtw.hxx:128
std::set< sal_uInt16 > m_aSyntaxLineTable
Definition: srcedtw.hxx:86
sal_uInt16 m_nStartLine
Definition: srcedtw.hxx:80
virtual void GetFocus() override
Definition: srcedtw.cxx:773
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE) override
Definition: srcedtw.cxx:743
Idle m_aSyntaxIdle
Definition: srcedtw.hxx:85
std::unique_ptr< ExtTextEngine > m_pTextEngine
Definition: srcedtw.hxx:66
bool IsModified() const
Definition: srcedtw.hxx:130
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: srcedtw.cxx:711
SwSrcView * GetSrcView()
Definition: srcedtw.hxx:122
void HandleWheelCommand(const CommandEvent &rCEvt)
Definition: srcedtw.cxx:767
SwSrcView * m_pSrcView
Definition: srcedtw.hxx:72
VclPtr< ScrollAdaptor > m_pVScrollbar
Definition: srcedtw.hxx:70
SwSrcEditWindow(vcl::Window *pParent, SwSrcView *pParentView)
Definition: srcedtw.cxx:226
void ImpDoHighlight(std::u16string_view aSource, sal_uInt16 nLineOff)
Definition: srcedtw.cxx:655
bool m_bHighlighting
Definition: srcedtw.hxx:83
virtual void DataChanged(const DataChangedEvent &) override
Definition: srcedtw.cxx:291
tools::Long m_nCurTextWidth
Definition: srcedtw.hxx:79
void SetFont()
Definition: srcedtw.cxx:938
rtl_TextEncoding m_eSourceEncoding
Definition: srcedtw.hxx:81
virtual ~SwSrcEditWindow() override
Definition: srcedtw.cxx:258
void SetScrollBarRanges()
Definition: srcedtw.cxx:533
css::uno::Reference< css::beans::XMultiPropertySet > m_xNotifier
Definition: srcedtw.hxx:77
virtual void Command(const CommandEvent &rCEvt) override
Definition: srcedtw.cxx:749
rtl::Reference< ChangesListener > m_xListener
Definition: srcedtw.hxx:74
virtual void dispose() override
Definition: srcedtw.cxx:263
VclPtr< ScrollAdaptor > m_pHScrollbar
Definition: srcedtw.hxx:69
void DoSyntaxHighlight(sal_uInt16 nPara)
Definition: srcedtw.cxx:630
friend class ChangesListener
Definition: srcedtw.hxx:63
TextEngine * GetTextEngine()
Definition: srcedtw.hxx:120
void CreateTextEngine()
Definition: srcedtw.cxx:482
std::mutex mutex_
Definition: srcedtw.hxx:75
virtual void Resize() override
Definition: srcedtw.cxx:309
std::unique_ptr< TextView > m_pTextView
Definition: srcedtw.hxx:65
VclPtr< TextViewOutWin > m_pOutWin
Definition: srcedtw.hxx:68
void InitScrollBars()
Definition: srcedtw.cxx:541
void SetTextEncoding(rtl_TextEncoding eEncoding)
Definition: srcedtw.cxx:976
bool IsReadonly() const
Definition: srcedtw.hxx:134
SwDocShell * GetDocShell()
Definition: srcview.cxx:244
void Stop()
bool IsModified() const
static bool DoesKeyChangeText(const KeyEvent &rKeyEvent)
const vcl::Font & GetFont() const
void SetFont(const vcl::Font &rFont)
sal_Int32 GetValue() const
sal_uInt32 GetPara() const
const TextPaM & GetStart() const
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &) override
Definition: srcedtw.cxx:477
virtual void MouseButtonUp(const MouseEvent &rMEvt) override
Definition: srcedtw.cxx:389
virtual void DataChanged(const DataChangedEvent &) override
Definition: srcedtw.cxx:362
virtual void Command(const CommandEvent &rCEvt) override
Definition: srcedtw.cxx:412
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: srcedtw.cxx:405
TextView * m_pTextView
Definition: srcedtw.hxx:42
virtual void MouseMove(const MouseEvent &rMEvt) override
Definition: srcedtw.cxx:383
virtual void KeyInput(const KeyEvent &rKeyEvt) override
Definition: srcedtw.cxx:439
void ShowCursor(bool bGotoCursor=true, bool bForceVisCursor=true)
void MouseButtonDown(const MouseEvent &rMouseEvent)
void Command(const CommandEvent &rCEvt)
void SetAutoScroll(bool bAutoScroll)
void MouseMove(const MouseEvent &rMouseEvent)
void MouseButtonUp(const MouseEvent &rMouseEvent)
bool KeyInput(const KeyEvent &rKeyEvent)
void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
TextEngine * GetTextEngine() const
void SetInvokeHandler(const Link< Timer *, void > &rLink)
void disposeAndClear()
static VclPtr< reference_type > Create(Arg &&... arg)
sal_Int64 GetTime() const
void SetFontSize(const Size &)
void SetTransparent(bool bTransparent)
void SetFillColor(const Color &)
const OUString & GetFamilyName() const
const Size & GetFontSize() const
sal_uInt16 GetGroup() const
sal_uInt16 GetCode() const
virtual void dispose() override
vcl::Window * GetParent() const
bool HandleScrollCommand(const CommandEvent &rCmd, Scrollable *pHScrl, Scrollable *pVScrl)
void GrabFocus()
const AllSettings & GetSettings() const
::OutputDevice const * GetOutDev() const
const vcl::Font & GetFont() const
void SetHelpId(const OString &)
Size GetOutputSizePixel() const
void SetPointFont(vcl::RenderContext &rRenderContext, const vcl::Font &rFont)
void SetBackground()
int nCount
DocumentType eType
ITALIC_NONE
WEIGHT_NORMAL
constexpr OStringLiteral HID_SOURCE_EDITWIN
Definition: helpids.h:28
HtmlTokenId
sal_Int64 n
constexpr sal_uInt16 KEY_INSERT
constexpr sal_uInt16 KEYGROUP_CURSOR
#define LANGUAGE_ENGLISH
#define LANGUAGE_SYSTEM
#define LANGUAGE_LITHUANIAN
#define LANGUAGE_ROMANIAN
#define LANGUAGE_CHINESE_TRADITIONAL
#define LANGUAGE_PORTUGUESE
#define LANGUAGE_HUNGARIAN
#define LANGUAGE_THAI
#define LANGUAGE_FINNISH
#define LANGUAGE_CZECH
#define LANGUAGE_FRENCH
#define LANGUAGE_ITALIAN
#define LANGUAGE_ICELANDIC
#define LANGUAGE_SPANISH
#define LANGUAGE_CHINESE_SIMPLIFIED
#define LANGUAGE_SLOVAK
#define LANGUAGE_JAPANESE
#define LANGUAGE_GREEK
#define LANGUAGE_RUSSIAN
#define LANGUAGE_KOREAN
#define LANGUAGE_SWEDISH
#define LANGUAGE_POLISH
#define LANGUAGE_FRENCH_CANADIAN
#define LANGUAGE_UKRAINIAN
#define LANGUAGE_ARABIC_SAUDI_ARABIA
#define LANGUAGE_HEBREW
#define LANGUAGE_DANISH
#define LANGUAGE_GERMAN
#define LANGUAGE_NORWEGIAN
#define LANGUAGE_CROATIAN
#define LANGUAGE_FARSI
#define LANGUAGE_ESTONIAN
#define LANGUAGE_TURKISH
#define LANGUAGE_LATVIAN
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
int i
Any GetTime(const OUString &val)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
DefTokenId nToken
static bool lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc, LanguageType aLanguages[])
Definition: srcedtw.cxx:779
static void lcl_Highlight(std::u16string_view aSource, TextPortions &aPortionList)
Definition: srcedtw.cxx:70
#define MAX_SYNTAX_HIGHLIGHT
Definition: srcedtw.cxx:65
IMPL_LINK_NOARG(SwSrcEditWindow, HorzScrollHdl, weld::Scrollbar &, void)
Definition: srcedtw.cxx:557
std::vector< TextPortion > TextPortions
Definition: srcedtw.cxx:68
#define MAX_HIGHLIGHTTIME
Definition: srcedtw.cxx:66
IMPL_LINK(SwSrcEditWindow, SyntaxTimerHdl, Timer *, pIdle, void)
Definition: srcedtw.cxx:575
#define SW_MOD()
Definition: swmodule.hxx:256
#define SAL_MAX_INT32
sal_uInt16 sal_Unicode
InvalidateFlags
WinBits const WB_BORDER
WinBits const WB_CLIPCHILDREN