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& 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 );
399 }
400}
401
403{
404 GrabFocus();
405 if ( m_pTextView )
407}
408
410{
411 switch(rCEvt.GetCommand())
412 {
413 case CommandEventId::ContextMenu:
415 break;
416 case CommandEventId::Wheel:
417 case CommandEventId::StartAutoScroll:
418 case CommandEventId::AutoScroll:
419 {
420 const CommandWheelData* pWData = rCEvt.GetWheelData();
421 if( !pWData || CommandWheelMode::ZOOM != pWData->GetMode() )
422 {
423 static_cast<SwSrcEditWindow*>(GetParent())->HandleWheelCommand( rCEvt );
424 }
425 }
426 break;
427
428 default:
429 if ( m_pTextView )
430 m_pTextView->Command( rCEvt );
431 else
432 Window::Command(rCEvt);
433 }
434}
435
437{
438 bool bDone = false;
439 SwSrcEditWindow* pSrcEditWin = static_cast<SwSrcEditWindow*>(GetParent());
440 bool bChange = !pSrcEditWin->IsReadonly() || !TextEngine::DoesKeyChangeText( rKEvt );
441 if(bChange)
442 bDone = m_pTextView->KeyInput( rKEvt );
443
444 SfxBindings& rBindings = static_cast<SwSrcEditWindow*>(GetParent())->GetSrcView()->GetViewFrame().GetBindings();
445 if ( !bDone )
446 {
447 if ( !SfxViewShell::Current()->KeyInput( rKEvt ) )
448 Window::KeyInput( rKEvt );
449 }
450 else
451 {
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() )
456 {
457 rBindings.Invalidate( SID_SAVEDOC );
458 rBindings.Invalidate( SID_DOC_MODIFIED );
459 }
460 if( rKEvt.GetKeyCode().GetCode() == KEY_INSERT )
461 rBindings.Invalidate( SID_ATTR_INSERT );
462 }
463
464 rBindings.Invalidate( SID_CUT );
465 rBindings.Invalidate( SID_COPY );
466
467 SwDocShell* pDocShell = pSrcEditWin->GetSrcView()->GetDocShell();
468 if(pSrcEditWin->GetTextEngine()->IsModified())
469 {
470 pDocShell->SetModified();
471 }
472}
473
475{
476 m_pTextView->Paint(rRenderContext, rRect);
477}
478
480{
481 // FIXME RenderContext
482
485 m_pOutWin->SetBackground(Wallpaper(rCol));
486 m_pOutWin->SetPointer(PointerStyle::Text);
487 m_pOutWin->Show();
488
489 // create Scrollbars
491 m_pHScrollbar->EnableRTL( false );
492 m_pHScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, HorzScrollHdl));
493 m_pHScrollbar->Show();
494
496 m_pVScrollbar->EnableRTL( false );
497 m_pVScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, VertScrollHdl));
498 m_pVScrollbar->Show();
499
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());
504
505 m_pTextEngine->SetUpdateMode( false );
506 m_pTextEngine->InsertView( m_pTextView.get() );
507
508 vcl::Font aFont;
509 aFont.SetTransparent( false );
510 aFont.SetFillColor( rCol );
511 SetPointFont(*GetOutDev(), aFont);
512 aFont = GetFont();
513 aFont.SetFillColor( rCol );
514 m_pOutWin->SetFont( aFont );
515 m_pTextEngine->SetFont( aFont );
516
517 m_aSyntaxIdle.SetInvokeHandler( LINK( this, SwSrcEditWindow, SyntaxTimerHdl ) );
518
519 m_pTextEngine->EnableUndo( true );
520 m_pTextEngine->SetUpdateMode( true );
521
522 m_pTextView->ShowCursor();
525
527 rBind.Invalidate( SID_TABLE_CELL );
528}
529
531{
532 // Extra method, not InitScrollBars, because also for TextEngine events.
533
534 m_pHScrollbar->SetRange( Range( 0, m_nCurTextWidth-1 ) );
535 m_pVScrollbar->SetRange( Range(0, m_pTextEngine->GetTextHeight()-1) );
536}
537
539{
541
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() );
551
552}
553
555{
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 );
561}
562
564{
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 );
570}
571
572IMPL_LINK( SwSrcEditWindow, SyntaxTimerHdl, Timer*, pIdle, void )
573{
574 tools::Time aSyntaxCheckStart( tools::Time::SYSTEM );
575 SAL_WARN_IF(m_pTextView == nullptr, "sw", "No View yet, but syntax highlighting?!");
576
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());
582 if(nCur > 40)
583 nCur -= 40;
584 else
585 nCur = 0;
586 if(!m_aSyntaxLineTable.empty())
587 for(sal_uInt16 i = 0; i < 80 && nCount < 40; i++, nCur++)
588 {
589 if(m_aSyntaxLineTable.find(nCur) != m_aSyntaxLineTable.end())
590 {
591 DoSyntaxHighlight( nCur );
592 m_aSyntaxLineTable.erase( nCur );
593 nCount++;
594 if(m_aSyntaxLineTable.empty())
595 break;
596 if((tools::Time( tools::Time::SYSTEM ).GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME )
597 {
598 break;
599 }
600 }
601 }
602
603 // when there is still anything left by then, go on from the beginning
604 while ( !m_aSyntaxLineTable.empty() && nCount < MAX_SYNTAX_HIGHLIGHT)
605 {
606 sal_uInt16 nLine = *m_aSyntaxLineTable.begin();
607 DoSyntaxHighlight( nLine );
608 m_aSyntaxLineTable.erase(nLine);
609 nCount ++;
610 if(tools::Time( tools::Time::SYSTEM ).GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME)
611 {
612 break;
613 }
614 }
615
616 if(!m_aSyntaxLineTable.empty() && !pIdle->IsActive())
617 pIdle->Start();
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;
625}
626
628{
629 // Because of DelayedSyntaxHighlight it could happen,
630 // that the line doesn't exist anymore!
631 if ( nPara >= m_pTextEngine->GetParagraphCount() )
632 return;
633
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()*/ );
646
647 if(!bTempModified)
649
650}
651
652void SwSrcEditWindow::ImpDoHighlight( std::u16string_view aSource, sal_uInt16 nLineOff )
653{
654 TextPortions aPortionList;
655 lcl_Highlight(aSource, aPortionList);
656
657 size_t nCount = aPortionList.size();
658 if ( !nCount )
659 return;
660
661 TextPortion& rLast = aPortionList[nCount-1];
662 if ( rLast.nStart > rLast.nEnd ) // Only until Bug from MD is resolved
663 {
664 nCount--;
665 aPortionList.pop_back();
666 if ( !nCount )
667 return;
668 }
669
670 {
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;
675
676 for ( size_t i = 0; i < nCount; i++ )
677 {
678 TextPortion& r = aPortionList[i];
679 if ( r.nStart > r.nEnd ) // only until Bug from MD is resolved
680 continue;
681
682 if ( r.nStart > nLastEnd )
683 {
684 // Can I rely on the fact that all except blank and tab
685 // are being highlighted?!
686 r.nStart = nLastEnd;
687 }
688 nLastEnd = r.nEnd+1;
689 if ( ( i == (nCount-1) ) && ( r.nEnd < aSource.size() ) )
690 r.nEnd = aSource.size();
691 }
692 }
693
694 for (TextPortion & r : aPortionList)
695 {
696 if ( r.nStart > r.nEnd ) // only until Bug from MD is resolved
697 continue;
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 );
705 }
706}
707
708void SwSrcEditWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
709{
710 const TextHint* pTextHint = dynamic_cast<const TextHint*>(&rHint);
711 if (!pTextHint)
712 return;
713
714 switch (pTextHint->GetId())
715 {
716 case SfxHintId::TextViewScrolled:
717 m_pHScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().X() );
718 m_pVScrollbar->SetThumbPos( m_pTextView->GetStartDocPos().Y() );
719 break;
720
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() );
726 break;
727
728 case SfxHintId::TextParaInserted:
729 case SfxHintId::TextParaContentChanged:
730 if ( !m_bHighlighting )
731 {
732 m_aSyntaxLineTable.insert( o3tl::narrowing<sal_uInt16>(pTextHint->GetValue()) );
734 }
735 break;
736 default: break;
737 }
738}
739
741{
742 m_pOutWin->Invalidate();
743 Window::ImplInvalidate(pRegion, nFlags);
744}
745
747{
748 switch(rCEvt.GetCommand())
749 {
750 case CommandEventId::Wheel:
751 case CommandEventId::StartAutoScroll:
752 case CommandEventId::AutoScroll:
753 {
754 const CommandWheelData* pWData = rCEvt.GetWheelData();
755 if( !pWData || CommandWheelMode::ZOOM != pWData->GetMode() )
757 }
758 break;
759 default:
760 Window::Command(rCEvt);
761 }
762}
763
765{
766 m_pTextView->Command(rCEvt);
768}
769
771{
772 if (m_pOutWin)
773 m_pOutWin->GrabFocus();
774}
775
776static bool lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc, LanguageType aLanguages[])
777{
778 switch(eEnc)
779 {
780 case RTL_TEXTENCODING_UTF7 :
781 case RTL_TEXTENCODING_UTF8 :
782 // don#t fill - all LANGUAGE_SYSTEM means unicode font has to be used
783 break;
784
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;
797 break;
798
799 case RTL_TEXTENCODING_IBM_865 :
800 //scandinavian
801 aLanguages[0] = LANGUAGE_FINNISH;
802 aLanguages[1] = LANGUAGE_NORWEGIAN;
803 aLanguages[2] = LANGUAGE_SWEDISH;
804 aLanguages[3] = LANGUAGE_DANISH;
805 break;
806
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;
817 break;
818
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 ;
825 break;
826
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;
830
831 case RTL_TEXTENCODING_IBM_861 :
832 case RTL_TEXTENCODING_APPLE_ICELAND :
833 aLanguages[0] = LANGUAGE_ICELANDIC;
834 break;
835
836 case RTL_TEXTENCODING_APPLE_CROATIAN:aLanguages[0] = LANGUAGE_CROATIAN; break;
837
838 case RTL_TEXTENCODING_IBM_437 :
839 case RTL_TEXTENCODING_ASCII_US : aLanguages[0] = LANGUAGE_ENGLISH; break;
840
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;
846 break;
847
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;
853 break;
854
855 case RTL_TEXTENCODING_IBM_860 :
856 aLanguages[0] = LANGUAGE_PORTUGUESE;
857 break;
858
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;
865 break;
866
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;
874 break;
875
876 case RTL_TEXTENCODING_APPLE_UKRAINIAN:
877 case RTL_TEXTENCODING_KOI8_U:
878 aLanguages[0] = LANGUAGE_UKRAINIAN;
879 break;
880
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;
886 break;
887
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;
895 break;
896
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;
906 break;
907
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;
916 break;
917
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;
924 break;
925
926 case RTL_TEXTENCODING_APPLE_THAI :
927 case RTL_TEXTENCODING_MS_874 :
928 case RTL_TEXTENCODING_TIS_620 :
929 aLanguages[0] = LANGUAGE_THAI;
930 break;
931 default: aLanguages[0] = Application::GetSettings().GetUILanguageTag().getLanguageType();
932 }
933 return aLanguages[0] != LANGUAGE_SYSTEM;
934}
936{
937 OUString sFontName(
939 value_or(OUString()));
940 if(sFontName.isEmpty())
941 {
942 LanguageType aLanguages[5] =
943 {
945 };
946 vcl::Font aFont;
948 {
949 //TODO: check for multiple languages
950 aFont = OutputDevice::GetDefaultFont(DefaultFontType::FIXED, aLanguages[0], GetDefaultFontFlags::NONE, GetOutDev());
951 }
952 else
953 aFont = OutputDevice::GetDefaultFont(DefaultFontType::SANS_UNICODE,
954 Application::GetSettings().GetLanguageTag().getLanguageType(), GetDefaultFontFlags::NONE, GetOutDev());
955 sFontName = aFont.GetFamilyName();
956 }
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);
961
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
966 aSize.setHeight(
968 aFont.SetFontSize(m_pOutWin->LogicToPixel(aSize, MapMode(MapUnit::MapTwip)));
969 GetTextEngine()->SetFont( aFont );
970 m_pOutWin->SetFont(aFont);
971}
972
973void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding)
974{
975 m_eSourceEncoding = eEncoding;
976 SetFont();
977}
978
979/* 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 setY(tools::Long nY)
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 SAL_WARN_UNUSED_RESULT 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:1437
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:126
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:770
Idle m_aSyntaxIdle
Definition: srcedtw.hxx:85
std::unique_ptr< ExtTextEngine > m_pTextEngine
Definition: srcedtw.hxx:66
bool IsModified() const
Definition: srcedtw.hxx:128
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: srcedtw.cxx:708
virtual void ImplInvalidate(const vcl::Region *pRegion, InvalidateFlags nFlags) override
Definition: srcedtw.cxx:740
SwSrcView * GetSrcView()
Definition: srcedtw.hxx:120
void HandleWheelCommand(const CommandEvent &rCEvt)
Definition: srcedtw.cxx:764
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:652
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:935
rtl_TextEncoding m_eSourceEncoding
Definition: srcedtw.hxx:81
virtual ~SwSrcEditWindow() override
Definition: srcedtw.cxx:258
void SetScrollBarRanges()
Definition: srcedtw.cxx:530
css::uno::Reference< css::beans::XMultiPropertySet > m_xNotifier
Definition: srcedtw.hxx:77
virtual void Command(const CommandEvent &rCEvt) override
Definition: srcedtw.cxx:746
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:627
friend class ChangesListener
Definition: srcedtw.hxx:63
TextEngine * GetTextEngine()
Definition: srcedtw.hxx:118
void CreateTextEngine()
Definition: srcedtw.cxx:479
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:538
void SetTextEncoding(rtl_TextEncoding eEncoding)
Definition: srcedtw.cxx:973
bool IsReadonly() const
Definition: srcedtw.hxx:132
SwDocShell * GetDocShell()
Definition: srcview.cxx:245
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:474
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:409
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: srcedtw.cxx:402
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:436
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
Size GetOutputSizePixel() const
void SetPointFont(vcl::RenderContext &rRenderContext, const vcl::Font &rFont)
void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
void SetHelpId(const OUString &)
void SetBackground()
int nCount
DocumentType eType
ITALIC_NONE
WEIGHT_NORMAL
constexpr OUStringLiteral 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:776
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:554
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:572
#define SW_MOD()
Definition: swmodule.hxx:254
#define SAL_MAX_INT32
sal_uInt16 sal_Unicode
InvalidateFlags
WinBits const WB_BORDER
WinBits const WB_CLIPCHILDREN