xref: /core/editeng/source/editeng/impedit.hxx (revision bc413e15)
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 #pragma once
20 
21 #include <eerdll2.hxx>
22 #include <editdoc.hxx>
23 #include "editsel.hxx"
24 #include "editundo.hxx"
25 #include "editstt2.hxx"
26 #include <editeng/editdata.hxx>
27 #include <editeng/SpellPortions.hxx>
28 #include <editeng/editeng.hxx>
29 #include <editeng/editview.hxx>
30 #include <svtools/colorcfg.hxx>
31 #include <editeng/outliner.hxx>
32 #include <vcl/virdev.hxx>
33 #include <vcl/cursor.hxx>
34 #include <vcl/vclptr.hxx>
35 #include <tools/fract.hxx>
36 #include <vcl/idle.hxx>
37 #include <vcl/commandevent.hxx>
38 #include <vcl/ptrstyle.hxx>
39 
40 #include <vcl/dndhelp.hxx>
41 #include <svl/ondemand.hxx>
42 #include <svl/languageoptions.hxx>
43 #include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
44 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
45 #include <com/sun/star/linguistic2/XHyphenator.hpp>
46 #include <com/sun/star/lang/Locale.hpp>
47 #include <com/sun/star/i18n/XBreakIterator.hpp>
48 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
49 #include <com/sun/star/i18n/WordType.hpp>
50 #include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
51 #include <com/sun/star/uno/Sequence.hxx>
52 
53 #include <i18nlangtag/lang.h>
54 #include <o3tl/deleter.hxx>
55 #include <o3tl/typed_flags_set.hxx>
56 
57 #include <functional>
58 #include <optional>
59 #include <memory>
60 #include <tuple>
61 #include <string_view>
62 #include <vector>
63 
64 class EditView;
65 class EditEngine;
66 class OutlinerSearchable;
67 
68 class SvxSearchItem;
69 class SvxLRSpaceItem;
70 class TextRanger;
71 class SvKeyValueIterator;
72 class SvxForbiddenCharactersTable;
73 class SvtCTLOptions;
74 namespace vcl { class Window; }
75 class SvxNumberFormat;
76 namespace com::sun::star::datatransfer::clipboard {
77     class XClipboard;
78 }
79 
80 namespace editeng {
81     struct MisspellRanges;
82 }
83 
84 #define DEL_LEFT    1
85 #define DEL_RIGHT   2
86 #define TRAVEL_X_DONTKNOW           0xFFFFFFFF
87 #define CURSOR_BIDILEVEL_DONTKNOW   0xFFFF
88 #define MAXCHARSINPARA              0x3FFF-CHARPOSGROW  // Max 16K, because WYSIWYG array
89 #define LINE_SEP    '\x0A'
90 
91 #define ATTRSPECIAL_WHOLEWORD   1
92 #define ATTRSPECIAL_EDGE        2
93 
94 enum class GetCursorFlags {
95     NONE                = 0x0000,
96     TextOnly            = 0x0001,
97     StartOfLine         = 0x0002,
98     EndOfLine           = 0x0004,
99     PreferPortionStart  = 0x0008,
100 };
101 namespace o3tl {
102     template<> struct typed_flags<GetCursorFlags> : is_typed_flags<GetCursorFlags, 0x0f> {};
103 }
104 
105 
106 struct DragAndDropInfo
107 {
108     tools::Rectangle           aCurCursor;
109     tools::Rectangle           aCurSavedCursor;
110     sal_uInt16          nSensibleRange;
111     sal_uInt16          nCursorWidth;
112     ESelection          aBeginDragSel;
113     EditPaM             aDropDest;
114     sal_Int32           nOutlinerDropDest;
115     ESelection          aDropSel;
116     VclPtr<VirtualDevice> pBackground;
117     const SvxFieldItem* pField;
118     bool            bVisCursor              : 1;
119     bool            bDroppedInMe            : 1;
120     bool            bStarterOfDD            : 1;
121     bool            bHasValidData           : 1;
122     bool            bUndoAction             : 1;
123     bool            bOutlinerMode           : 1;
124     bool            bDragAccepted           : 1;
125 
126     DragAndDropInfo()
127       : nSensibleRange(0), nCursorWidth(0), nOutlinerDropDest(0), pBackground(nullptr),
128         pField(nullptr), bVisCursor(false), bDroppedInMe(false), bStarterOfDD(false),
129         bHasValidData(false), bUndoAction(false), bOutlinerMode(false), bDragAccepted(false)
130     {
131     }
132     ~DragAndDropInfo()
133     {
134             pBackground.disposeAndClear();
135     }
136 };
137 
138 struct ImplIMEInfos
139 {
140     OUString    aOldTextAfterStartPos;
141     std::unique_ptr<ExtTextInputAttr[]> pAttribs;
142     EditPaM     aPos;
143     sal_Int32   nLen;
144     bool        bWasCursorOverwrite;
145 
146             ImplIMEInfos( const EditPaM& rPos, const OUString& rOldTextAfterStartPos );
147             ~ImplIMEInfos();
148 
149     void    CopyAttribs( const ExtTextInputAttr* pA, sal_uInt16 nL );
150     void    DestroyAttribs();
151 };
152 
153 // #i18881# to be able to identify the positions of changed words
154 // the positions of each portion need to be saved
155 typedef std::vector<EditSelection>  SpellContentSelections;
156 
157 struct SpellInfo
158 {
159     EditPaM         aCurSentenceStart;
160     svx::SpellPortions    aLastSpellPortions;
161     SpellContentSelections  aLastSpellContentSelections;
162     EESpellState    eState;
163     EPaM            aSpellStart;
164     EPaM            aSpellTo;
165     bool        bSpellToEnd;
166     bool        bMultipleDoc;
167     SpellInfo() : eState(EESpellState::Ok), bSpellToEnd(true), bMultipleDoc(false)
168         { }
169 };
170 
171 // used for text conversion
172 struct ConvInfo
173 {
174     EPaM            aConvStart;
175     EPaM            aConvTo;
176     EPaM            aConvContinue;    // position to start search for next text portion (word) with
177     bool            bConvToEnd;
178     bool            bMultipleDoc;
179 
180     ConvInfo() : bConvToEnd(true), bMultipleDoc(false) {}
181 };
182 
183 struct FormatterFontMetric
184 {
185     sal_uInt16 nMaxAscent;
186     sal_uInt16 nMaxDescent;
187 
188     FormatterFontMetric() : nMaxAscent(0), nMaxDescent(0) { /* nMinLeading = 0xFFFF; */ }
189     sal_uInt16  GetHeight() const       { return nMaxAscent+nMaxDescent; }
190 };
191 
192 class IdleFormattter : public Idle
193 {
194 private:
195     EditView*   pView;
196     int         nRestarts;
197 
198 public:
199                 IdleFormattter();
200                 virtual ~IdleFormattter() override;
201 
202     void        DoIdleFormat( EditView* pV );
203     void        ForceTimeout();
204     void        ResetRestarts() { nRestarts = 0; }
205     EditView*   GetView()       { return pView; }
206 };
207 
208 class ImpEditView;
209 /// This is meant just for Calc, where all positions in logical units (twips for LOK) are computed by
210 /// doing independent pixel-alignment for each cell's size. LOKSpecialPositioning stores
211 /// both 'output-area' and 'visible-doc-position' in pure logical unit (twips for LOK).
212 /// This allows the cursor/selection messages to be in regular(print) twips unit like in Writer.
213 class LOKSpecialPositioning
214 {
215 public:
216     LOKSpecialPositioning(const ImpEditView& rImpEditView, MapUnit eUnit, const tools::Rectangle& rOutputArea,
217                           const Point& rVisDocStartPos);
218 
219     void ReInit(MapUnit eUnit, const tools::Rectangle& rOutputArea, const Point& rVisDocStartPos);
220 
221     void SetOutputArea(const tools::Rectangle& rOutputArea);
222     const tools::Rectangle& GetOutputArea() const;
223     void SetVisDocStartPos(const Point& rVisDocStartPos);
224 
225     bool IsVertical() const;
226     bool IsTopToBottom() const;
227 
228     tools::Long GetVisDocLeft() const { return maVisDocStartPos.X(); }
229     tools::Long GetVisDocTop() const  { return maVisDocStartPos.Y(); }
230     tools::Long GetVisDocRight() const  { return maVisDocStartPos.X() + (!IsVertical() ? maOutArea.GetWidth() : maOutArea.GetHeight()); }
231     tools::Long GetVisDocBottom() const { return maVisDocStartPos.Y() + (!IsVertical() ? maOutArea.GetHeight() : maOutArea.GetWidth()); }
232     tools::Rectangle GetVisDocArea() const;
233 
234     Point            GetWindowPos(const Point& rDocPos, MapUnit eDocPosUnit) const;
235     tools::Rectangle GetWindowPos(const tools::Rectangle& rDocRect, MapUnit eDocRectUnit) const;
236 
237     Point GetRefPoint() const;
238 
239 private:
240     Point convertUnit(const Point& rPos, MapUnit ePosUnit) const;
241     tools::Rectangle convertUnit(const tools::Rectangle& rRect, MapUnit eRectUnit) const;
242 
243     const ImpEditView& mrImpEditView;
244     tools::Rectangle maOutArea;
245     Point maVisDocStartPos;
246     MapUnit meUnit;
247 };
248 
249 
250 
251 class ImpEditView : public vcl::unohelper::DragAndDropClient
252 {
253     friend class EditView;
254     friend class EditEngine;
255     friend class ImpEditEngine;
256     using vcl::unohelper::DragAndDropClient::dragEnter;
257     using vcl::unohelper::DragAndDropClient::dragExit;
258     using vcl::unohelper::DragAndDropClient::dragOver;
259 
260 private:
261     EditView*                 pEditView;
262     std::unique_ptr<vcl::Cursor, o3tl::default_delete<vcl::Cursor>>  pCursor;
263     std::optional<Color>      mxBackgroundColor;
264     /// Containing view shell, if any.
265     OutlinerViewShell*        mpViewShell;
266     /// Another shell, just listening to our state, if any.
267     OutlinerViewShell*        mpOtherShell;
268     EditEngine*               pEditEngine;
269     VclPtr<vcl::Window>       pOutWin;
270     EditView::OutWindowSet    aOutWindowSet;
271     std::optional<PointerStyle>  mxPointer;
272     std::unique_ptr<DragAndDropInfo>  pDragAndDropInfo;
273 
274     css::uno::Reference< css::datatransfer::dnd::XDragSourceListener > mxDnDListener;
275 
276 
277     tools::Long                nInvMore;
278     EVControlBits       nControl;
279     sal_uInt32          nTravelXPos;
280     GetCursorFlags      nExtraCursorFlags;
281     sal_uInt16          nCursorBidiLevel;
282     sal_uInt16          nScrollDiffX;
283     bool                bReadOnly;
284     bool                bClickedInSelection;
285     bool                bActiveDragAndDropListener;
286 
287     Point               aAnchorPoint;
288     tools::Rectangle           aOutArea;
289     Point               aVisDocStartPos;
290     EESelectionMode     eSelectionMode;
291     EditSelection       aEditSelection;
292     EEAnchorMode        eAnchorMode;
293 
294     /// mechanism to change from the classic refresh mode that simply
295     // invalidates the area where text was changed. When set, the invalidate
296     // and the direct repaint of the Window-plugged EditView will be suppressed.
297     // Instead, a consumer that has registered using an EditViewCallbacks
298     // incarnation has to handle that. Used e.g. to represent the edited text
299     // in Draw/Impress in an OverlayObject which avoids evtl. expensive full
300     // repaints of the EditView(s)
301     EditViewCallbacks* mpEditViewCallbacks;
302     std::unique_ptr<LOKSpecialPositioning> mpLOKSpecialPositioning;
303     bool mbBroadcastLOKViewCursor:1;
304     bool mbSuppressLOKMessages:1;
305 
306     EditViewCallbacks* getEditViewCallbacks() const
307     {
308         return mpEditViewCallbacks;
309     }
310 
311     void lokSelectionCallback(const std::optional<tools::PolyPolygon> &pPolyPoly, bool bStartHandleVisible, bool bEndHandleVisible);
312 
313     void setEditViewCallbacks(EditViewCallbacks* pEditViewCallbacks)
314     {
315         mpEditViewCallbacks = pEditViewCallbacks;
316     }
317 
318     void InvalidateAtWindow(const tools::Rectangle& rRect);
319 
320     css::uno::Reference<css::datatransfer::clipboard::XClipboard> GetClipboard() const;
321 
322     void SetBroadcastLOKViewCursor(bool bSet)
323     {
324         mbBroadcastLOKViewCursor = bSet;
325     }
326 
327 protected:
328 
329     // DragAndDropClient
330     void dragGestureRecognized(const css::datatransfer::dnd::DragGestureEvent& dge) override;
331     void dragDropEnd( const css::datatransfer::dnd::DragSourceDropEvent& dsde ) override;
332     void drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde) override;
333     void dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) override;
334     void dragExit( const css::datatransfer::dnd::DropTargetEvent& dte ) override;
335     void dragOver(const css::datatransfer::dnd::DropTargetDragEvent& dtde) override;
336 
337     void ShowDDCursor( const tools::Rectangle& rRect );
338     void HideDDCursor();
339 
340     void ImplDrawHighlightRect(OutputDevice& rTarget, const Point& rDocPosTopLeft, const Point& rDocPosBottomRight, tools::PolyPolygon* pPolyPoly);
341     tools::Rectangle ImplGetEditCursor(EditPaM& aPaM, GetCursorFlags nShowCursorFlags,
342             sal_Int32& nTextPortionStart, const ParaPortion* pParaPortion) const;
343 
344 public:
345                     ImpEditView( EditView* pView, EditEngine* pEng, vcl::Window* pWindow );
346                     virtual ~ImpEditView() override;
347 
348     EditView*       GetEditViewPtr() { return pEditView; }
349 
350     sal_uInt16      GetScrollDiffX() const          { return nScrollDiffX; }
351     void            SetScrollDiffX( sal_uInt16 n )  { nScrollDiffX = n; }
352 
353     sal_uInt16      GetCursorBidiLevel() const      { return nCursorBidiLevel; }
354     void            SetCursorBidiLevel( sal_uInt16 n ) { nCursorBidiLevel = n; }
355 
356     Point           GetDocPos( const Point& rWindowPos ) const;
357     Point           GetWindowPos( const Point& rDocPos ) const;
358     tools::Rectangle       GetWindowPos( const tools::Rectangle& rDocPos ) const;
359 
360     void                SetOutputArea( const tools::Rectangle& rRect );
361     void                ResetOutputArea( const tools::Rectangle& rRect );
362     const tools::Rectangle&    GetOutputArea() const   { return aOutArea; }
363 
364     bool            IsVertical() const;
365     bool            IsTopToBottom() const;
366 
367     bool            PostKeyEvent( const KeyEvent& rKeyEvent, vcl::Window const * pFrameWin );
368 
369     bool            MouseButtonUp( const MouseEvent& rMouseEvent );
370     bool            MouseButtonDown( const MouseEvent& rMouseEvent );
371     void            ReleaseMouse();
372     bool            MouseMove( const MouseEvent& rMouseEvent );
373     bool            Command(const CommandEvent& rCEvt);
374 
375     void            CutCopy( css::uno::Reference< css::datatransfer::clipboard::XClipboard > const & rxClipboard, bool bCut );
376     void            Paste( css::uno::Reference< css::datatransfer::clipboard::XClipboard > const & rxClipboard, bool bUseSpecial = false );
377 
378     void            SetVisDocStartPos( const Point& rPos ) { aVisDocStartPos = rPos; }
379 
380     tools::Long            GetVisDocLeft() const { return aVisDocStartPos.X(); }
381     tools::Long            GetVisDocTop() const { return aVisDocStartPos.Y(); }
382     tools::Long            GetVisDocRight() const { return aVisDocStartPos.X() + ( !IsVertical() ? aOutArea.GetWidth() : aOutArea.GetHeight() ); }
383     tools::Long            GetVisDocBottom() const { return aVisDocStartPos.Y() + ( !IsVertical() ? aOutArea.GetHeight() : aOutArea.GetWidth() ); }
384     tools::Rectangle       GetVisDocArea() const;
385 
386     const EditSelection&  GetEditSelection() const { return aEditSelection; }
387     void            SetEditSelection( const EditSelection& rEditSelection );
388     bool            HasSelection() const { return aEditSelection.HasRange(); }
389 
390     void SelectionChanged();
391     void            DrawSelectionXOR() { DrawSelectionXOR( aEditSelection ); }
392     void            DrawSelectionXOR( EditSelection, vcl::Region* pRegion = nullptr, OutputDevice* pTargetDevice = nullptr );
393     void GetSelectionRectangles(EditSelection aTmpSel, std::vector<tools::Rectangle>& rLogicRects);
394 
395     void ScrollStateChange();
396 
397     OutputDevice&   GetOutputDevice() const;
398     weld::Widget*   GetPopupParent(tools::Rectangle& rRect) const;
399     vcl::Window*    GetWindow() const           { return pOutWin; }
400 
401     void            SetSelectionMode( EESelectionMode eMode );
402 
403     inline PointerStyle GetPointer();
404 
405     inline vcl::Cursor*     GetCursor();
406 
407     void            AddDragAndDropListeners();
408     void            RemoveDragAndDropListeners();
409 
410     bool            IsBulletArea( const Point& rPos, sal_Int32* pPara );
411 
412 //  For the Selection Engine...
413     void            CreateAnchor();
414     void            DeselectAll();
415     bool            SetCursorAtPoint( const Point& rPointPixel );
416     bool            IsSelectionAtPoint( const Point& rPosPixel );
417     bool            IsInSelection( const EditPaM& rPaM );
418 
419 
420     void            SetAnchorMode( EEAnchorMode eMode );
421     EEAnchorMode    GetAnchorMode() const           { return eAnchorMode; }
422     void            CalcAnchorPoint();
423     void            RecalcOutputArea();
424 
425     tools::Rectangle GetEditCursor() const;
426 
427     void            ShowCursor( bool bGotoCursor, bool bForceVisCursor );
428     Pair            Scroll( tools::Long ndX, tools::Long ndY, ScrollRangeCheck nRangeCheck = ScrollRangeCheck::NoNegative );
429 
430     void        SetInsertMode( bool bInsert );
431     bool        IsInsertMode() const            { return !( nControl & EVControlBits::OVERWRITE ); }
432 
433     bool        IsPasteEnabled() const          { return bool( nControl & EVControlBits::ENABLEPASTE ); }
434 
435     bool        DoSingleLinePaste() const       { return bool( nControl & EVControlBits::SINGLELINEPASTE ); }
436     bool        DoAutoScroll() const            { return bool( nControl & EVControlBits::AUTOSCROLL ); }
437     bool        DoAutoSize() const              { return bool( nControl & EVControlBits::AUTOSIZE ); }
438     bool        DoAutoWidth() const             { return bool( nControl & EVControlBits::AUTOSIZEX); }
439     bool        DoAutoHeight() const            { return bool( nControl & EVControlBits::AUTOSIZEY); }
440     bool        DoInvalidateMore() const        { return bool( nControl & EVControlBits::INVONEMORE ); }
441 
442     void        SetBackgroundColor( const Color& rColor );
443     const Color& GetBackgroundColor() const;
444 
445     /// Informs this edit view about which view shell contains it.
446     void RegisterViewShell(OutlinerViewShell* pViewShell);
447     const OutlinerViewShell* GetViewShell() const;
448     /// Informs this edit view about which other shell listens to it.
449     void RegisterOtherShell(OutlinerViewShell* pViewShell);
450 
451     bool            IsWrongSpelledWord( const EditPaM& rPaM, bool bMarkIfWrong );
452     OUString        SpellIgnoreWord();
453 
454     const SvxFieldItem* GetField( const Point& rPos, sal_Int32* pPara, sal_Int32* pPos ) const;
455     void            DeleteSelected();
456 
457     //  If possible invalidate more than OutputArea, for the DrawingEngine text frame
458     void            SetInvalidateMore( sal_uInt16 nPixel ) { nInvMore = nPixel; }
459     sal_uInt16      GetInvalidateMore() const { return static_cast<sal_uInt16>(nInvMore); }
460 
461     void InitLOKSpecialPositioning(MapUnit eUnit, const tools::Rectangle& rOutputArea,
462                                    const Point& rVisDocStartPos);
463     void SetLOKSpecialOutputArea(const tools::Rectangle& rOutputArea);
464     const tools::Rectangle & GetLOKSpecialOutputArea() const;
465     void SetLOKSpecialVisArea(const tools::Rectangle& rVisArea);
466     tools::Rectangle GetLOKSpecialVisArea() const;
467     bool HasLOKSpecialPositioning() const;
468 
469     void SuppressLOKMessages(bool bSet) { mbSuppressLOKMessages = bSet; }
470     bool IsSuppressLOKMessages() const { return mbSuppressLOKMessages; }
471 };
472 
473 
474 //  ImpEditEngine
475 
476 
477 class ImpEditEngine : public SfxListener
478 {
479     friend class EditEngine;
480 
481     typedef EditEngine::ViewsType ViewsType;
482 
483 private:
484     std::shared_ptr<editeng::SharedVclResources> pSharedVCL;
485 
486 
487     // Data ...
488 
489 
490     // Document Specific data ...
491     ParaPortionList     aParaPortionList;       // Formatting
492     Size                aPaperSize;             // Layout
493     Size                aMinAutoPaperSize;      // Layout ?
494     Size                aMaxAutoPaperSize;      // Layout ?
495     tools::Long mnMinColumnWrapHeight = 0; // Corresponds to graphic object height
496     EditDoc             aEditDoc;               // Document content
497 
498     // Engine Specific data ...
499     EditEngine*         pEditEngine;
500     ViewsType           aEditViews;
501     EditView*           pActiveView;
502     std::unique_ptr<TextRanger> pTextRanger;
503 
504     SfxStyleSheetPool*  pStylePool;
505     SfxItemPool*        pTextObjectPool;
506 
507     VclPtr< VirtualDevice> pVirtDev;
508     VclPtr< OutputDevice > pRefDev;
509     VclPtr<VirtualDevice> mpOwnDev;
510 
511     svtools::ColorConfig maColorConfig;
512     mutable std::unique_ptr<SvtCTLOptions> pCTLOptions;
513 
514     mutable std::unique_ptr<SfxItemSet> pEmptyItemSet;
515     EditUndoManager*    pUndoManager;
516     std::unique_ptr<ESelection> pUndoMarkSelection;
517 
518     std::unique_ptr<ImplIMEInfos> mpIMEInfos;
519 
520     OUString            aWordDelimiters;
521 
522     EditSelFunctionSet  aSelFuncSet;
523     EditSelectionEngine aSelEngine;
524 
525     Color               maBackgroundColor;
526 
527     sal_uInt16          nStretchX;
528     sal_uInt16          nStretchY;
529 
530     CharCompressType    nAsianCompressionMode;
531 
532     EEHorizontalTextDirection eDefaultHorizontalTextDirection;
533 
534     sal_Int32          nBigTextObjectStart;
535     css::uno::Reference< css::linguistic2::XSpellChecker1 > xSpeller;
536     css::uno::Reference< css::linguistic2::XHyphenator >    xHyphenator;
537     std::unique_ptr<SpellInfo> pSpellInfo;
538     mutable css::uno::Reference < css::i18n::XBreakIterator > xBI;
539     mutable css::uno::Reference < css::i18n::XExtendedInputSequenceChecker > xISC;
540 
541     std::unique_ptr<ConvInfo> pConvInfo;
542 
543     OUString            aAutoCompleteText;
544 
545     InternalEditStatus  aStatus;
546 
547     LanguageType        eDefLanguage;
548 
549     OnDemandLocaleDataWrapper       xLocaleDataWrapper;
550     OnDemandTransliterationWrapper  xTransliterationWrapper;
551 
552     // For Formatting / Update...
553     std::vector<std::unique_ptr<DeletedNodeInfo> > aDeletedNodes;
554     tools::Rectangle           aInvalidRect;
555     tools::Long         nCurTextHeight;
556     tools::Long         nCurTextHeightNTP;  // without trailing empty paragraphs
557     sal_uInt16          nOnePixelInRef;
558 
559     IdleFormattter      aIdleFormatter;
560 
561     Timer               aOnlineSpellTimer;
562 
563     // For Chaining
564     sal_Int32 mnOverflowingPara = -1;
565     sal_Int32 mnOverflowingLine = -1;
566     bool mbNeedsChainingHandling = false;
567 
568     sal_Int16 mnColumns = 1;
569     sal_Int32 mnColumnSpacing = 0;
570 
571     // If it is detected at one point that the StatusHdl has to be called, but
572     // this should not happen immediately (critical section):
573     Timer               aStatusTimer;
574     Size                aLOKSpecialPaperSize;
575 
576     Link<EditStatus&,void>         aStatusHdlLink;
577     Link<EENotify&,void>           aNotifyHdl;
578     Link<HtmlImportInfo&,void>     aHtmlImportHdl;
579     Link<RtfImportInfo&,void>      aRtfImportHdl;
580     Link<MoveParagraphsInfo&,void> aBeginMovingParagraphsHdl;
581     Link<MoveParagraphsInfo&,void> aEndMovingParagraphsHdl;
582     Link<PasteOrDropInfos&,void>   aBeginPasteOrDropHdl;
583     Link<PasteOrDropInfos&,void>   aEndPasteOrDropHdl;
584     Link<LinkParamNone*,void>      aModifyHdl;
585     Link<EditView*,void>           maBeginDropHdl;
586     Link<EditView*,void>           maEndDropHdl;
587 
588     bool            bKernAsianPunctuation:1;
589     bool            bAddExtLeading:1;
590     bool            bIsFormatting:1;
591     bool            bFormatted:1;
592     bool            bInSelection:1;
593     bool            bIsInUndo:1;
594     bool            bUpdateLayout:1;
595     bool            bUndoEnabled:1;
596     bool            bDowning:1;
597     bool            bUseAutoColor:1;
598     bool            bForceAutoColor:1;
599     bool            bCallParaInsertedOrDeleted:1;
600     bool            bFirstWordCapitalization:1;   // specifies if auto-correction should capitalize the first word or not
601     bool            mbLastTryMerge:1;
602     bool            mbReplaceLeadingSingleQuotationMark:1;
603 
604     bool            mbNbspRunNext;  // can't be a bitfield as it is passed as bool&
605 
606 
607     // Methods...
608 
609 
610     void                CursorMoved( const ContentNode* pPrevNode );
611     void                ParaAttribsChanged( ContentNode const * pNode, bool bIgnoreUndoCheck = false );
612     void                TextModified();
613     void                CalcHeight( ParaPortion* pPortion );
614 
615     void                InsertUndo( std::unique_ptr<EditUndo> pUndo, bool bTryMerge = false );
616     void                ResetUndoManager();
617     bool            HasUndoManager() const  { return pUndoManager != nullptr; }
618 
619     std::unique_ptr<EditUndoSetAttribs> CreateAttribUndo( EditSelection aSel, const SfxItemSet& rSet );
620 
621     std::unique_ptr<EditTextObject> GetEmptyTextObject();
622 
623     std::tuple<const ParaPortion*, const EditLine*, tools::Long> GetPortionAndLine(Point aDocPos);
624     EditPaM             GetPaM( Point aDocPos, bool bSmart = true );
625     bool IsTextPos(const Point& rDocPos, sal_uInt16 nBorder);
626     tools::Long GetXPos(const ParaPortion* pParaPortion, const EditLine* pLine, sal_Int32 nIndex, bool bPreferPortionStart = false) const;
627     tools::Long GetPortionXOffset(const ParaPortion* pParaPortion, const EditLine* pLine, sal_Int32 nTextPortion) const;
628     sal_Int32 GetChar(const ParaPortion* pParaPortion, const EditLine* pLine, tools::Long nX, bool bSmart = true);
629     Range GetLineXPosStartEnd( const ParaPortion* pParaPortion, const EditLine* pLine ) const;
630 
631     void                ParaAttribsToCharAttribs( ContentNode* pNode );
632     void                GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const;
633 
634     std::unique_ptr<EditTextObject>
635                         CreateTextObject(EditSelection aSelection, SfxItemPool*, bool bAllowBigObjects = false, sal_Int32 nBigObjStart = 0);
636     EditSelection       InsertTextObject( const EditTextObject&, EditPaM aPaM );
637     EditSelection       PasteText( css::uno::Reference< css::datatransfer::XTransferable > const & rxDataObj, const OUString& rBaseURL, const EditPaM& rPaM, bool bUseSpecial );
638 
639     void                CheckPageOverflow();
640 
641     void                Clear();
642     EditPaM             RemoveText();
643     bool                CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY );
644     void                CreateAndInsertEmptyLine( ParaPortion* pParaPortion );
645     bool                FinishCreateLines( ParaPortion* pParaPortion );
646     void                CreateTextPortions( ParaPortion* pParaPortion, sal_Int32& rStartPos /*, sal_Bool bCreateBlockPortions */ );
647     void                RecalcTextPortion( ParaPortion* pParaPortion, sal_Int32 nStartPos, sal_Int32 nNewChars );
648     sal_Int32           SplitTextPortion( ParaPortion* pParaPortion, sal_Int32 nPos,  EditLine* pCurLine = nullptr );
649     void                SeekCursor( ContentNode* pNode, sal_Int32 nPos, SvxFont& rFont, OutputDevice* pOut = nullptr );
650     void                RecalcFormatterFontMetrics( FormatterFontMetric& rCurMetrics, SvxFont& rFont );
651     void                CheckAutoPageSize();
652 
653     void                ImpBreakLine( ParaPortion* pParaPortion, EditLine* pLine, TextPortion const * pPortion, sal_Int32 nPortionStart, tools::Long nRemainingWidth, bool bCanHyphenate );
654     void                ImpAdjustBlocks( ParaPortion* pParaPortion, EditLine* pLine, tools::Long nRemainingSpace );
655     EditPaM             ImpConnectParagraphs( ContentNode* pLeft, ContentNode* pRight, bool bBackward = false );
656     EditPaM             ImpDeleteSelection(const EditSelection& rCurSel);
657     EditPaM             ImpInsertParaBreak( EditPaM& rPaM, bool bKeepEndingAttribs = true );
658     EditPaM             ImpInsertParaBreak( const EditSelection& rEditSelection );
659     EditPaM             ImpInsertText(const EditSelection& aCurEditSelection, const OUString& rStr);
660     EditPaM             ImpInsertFeature(const EditSelection& rCurSel, const SfxPoolItem& rItem);
661     void                ImpRemoveChars( const EditPaM& rPaM, sal_Int32 nChars );
662     void                ImpRemoveParagraph( sal_Int32 nPara );
663     EditSelection       ImpMoveParagraphs( Range aParagraphs, sal_Int32 nNewPos );
664 
665     EditPaM             ImpFastInsertText( EditPaM aPaM, const OUString& rStr );
666     EditPaM             ImpFastInsertParagraph( sal_Int32 nPara );
667 
668     bool                ImpCheckRefMapMode();
669 
670     bool                ImplHasText() const;
671 
672     void                ImpFindKashidas( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEnd, std::vector<sal_Int32>& rArray );
673 
674     void                InsertContent( ContentNode* pNode, sal_Int32 nPos );
675     EditPaM             SplitContent( sal_Int32 nNode, sal_Int32 nSepPos );
676     EditPaM             ConnectContents( sal_Int32 nLeftNode, bool bBackward );
677 
678     void                ShowParagraph( sal_Int32 nParagraph, bool bShow );
679 
680     EditPaM             PageUp( const EditPaM& rPaM, EditView const * pView);
681     EditPaM             PageDown( const EditPaM& rPaM, EditView const * pView);
682     EditPaM             CursorUp( const EditPaM& rPaM, EditView const * pEditView );
683     EditPaM             CursorDown( const EditPaM& rPaM, EditView const * pEditView );
684     EditPaM             CursorLeft( const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode = css::i18n::CharacterIteratorMode::SKIPCELL );
685     EditPaM             CursorRight( const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode = css::i18n::CharacterIteratorMode::SKIPCELL );
686     EditPaM             CursorStartOfLine( const EditPaM& rPaM );
687     EditPaM             CursorEndOfLine( const EditPaM& rPaM );
688     static EditPaM      CursorStartOfParagraph( const EditPaM& rPaM );
689     static EditPaM      CursorEndOfParagraph( const EditPaM& rPaM );
690     EditPaM             CursorStartOfDoc();
691     EditPaM             CursorEndOfDoc();
692     EditPaM             WordLeft( const EditPaM& rPaM );
693     EditPaM             WordRight( const EditPaM& rPaM, sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES );
694     EditPaM             StartOfWord( const EditPaM& rPaM );
695     EditPaM             EndOfWord( const EditPaM& rPaM );
696     EditSelection       SelectWord( const EditSelection& rCurSelection, sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, bool bAcceptStartOfWord = true );
697     EditSelection       SelectSentence( const EditSelection& rCurSel ) const;
698     EditPaM             CursorVisualLeftRight( EditView const * pEditView, const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode, bool bToLeft );
699     EditPaM             CursorVisualStartEnd( EditView const * pEditView, const EditPaM& rPaM, bool bStart );
700 
701 
702     void                InitScriptTypes( sal_Int32 nPara );
703     sal_uInt16          GetI18NScriptType( const EditPaM& rPaM, sal_Int32* pEndPos = nullptr ) const;
704     SvtScriptType       GetItemScriptType( const EditSelection& rSel ) const;
705     bool                IsScriptChange( const EditPaM& rPaM ) const;
706     bool                HasScriptType( sal_Int32 nPara, sal_uInt16 nType ) const;
707 
708     bool                ImplCalcAsianCompression( ContentNode* pNode, TextPortion* pTextPortion, sal_Int32 nStartPos,
709                                                 sal_Int32* pDXArray, sal_uInt16 n100thPercentFromMax, bool bManipulateDXArray );
710     void                ImplExpandCompressedPortions( EditLine* pLine, ParaPortion* pParaPortion, tools::Long nRemainingWidth );
711 
712     void                ImplInitLayoutMode(OutputDevice& rOutDev, sal_Int32 nPara, sal_Int32 nIndex);
713     LanguageType        ImplCalcDigitLang(LanguageType eCurLang) const;
714     void                ImplInitDigitMode(OutputDevice& rOutDev, LanguageType eLang);
715     static OUString     convertDigits(std::u16string_view rString, sal_Int32 nStt, sal_Int32 nLen, LanguageType eDigitLang);
716 
717     EditPaM             ReadText( SvStream& rInput, EditSelection aSel );
718     EditPaM             ReadRTF( SvStream& rInput, EditSelection aSel );
719     EditPaM             ReadXML( SvStream& rInput, EditSelection aSel );
720     EditPaM             ReadHTML( SvStream& rInput, const OUString& rBaseURL, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs );
721     ErrCode             WriteText( SvStream& rOutput, EditSelection aSel );
722     ErrCode             WriteRTF( SvStream& rOutput, EditSelection aSel );
723     void                WriteXML(SvStream& rOutput, const EditSelection& rSel);
724 
725     void                WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, sal_Int32 nPara, sal_Int32 nPos,
726                             std::vector<std::unique_ptr<SvxFontItem>>& rFontTable, SvxColorList& rColorList );
727     bool                WriteItemListAsRTF( ItemList& rLst, SvStream& rOutput, sal_Int32 nPara, sal_Int32 nPos,
728                             std::vector<std::unique_ptr<SvxFontItem>>& rFontTable, SvxColorList& rColorList );
729     sal_Int32           LogicToTwips( sal_Int32 n );
730 
731     inline short        GetXValue( short nXValue ) const;
732     inline tools::Long         GetXValue( tools::Long nXValue ) const;
733 
734     inline short        GetYValue( short nYValue ) const;
735     inline sal_uInt16   GetYValue( sal_uInt16 nYValue ) const;
736 
737     ContentNode*        GetPrevVisNode( ContentNode const * pCurNode );
738     ContentNode*        GetNextVisNode( ContentNode const * pCurNode );
739 
740     const ParaPortion*  GetPrevVisPortion( const ParaPortion* pCurPortion ) const;
741     const ParaPortion*  GetNextVisPortion( const ParaPortion* pCurPortion ) const;
742 
743     void                SetBackgroundColor( const Color& rColor ) { maBackgroundColor = rColor; }
744     const Color&        GetBackgroundColor() const { return maBackgroundColor; }
745 
746     tools::Long                CalcVertLineSpacing(Point& rStartPos) const;
747 
748     Color               GetAutoColor() const;
749     void                EnableAutoColor( bool b ) { bUseAutoColor = b; }
750     bool                IsAutoColorEnabled() const { return bUseAutoColor; }
751     void                ForceAutoColor( bool b ) { bForceAutoColor = b; }
752     bool                IsForceAutoColor() const { return bForceAutoColor; }
753 
754     inline VirtualDevice*   GetVirtualDevice( const MapMode& rMapMode, DrawModeFlags nDrawMode );
755     void             EraseVirtualDevice() { pVirtDev.disposeAndClear(); }
756 
757     DECL_LINK( StatusTimerHdl, Timer *, void);
758     DECL_LINK( IdleFormatHdl, Timer *, void);
759     DECL_LINK( OnlineSpellHdl, Timer *, void);
760     DECL_LINK( DocModified, LinkParamNone*, void );
761 
762     void                CheckIdleFormatter();
763 
764     inline const ParaPortion& FindParaPortion( const ContentNode* pNode ) const;
765     inline ParaPortion& FindParaPortion( ContentNode const * pNode );
766 
767     css::uno::Reference< css::datatransfer::XTransferable > CreateTransferable( const EditSelection& rSelection );
768 
769     void                SetValidPaperSize( const Size& rSz );
770 
771     css::uno::Reference < css::i18n::XBreakIterator > const & ImplGetBreakIterator() const;
772     css::uno::Reference < css::i18n::XExtendedInputSequenceChecker > const & ImplGetInputSequenceChecker() const;
773 
774     void ImplUpdateOverflowingParaNum(tools::Long);
775     void ImplUpdateOverflowingLineNum(tools::Long, sal_uInt32, tools::Long);
776 
777     void CreateSpellInfo( bool bMultipleDocs );
778     /// Obtains a view shell ID from the active EditView.
779     ViewShellId CreateViewShellId();
780 
781     ImpEditEngine(EditEngine* pEditEngine, SfxItemPool* pPool);
782     void InitDoc(bool bKeepParaAttribs);
783     EditDoc&                GetEditDoc()            { return aEditDoc; }
784     const EditDoc&          GetEditDoc() const      { return aEditDoc; }
785 
786     const ParaPortionList&  GetParaPortions() const { return aParaPortionList; }
787     ParaPortionList&        GetParaPortions()       { return aParaPortionList; }
788 
789     tools::Long Calc1ColumnTextHeight(tools::Long* pHeightNTP);
790 
791     void IdleFormatAndLayout(EditView* pCurView) { aIdleFormatter.DoIdleFormat(pCurView); }
792 
793 protected:
794     virtual void            Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
795 
796 public:
797                             virtual ~ImpEditEngine() override;
798                             ImpEditEngine(const ImpEditEngine&) = delete;
799     ImpEditEngine&          operator=(const ImpEditEngine&) = delete;
800 
801     inline EditUndoManager& GetUndoManager();
802     inline SfxUndoManager* SetUndoManager(SfxUndoManager* pNew);
803 
804     // @return the previous bUpdateLayout state
805     bool                    SetUpdateLayout( bool bUpdate, EditView* pCurView = nullptr, bool bForceUpdate = false );
806     bool                    IsUpdateLayout() const   { return bUpdateLayout; }
807 
808     ViewsType& GetEditViews() { return aEditViews; }
809     const ViewsType& GetEditViews() const { return aEditViews; }
810 
811     const Size&             GetPaperSize() const                    { return aPaperSize; }
812     void                    SetPaperSize( const Size& rSz )         { aPaperSize = rSz; }
813 
814     void                    SetVertical( bool bVertical);
815     bool                    IsEffectivelyVertical() const                      { return GetEditDoc().IsEffectivelyVertical(); }
816     bool                    IsTopToBottom() const                   { return GetEditDoc().IsTopToBottom(); }
817     bool                    GetVertical() const               { return GetEditDoc().GetVertical(); }
818     void                    SetRotation( TextRotation nRotation);
819     TextRotation            GetRotation() const                     { return GetEditDoc().GetRotation(); }
820 
821     void SetTextColumns(sal_Int16 nColumns, sal_Int32 nSpacing);
822 
823     bool IsPageOverflow( ) const;
824 
825     void                    SetFixedCellHeight( bool bUseFixedCellHeight );
826     bool                    IsFixedCellHeight() const { return GetEditDoc().IsFixedCellHeight(); }
827 
828     void                        SetDefaultHorizontalTextDirection( EEHorizontalTextDirection eHTextDir ) { eDefaultHorizontalTextDirection = eHTextDir; }
829     EEHorizontalTextDirection   GetDefaultHorizontalTextDirection() const { return eDefaultHorizontalTextDirection; }
830 
831 
832     void                    InitWritingDirections( sal_Int32 nPara );
833     bool                    IsRightToLeft( sal_Int32 nPara ) const;
834     sal_uInt8               GetRightToLeft( sal_Int32 nPara, sal_Int32 nChar, sal_Int32* pStart = nullptr, sal_Int32* pEnd = nullptr );
835     bool                    HasDifferentRTLLevels( const ContentNode* pNode );
836 
837     void                    SetTextRanger( std::unique_ptr<TextRanger> pRanger );
838     TextRanger*             GetTextRanger() const { return pTextRanger.get(); }
839 
840     const Size&             GetMinAutoPaperSize() const             { return aMinAutoPaperSize; }
841     void                    SetMinAutoPaperSize( const Size& rSz )  { aMinAutoPaperSize = rSz; }
842 
843     const Size&             GetMaxAutoPaperSize() const             { return aMaxAutoPaperSize; }
844     void                    SetMaxAutoPaperSize( const Size& rSz )  { aMaxAutoPaperSize = rSz; }
845 
846     void SetMinColumnWrapHeight(tools::Long nVal) { mnMinColumnWrapHeight = nVal; }
847 
848     void                    FormatDoc();
849     void                    FormatFullDoc();
850     void                    UpdateViews( EditView* pCurView = nullptr );
851     void                    Paint( ImpEditView* pView, const tools::Rectangle& rRect, OutputDevice* pTargetDevice );
852     void                    Paint(OutputDevice& rOutDev, tools::Rectangle aClipRect, Point aStartPos, bool bStripOnly = false, Degree10 nOrientation = 0_deg10);
853 
854     bool                MouseButtonUp( const MouseEvent& rMouseEvent, EditView* pView );
855     bool                MouseButtonDown( const MouseEvent& rMouseEvent, EditView* pView );
856     void                ReleaseMouse();
857     bool                MouseMove( const MouseEvent& rMouseEvent, EditView* pView );
858     bool                    Command(const CommandEvent& rCEvt, EditView* pView);
859 
860     EditSelectionEngine&    GetSelEngine() { return aSelEngine; }
861     OUString                GetSelected( const EditSelection& rSel ) const;
862 
863     const SfxItemSet& GetEmptyItemSet() const;
864 
865     void                    UpdateSelections();
866 
867     void                EnableUndo( bool bEnable );
868     bool                IsUndoEnabled() const   { return bUndoEnabled; }
869     void                SetUndoMode( bool b )   { bIsInUndo = b; }
870     bool                IsInUndo() const        { return bIsInUndo; }
871 
872     void                SetCallParaInsertedOrDeleted( bool b ) { bCallParaInsertedOrDeleted = b; }
873     bool                IsCallParaInsertedOrDeleted() const { return bCallParaInsertedOrDeleted; }
874 
875     bool                IsFormatted() const { return bFormatted; }
876     bool                IsFormatting() const { return bIsFormatting; }
877 
878     void            SetText(const OUString& rText);
879     EditPaM         DeleteSelected(const EditSelection& rEditSelection);
880     EditPaM         InsertTextUserInput( const EditSelection& rCurEditSelection, sal_Unicode c, bool bOverwrite );
881     EditPaM         InsertText(const EditSelection& aCurEditSelection, const OUString& rStr);
882     EditPaM         AutoCorrect( const EditSelection& rCurEditSelection, sal_Unicode c, bool bOverwrite, vcl::Window const * pFrameWin = nullptr );
883     EditPaM         DeleteLeftOrRight( const EditSelection& rEditSelection, sal_uInt8 nMode, DeleteMode nDelMode );
884     EditPaM         InsertParaBreak(const EditSelection& rEditSelection);
885     EditPaM         InsertLineBreak(const EditSelection& aEditSelection);
886     EditPaM         InsertTab(const EditSelection& rEditSelection);
887     EditPaM         InsertField(const EditSelection& rCurSel, const SvxFieldItem& rFld);
888     bool            UpdateFields();
889 
890     EditPaM         Read(SvStream& rInput, const OUString& rBaseURL, EETextFormat eFormat, const EditSelection& rSel, SvKeyValueIterator* pHTTPHeaderAttrs = nullptr);
891     void            Write(SvStream& rOutput, EETextFormat eFormat, const EditSelection& rSel);
892 
893     std::unique_ptr<EditTextObject> CreateTextObject();
894     std::unique_ptr<EditTextObject> CreateTextObject(const EditSelection& rSel);
895     void            SetText( const EditTextObject& rTextObject );
896     EditSelection   InsertText( const EditTextObject& rTextObject, EditSelection aSel );
897 
898     EditSelection const & MoveCursor( const KeyEvent& rKeyEvent, EditView* pEditView );
899 
900     EditSelection   MoveParagraphs( Range aParagraphs, sal_Int32 nNewPos, EditView* pCurView );
901 
902     tools::Long     CalcTextHeight( tools::Long* pHeightNTP );
903     sal_uInt32      GetTextHeight() const;
904     sal_uInt32      GetTextHeightNTP() const;
905     sal_uInt32      CalcTextWidth( bool bIgnoreExtraSpace);
906     sal_uInt32      CalcParaWidth( sal_Int32 nParagraph, bool bIgnoreExtraSpace );
907     sal_uInt32      CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace);
908     sal_Int32       GetLineCount( sal_Int32 nParagraph ) const;
909     sal_Int32       GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine ) const;
910     void            GetLineBoundaries( /*out*/sal_Int32& rStart, /*out*/sal_Int32& rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const;
911     sal_Int32       GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) const;
912     sal_uInt16      GetLineHeight( sal_Int32 nParagraph, sal_Int32 nLine );
913     sal_uInt32      GetParaHeight( sal_Int32 nParagraph );
914 
915     SfxItemSet      GetAttribs( sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, GetAttribsFlags nFlags = GetAttribsFlags::ALL ) const;
916     SfxItemSet      GetAttribs( EditSelection aSel, EditEngineAttribs nOnlyHardAttrib = EditEngineAttribs::All  );
917     void            SetAttribs( EditSelection aSel, const SfxItemSet& rSet, SetAttribsMode nSpecial = SetAttribsMode::NONE, bool bSetSelection = true );
918     void            RemoveCharAttribs( EditSelection aSel, EERemoveParaAttribsMode eMode, sal_uInt16 nWhich );
919     void            RemoveCharAttribs( sal_Int32 nPara, sal_uInt16 nWhich = 0, bool bRemoveFeatures = false );
920     void            SetFlatMode( bool bFlat );
921 
922     void                SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet );
923     const SfxItemSet&   GetParaAttribs( sal_Int32 nPara ) const;
924 
925     bool            HasParaAttrib( sal_Int32 nPara, sal_uInt16 nWhich ) const;
926     const SfxPoolItem&  GetParaAttrib( sal_Int32 nPara, sal_uInt16 nWhich ) const;
927     template<class T>
928     const T&            GetParaAttrib( sal_Int32 nPara, TypedWhichId<T> nWhich ) const
929     {
930         return static_cast<const T&>(GetParaAttrib(nPara, sal_uInt16(nWhich)));
931     }
932 
933     tools::Rectangle       PaMtoEditCursor( EditPaM aPaM, GetCursorFlags nFlags = GetCursorFlags::NONE );
934     tools::Rectangle GetEditCursor(const ParaPortion* pPortion, const EditLine* pLine,
935                                    sal_Int32 nIndex, GetCursorFlags nFlags);
936 
937     bool            IsModified() const      { return aEditDoc.IsModified(); }
938     void            SetModifyFlag( bool b ) { aEditDoc.SetModified( b ); }
939     void            SetModifyHdl( const Link<LinkParamNone*,void>& rLink ) { aModifyHdl = rLink; }
940     const Link<LinkParamNone*,void>& GetModifyHdl() const { return aModifyHdl; }
941 
942     bool            IsInSelectionMode() const { return bInSelection; }
943 
944 //  For Undo/Redo
945     void            Undo( EditView* pView );
946     void            Redo( EditView* pView );
947 
948 //  OV-Special
949     void            InvalidateFromParagraph( sal_Int32 nFirstInvPara );
950     EditPaM         InsertParagraph( sal_Int32 nPara );
951     std::optional<EditSelection> SelectParagraph( sal_Int32 nPara );
952 
953     void            SetStatusEventHdl( const Link<EditStatus&, void>& rLink ) { aStatusHdlLink = rLink; }
954     const Link<EditStatus&,void>& GetStatusEventHdl() const               { return aStatusHdlLink; }
955 
956     void            SetNotifyHdl( const Link<EENotify&,void>& rLink )     { aNotifyHdl = rLink; }
957     const Link<EENotify&,void>&   GetNotifyHdl() const            { return aNotifyHdl; }
958 
959     void            FormatAndLayout( EditView* pCurView = nullptr, bool bCalledFromUndo = false );
960 
961     const svtools::ColorConfig& GetColorConfig() const { return maColorConfig; }
962     bool            IsVisualCursorTravelingEnabled();
963     bool            DoVisualCursorTraveling();
964 
965     EditSelection         ConvertSelection( sal_Int32 nStartPara, sal_Int32 nStartPos, sal_Int32 nEndPara, sal_Int32 nEndPos );
966     inline EPaM           CreateEPaM( const EditPaM& rPaM ) const;
967     inline EditPaM        CreateEditPaM( const EPaM& rEPaM );
968     inline ESelection     CreateESel( const EditSelection& rSel ) const;
969     inline EditSelection  CreateSel( const ESelection& rSel );
970 
971     void                SetStyleSheetPool( SfxStyleSheetPool* pSPool );
972     SfxStyleSheetPool*  GetStyleSheetPool() const { return pStylePool; }
973 
974     void                SetStyleSheet( EditSelection aSel, SfxStyleSheet* pStyle );
975     void                SetStyleSheet( sal_Int32 nPara, SfxStyleSheet* pStyle );
976     const SfxStyleSheet* GetStyleSheet( sal_Int32 nPara ) const;
977     SfxStyleSheet*      GetStyleSheet( sal_Int32 nPara );
978 
979     void                UpdateParagraphsWithStyleSheet( SfxStyleSheet* pStyle );
980     void                RemoveStyleFromParagraphs( SfxStyleSheet const * pStyle );
981 
982     OutputDevice*       GetRefDevice() const { return pRefDev.get(); }
983     void                SetRefDevice( OutputDevice* pRefDef );
984 
985     const MapMode&      GetRefMapMode() const { return pRefDev->GetMapMode(); }
986     void                SetRefMapMode( const MapMode& rMapMode );
987 
988     InternalEditStatus& GetStatus() { return aStatus; }
989     void                CallStatusHdl();
990     void                DelayedCallStatusHdl()  { aStatusTimer.Start(); }
991 
992     void                UndoActionStart( sal_uInt16 nId );
993     void                UndoActionStart( sal_uInt16 nId, const ESelection& rSel );
994     void                UndoActionEnd();
995 
996     EditView*           GetActiveView() const   { return pActiveView; }
997     void                SetActiveView( EditView* pView );
998 
999     css::uno::Reference< css::linguistic2::XSpellChecker1 > const &
1000                         GetSpeller();
1001     void                SetSpeller( css::uno::Reference< css::linguistic2::XSpellChecker1 > const &xSpl )
1002                             { xSpeller = xSpl; }
1003     const css::uno::Reference< css::linguistic2::XHyphenator >&
1004                         GetHyphenator() const { return xHyphenator; }
1005     void                SetHyphenator( css::uno::Reference< css::linguistic2::XHyphenator > const &xHyph )
1006                             { xHyphenator = xHyph; }
1007 
1008     void GetAllMisspellRanges( std::vector<editeng::MisspellRanges>& rRanges ) const;
1009     void SetAllMisspellRanges( const std::vector<editeng::MisspellRanges>& rRanges );
1010 
1011     SpellInfo*          GetSpellInfo() const { return pSpellInfo.get(); }
1012 
1013     void                SetDefaultLanguage( LanguageType eLang ) { eDefLanguage = eLang; }
1014     LanguageType        GetDefaultLanguage() const { return eDefLanguage; }
1015 
1016     LanguageType        GetLanguage( const EditPaM& rPaM, sal_Int32* pEndPos = nullptr ) const;
1017     css::lang::Locale   GetLocale( const EditPaM& rPaM ) const;
1018 
1019     void DoOnlineSpelling( ContentNode* pThisNodeOnly = nullptr, bool bSpellAtCursorPos = false, bool bInterruptible = true );
1020     EESpellState        Spell(EditView* pEditView, weld::Widget* pDialogParent, bool bMultipleDoc);
1021     EESpellState        HasSpellErrors();
1022     void                ClearSpellErrors();
1023     EESpellState        StartThesaurus(EditView* pEditView, weld::Widget* pDialogParent);
1024     css::uno::Reference< css::linguistic2::XSpellAlternatives >
1025                         ImpSpell( EditView* pEditView );
1026 
1027     // text conversion functions
1028     void                Convert(EditView* pEditView, weld::Widget* pDialogParent, LanguageType nSrcLang, LanguageType nDestLang, const vcl::Font *pDestFont, sal_Int32 nOptions, bool bIsInteractive, bool bMultipleDoc);
1029     void                ImpConvert( OUString &rConvTxt, LanguageType &rConvTxtLang, EditView* pEditView, LanguageType nSrcLang, const ESelection &rConvRange,
1030                                     bool bAllowImplicitChangesForNotConvertibleText, LanguageType nTargetLang, const vcl::Font *pTargetFont );
1031     ConvInfo *          GetConvInfo() const { return pConvInfo.get(); }
1032     bool                HasConvertibleTextPortion( LanguageType nLang );
1033     void                SetLanguageAndFont( const ESelection &rESel,
1034                                 LanguageType nLang, sal_uInt16 nLangWhichId,
1035                                 const vcl::Font *pFont,  sal_uInt16 nFontWhichId );
1036 
1037     // returns true if input sequence checking should be applied
1038     bool                IsInputSequenceCheckingRequired( sal_Unicode nChar, const EditSelection& rCurSel ) const;
1039 
1040     //find the next error within the given selection - forward only!
1041     css::uno::Reference< css::linguistic2::XSpellAlternatives >
1042                         ImpFindNextError(EditSelection& rSelection);
1043     //spell and return a sentence
1044     bool                SpellSentence(EditView const & rView, svx::SpellPortions& rToFill );
1045     //put spelling back to start of current sentence - needed after switch of grammar support
1046     void                PutSpellingToSentenceStart( EditView const & rEditView );
1047     //applies a changed sentence
1048     void                ApplyChangedSentence(EditView const & rEditView, const svx::SpellPortions& rNewPortions, bool bRecheck );
1049     //adds one or more portions of text to the SpellPortions depending on language changes
1050     void                AddPortionIterated(
1051                           EditView const & rEditView,
1052                           const EditSelection &rSel,
1053                           const css::uno::Reference< css::linguistic2::XSpellAlternatives >& xAlt,
1054                           svx::SpellPortions& rToFill);
1055     //adds one portion to the SpellPortions
1056     void                AddPortion(
1057                             const EditSelection &rSel,
1058                             const css::uno::Reference< css::linguistic2::XSpellAlternatives >& xAlt,
1059                             svx::SpellPortions& rToFill,
1060                             bool bIsField );
1061 
1062     bool                    Search( const SvxSearchItem& rSearchItem, EditView* pView );
1063     bool                    ImpSearch( const SvxSearchItem& rSearchItem, const EditSelection& rSearchSelection, const EditPaM& rStartPos, EditSelection& rFoundSel );
1064     sal_Int32               StartSearchAndReplace( EditView* pEditView, const SvxSearchItem& rSearchItem );
1065     bool                    HasText( const SvxSearchItem& rSearchItem );
1066 
1067     void                    SetEditTextObjectPool( SfxItemPool* pP )    { pTextObjectPool = pP; }
1068     SfxItemPool*            GetEditTextObjectPool() const               { return pTextObjectPool; }
1069 
1070     const SvxNumberFormat * GetNumberFormat( const ContentNode* pNode ) const;
1071     sal_Int32               GetSpaceBeforeAndMinLabelWidth( const ContentNode *pNode, sal_Int32 *pnSpaceBefore = nullptr, sal_Int32 *pnMinLabelWidth = nullptr ) const;
1072 
1073     const SvxLRSpaceItem&   GetLRSpaceItem( ContentNode* pNode );
1074     SvxAdjust               GetJustification( sal_Int32 nPara ) const;
1075     SvxCellJustifyMethod    GetJustifyMethod( sal_Int32 nPara ) const;
1076     SvxCellVerJustify       GetVerJustification( sal_Int32 nPara ) const;
1077 
1078     void                SetCharStretching( sal_uInt16 nX, sal_uInt16 nY );
1079     inline void         GetCharStretching( sal_uInt16& rX, sal_uInt16& rY ) const;
1080 
1081     sal_Int32           GetBigTextObjectStart() const                               { return nBigTextObjectStart; }
1082 
1083     EditEngine*  GetEditEnginePtr() const    { return pEditEngine; }
1084 
1085     void                StartOnlineSpellTimer()     { aOnlineSpellTimer.Start(); }
1086     void                StopOnlineSpellTimer()      { aOnlineSpellTimer.Stop(); }
1087 
1088     const OUString&     GetAutoCompleteText() const { return aAutoCompleteText; }
1089     void                SetAutoCompleteText(const OUString& rStr, bool bUpdateTipWindow);
1090 
1091     EditSelection       TransliterateText( const EditSelection& rSelection, TransliterationFlags nTransliterationMode );
1092     short               ReplaceTextOnly( ContentNode* pNode, sal_Int32 nCurrentStart, std::u16string_view rText, const css::uno::Sequence< sal_Int32 >& rOffsets );
1093 
1094     void                SetAsianCompressionMode( CharCompressType n );
1095     CharCompressType    GetAsianCompressionMode() const { return nAsianCompressionMode; }
1096 
1097     void                SetKernAsianPunctuation( bool b );
1098     bool                IsKernAsianPunctuation() const { return bKernAsianPunctuation; }
1099 
1100     sal_Int32 GetOverflowingParaNum() const { return mnOverflowingPara; }
1101     sal_Int32 GetOverflowingLineNum() const { return mnOverflowingLine; }
1102     void ClearOverflowingParaNum() { mnOverflowingPara = -1; }
1103 
1104 
1105     void                SetAddExtLeading( bool b );
1106     bool                IsAddExtLeading() const { return bAddExtLeading; }
1107 
1108     static std::shared_ptr<SvxForbiddenCharactersTable> const & GetForbiddenCharsTable();
1109     static void         SetForbiddenCharsTable( const std::shared_ptr<SvxForbiddenCharactersTable>& xForbiddenChars );
1110 
1111     /** sets a link that is called at the beginning of a drag operation at an edit view */
1112     void                SetBeginDropHdl( const Link<EditView*,void>& rLink ) { maBeginDropHdl = rLink; }
1113     const Link<EditView*,void>&  GetBeginDropHdl() const { return maBeginDropHdl; }
1114 
1115     /** sets a link that is called at the end of a drag operation at an edit view */
1116     void            SetEndDropHdl( const Link<EditView*,void>& rLink ) { maEndDropHdl = rLink; }
1117     const Link<EditView*,void>&  GetEndDropHdl() const { return maEndDropHdl; }
1118 
1119     /// specifies if auto-correction should capitalize the first word or not (default is on)
1120     void            SetFirstWordCapitalization( bool bCapitalize )  { bFirstWordCapitalization = bCapitalize; }
1121     bool            IsFirstWordCapitalization() const   { return bFirstWordCapitalization; }
1122 
1123     /** specifies if auto-correction should replace a leading single quotation
1124         mark (apostrophe) or not (default is on) */
1125     void            SetReplaceLeadingSingleQuotationMark( bool bReplace ) { mbReplaceLeadingSingleQuotationMark = bReplace; }
1126     bool            IsReplaceLeadingSingleQuotationMark() const { return mbReplaceLeadingSingleQuotationMark; }
1127 
1128     /** Whether last AutoCorrect inserted a NO-BREAK SPACE that may need to be removed again. */
1129     bool            IsNbspRunNext() const { return mbNbspRunNext; }
1130 
1131     void Dispose();
1132     void SetLOKSpecialPaperSize(const Size& rSize) { aLOKSpecialPaperSize = rSize; }
1133     const Size& GetLOKSpecialPaperSize() const { return aLOKSpecialPaperSize; }
1134 
1135     enum class CallbackResult
1136     {
1137         Continue,
1138         SkipThisPortion, // Do not call callback until next portion
1139         Stop, // Stop iteration
1140     };
1141     struct LineAreaInfo
1142     {
1143         ParaPortion& rPortion; // Current ParaPortion
1144         EditLine* pLine; // Current line, or nullptr for paragraph start
1145         tools::Long nHeightNeededToNotWrap;
1146         tools::Rectangle aArea; // The area for the line (or for rPortion's first line offset)
1147                                 // Bottom coordinate *does not* belong to the area
1148         sal_Int32 nPortion;
1149         sal_Int32 nLine;
1150         sal_Int16 nColumn; // Column number; when overflowing, equal to total number of columns
1151     };
1152     using IterateLinesAreasFunc = std::function<CallbackResult(const LineAreaInfo&)>;
1153     enum IterFlag // bitmask
1154     {
1155         none = 0,
1156         inclILS = 1, // rArea includes interline space
1157     };
1158 
1159     void IterateLineAreas(const IterateLinesAreasFunc& f, IterFlag eOptions);
1160 
1161     tools::Long GetColumnWidth(const Size& rPaperSize) const;
1162     Point MoveToNextLine(Point& rMovePos, tools::Long nLineHeight, sal_Int16& nColumn,
1163                          Point aOrigin, tools::Long* pnHeightNeededToNotWrap = nullptr) const;
1164 
1165     tools::Long getWidthDirectionAware(const Size& sz) const;
1166     tools::Long getHeightDirectionAware(const Size& sz) const;
1167     void adjustXDirectionAware(Point& pt, tools::Long x) const;
1168     void adjustYDirectionAware(Point& pt, tools::Long y) const;
1169     void setXDirectionAwareFrom(Point& ptDest, const Point& ptSrc) const;
1170     void setYDirectionAwareFrom(Point& ptDest, const Point& ptSrc) const;
1171     tools::Long getYOverflowDirectionAware(const Point& pt, const tools::Rectangle& rectMax) const;
1172     bool isXOverflowDirectionAware(const Point& pt, const tools::Rectangle& rectMax) const;
1173     // Offset of the rectangle's direction-aware corners in document coordinates
1174     tools::Long getBottomDocOffset(const tools::Rectangle& rect) const;
1175     Size getTopLeftDocOffset(const tools::Rectangle& rect) const;
1176 };
1177 
1178 inline EPaM ImpEditEngine::CreateEPaM( const EditPaM& rPaM ) const
1179 {
1180     const ContentNode* pNode = rPaM.GetNode();
1181     return EPaM( aEditDoc.GetPos( pNode ), rPaM.GetIndex() );
1182 }
1183 
1184 inline EditPaM ImpEditEngine::CreateEditPaM( const EPaM& rEPaM )
1185 {
1186     DBG_ASSERT( rEPaM.nPara < aEditDoc.Count(), "CreateEditPaM: invalid paragraph" );
1187     DBG_ASSERT( aEditDoc[ rEPaM.nPara ]->Len() >= rEPaM.nIndex, "CreateEditPaM: invalid Index" );
1188     return EditPaM( aEditDoc[ rEPaM.nPara], rEPaM.nIndex );
1189 }
1190 
1191 inline ESelection ImpEditEngine::CreateESel( const EditSelection& rSel ) const
1192 {
1193     const ContentNode* pStartNode = rSel.Min().GetNode();
1194     const ContentNode* pEndNode = rSel.Max().GetNode();
1195     ESelection aESel;
1196     aESel.nStartPara = aEditDoc.GetPos( pStartNode );
1197     aESel.nStartPos = rSel.Min().GetIndex();
1198     aESel.nEndPara = aEditDoc.GetPos( pEndNode );
1199     aESel.nEndPos = rSel.Max().GetIndex();
1200     return aESel;
1201 }
1202 
1203 inline EditSelection ImpEditEngine::CreateSel( const ESelection& rSel )
1204 {
1205     DBG_ASSERT( rSel.nStartPara < aEditDoc.Count(), "CreateSel: invalid start paragraph" );
1206     DBG_ASSERT( rSel.nEndPara < aEditDoc.Count(), "CreateSel: invalid end paragraph" );
1207     EditSelection aSel;
1208     aSel.Min().SetNode( aEditDoc[ rSel.nStartPara ] );
1209     aSel.Min().SetIndex( rSel.nStartPos );
1210     aSel.Max().SetNode( aEditDoc[ rSel.nEndPara ] );
1211     aSel.Max().SetIndex( rSel.nEndPos );
1212     DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "CreateSel: incorrect selection!" );
1213     return aSel;
1214 }
1215 
1216 inline VirtualDevice* ImpEditEngine::GetVirtualDevice( const MapMode& rMapMode, DrawModeFlags nDrawMode )
1217 {
1218     if ( !pVirtDev )
1219         pVirtDev = VclPtr<VirtualDevice>::Create();
1220 
1221     if ( ( pVirtDev->GetMapMode().GetMapUnit() != rMapMode.GetMapUnit() ) ||
1222          ( pVirtDev->GetMapMode().GetScaleX() != rMapMode.GetScaleX() ) ||
1223          ( pVirtDev->GetMapMode().GetScaleY() != rMapMode.GetScaleY() ) )
1224     {
1225         MapMode aMapMode( rMapMode );
1226         aMapMode.SetOrigin( Point( 0, 0 ) );
1227         pVirtDev->SetMapMode( aMapMode );
1228     }
1229 
1230     pVirtDev->SetDrawMode( nDrawMode );
1231 
1232     return pVirtDev;
1233 }
1234 
1235 inline EditUndoManager& ImpEditEngine::GetUndoManager()
1236 {
1237     if ( !pUndoManager )
1238     {
1239         pUndoManager = new EditUndoManager();
1240         pUndoManager->SetEditEngine(pEditEngine);
1241     }
1242     return *pUndoManager;
1243 }
1244 
1245 inline SfxUndoManager* ImpEditEngine::SetUndoManager(SfxUndoManager* pNew)
1246 {
1247     SfxUndoManager* pRetval = pUndoManager;
1248 
1249     if(pUndoManager)
1250     {
1251         pUndoManager->SetEditEngine(nullptr);
1252     }
1253 
1254     pUndoManager = dynamic_cast< EditUndoManager* >(pNew);
1255 
1256     if(pUndoManager)
1257     {
1258         pUndoManager->SetEditEngine(pEditEngine);
1259     }
1260 
1261     return pRetval;
1262 }
1263 
1264 inline const ParaPortion& ImpEditEngine::FindParaPortion( const ContentNode* pNode ) const
1265 {
1266     sal_Int32 nPos = aEditDoc.GetPos( pNode );
1267     DBG_ASSERT( nPos < GetParaPortions().Count(), "Portionloser Node?" );
1268     return GetParaPortions()[ nPos ];
1269 }
1270 
1271 inline ParaPortion& ImpEditEngine::FindParaPortion( ContentNode const * pNode )
1272 {
1273     sal_Int32 nPos = aEditDoc.GetPos( pNode );
1274     DBG_ASSERT( nPos < GetParaPortions().Count(), "Portionloser Node?" );
1275     return GetParaPortions()[ nPos ];
1276 }
1277 
1278 inline void ImpEditEngine::GetCharStretching( sal_uInt16& rX, sal_uInt16& rY ) const
1279 {
1280     rX = nStretchX;
1281     rY = nStretchY;
1282 }
1283 
1284 inline short ImpEditEngine::GetXValue( short nXValue ) const
1285 {
1286     if ( !aStatus.DoStretch() || ( nStretchX == 100 ) )
1287         return nXValue;
1288 
1289     return static_cast<short>(static_cast<tools::Long>(nXValue)*nStretchX/100);
1290 }
1291 
1292 
1293 inline tools::Long ImpEditEngine::GetXValue( tools::Long nXValue ) const
1294 {
1295     if ( !aStatus.DoStretch() || ( nStretchX == 100 ) )
1296         return nXValue;
1297 
1298     return nXValue*nStretchX/100;
1299 }
1300 
1301 inline short ImpEditEngine::GetYValue( short nYValue ) const
1302 {
1303     if ( !aStatus.DoStretch() || ( nStretchY == 100 ) )
1304         return nYValue;
1305 
1306     return static_cast<short>(static_cast<tools::Long>(nYValue)*nStretchY/100);
1307 }
1308 
1309 inline sal_uInt16 ImpEditEngine::GetYValue( sal_uInt16 nYValue ) const
1310 {
1311     if ( !aStatus.DoStretch() || ( nStretchY == 100 ) )
1312         return nYValue;
1313 
1314     return static_cast<sal_uInt16>(static_cast<tools::Long>(nYValue)*nStretchY/100);
1315 }
1316 
1317 inline PointerStyle ImpEditView::GetPointer()
1318 {
1319     if ( !mxPointer )
1320     {
1321         mxPointer = IsVertical() ? PointerStyle::TextVertical : PointerStyle::Text;
1322         return *mxPointer;
1323     }
1324 
1325     if(PointerStyle::Text == *mxPointer && IsVertical())
1326     {
1327         mxPointer = PointerStyle::TextVertical;
1328     }
1329     else if(PointerStyle::TextVertical == *mxPointer && !IsVertical())
1330     {
1331         mxPointer = PointerStyle::Text;
1332     }
1333 
1334     return *mxPointer;
1335 }
1336 
1337 inline vcl::Cursor* ImpEditView::GetCursor()
1338 {
1339     if ( !pCursor )
1340         pCursor.reset( new vcl::Cursor );
1341     return pCursor.get();
1342 }
1343 
1344 void ConvertItem( std::unique_ptr<SfxPoolItem>& rPoolItem, MapUnit eSourceUnit, MapUnit eDestUnit );
1345 void ConvertAndPutItems( SfxItemSet& rDest, const SfxItemSet& rSource, const MapUnit* pSourceUnit = nullptr, const MapUnit* pDestUnit = nullptr );
1346 AsianCompressionFlags GetCharTypeForCompression( sal_Unicode cChar );
1347 Point Rotate( const Point& rPoint, Degree10 nOrientation, const Point& rOrigin );
1348 
1349 
1350 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1351