Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  impedit.hxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#pragma once

#include <eerdll2.hxx>
#include <editdoc.hxx>
#include "editsel.hxx"
#include "editundo.hxx"
#include "editstt2.hxx"
#include <editeng/editdata.hxx>
#include <editeng/SpellPortions.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editview.hxx>
#include <svtools/colorcfg.hxx>
#include <editeng/outliner.hxx>
#include <vcl/virdev.hxx>
#include <vcl/cursor.hxx>
#include <vcl/vclptr.hxx>
#include <tools/fract.hxx>
#include <vcl/idle.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/ptrstyle.hxx>

#include <vcl/dndhelp.hxx>
#include <svl/ondemand.hxx>
#include <svl/languageoptions.hxx>
#include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
#include <com/sun/star/linguistic2/XHyphenator.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
#include <com/sun/star/i18n/WordType.hpp>
#include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
#include <com/sun/star/uno/Sequence.hxx>

#include <i18nlangtag/lang.h>
#include <o3tl/deleter.hxx>
#include <o3tl/typed_flags_set.hxx>

#include <functional>
#include <optional>
#include <memory>
#include <tuple>
#include <string_view>
#include <vector>

class SvxSearchItem;
class SvxLRSpaceItem;
struct SvxFontUnitMetrics;
class TextRanger;
class SvKeyValueIterator;
class SvxForbiddenCharactersTable;
namespace vcl { class Window; }
class SvxNumberFormat;
namespace com::sun::star::datatransfer::clipboard {
    class XClipboard;
}

namespace editeng {
    struct MisspellRanges;
}

#define DEL_LEFT    1
#define DEL_RIGHT   2
#define TRAVEL_X_DONTKNOW           0xFFFFFFFF
#define CURSOR_BIDILEVEL_DONTKNOW   0xFFFF
#define MAXCHARSINPARA              0x3FFF-CHARPOSGROW  // Max 16K, because WYSIWYG array
#define LINE_SEP    '\x0A'

struct CursorFlags
{
    bool bTextOnly : 1 = false;
    bool bStartOfLine : 1 = false;
    bool bEndOfLine : 1 = false;
    bool bPreferPortionStart : 1 = false;
};

struct DragAndDropInfo
{
    tools::Rectangle aCurCursor;
    tools::Rectangle aCurSavedCursor;
    sal_uInt16 nSensibleRange = 0;
    sal_uInt16 nCursorWidth = 0;
    ESelection aBeginDragSel;
    EditPaM aDropDest;
    sal_Int32 nOutlinerDropDest = 0;
    ESelection aDropSel;
    VclPtr<VirtualDevice> pBackground = nullptr;
    const SvxFieldItem* pField = nullptr;
    bool bVisCursor : 1 = false;
    bool bDroppedInMe : 1 = false;
    bool bStarterOfDD : 1 = false;
    bool bHasValidData : 1 = false;
    bool bUndoAction : 1 = false;
    bool bOutlinerMode : 1 = false;
    bool bDragAccepted : 1 = false;

    ~DragAndDropInfo()
    {
        pBackground.disposeAndClear();
    }
};

struct ImplIMEInfos
{
    OUString aOldTextAfterStartPos;
    std::unique_ptr<ExtTextInputAttr[]> pAttribs;
    EditPaM aPos;
    sal_Int32 nLen = 0;
    bool bWasCursorOverwrite = false;

    ImplIMEInfos(const EditPaM& rPos, OUString _aOldTextAfterStartPos)
        : aOldTextAfterStartPos(std::move(_aOldTextAfterStartPos))
        , aPos(rPos)
    {}

    void CopyAttribs(const ExtTextInputAttr* pInputAttributes, sal_uInt16 nInputLength)
    {
        nLen = nInputLength;
        pAttribs.reset(new ExtTextInputAttr[nInputLength]);
        memcpy(pAttribs.get(), pInputAttributes, nInputLength * sizeof(ExtTextInputAttr));
    }

    void DestroyAttribs()
    {
        pAttribs.reset();
        nLen = 0;
    }
};

// #i18881# to be able to identify the positions of changed words
// the positions of each portion need to be saved
typedef std::vector<EditSelection>  SpellContentSelections;

struct SpellInfo
{
    EditPaM aCurSentenceStart;
    svx::SpellPortions aLastSpellPortions;
    SpellContentSelections aLastSpellContentSelections;
    EESpellState eState = EESpellState::Ok;
    EPaM aSpellStart;
    EPaM aSpellTo;
    bool bSpellToEnd : 1 = true;
    bool bMultipleDoc : 1 = false;
};

// used for text conversion
struct ConvInfo
{
    EPaM aConvStart;
    EPaM aConvTo;
    EPaM aConvContinue;    // position to start search for next text portion (word) with
    bool bConvToEnd : 1 = true;
    bool bMultipleDoc : 1 = false;
};

struct FormatterFontMetric
{
    sal_uInt16 nMaxAscent = 0;
    sal_uInt16 nMaxDescent = 0;

    sal_uInt16 GetHeight() const
    {
        return nMaxAscent + nMaxDescent;
    }
};

class IdleFormattter : public Idle
{
private:
    EditView* mpView = nullptr;
    int mnRestarts = 0;

public:
    IdleFormattter();
    virtual ~IdleFormattter() override;

    void DoIdleFormat(EditView* pView);
    void ForceTimeout();
    void ResetRestarts() { mnRestarts = 0; }
    EditView* GetView() { return mpView; }
};

class ImpEditView;

/// This is meant just for Calc, where all positions in logical units (twips for LOK) are computed by
/// doing independent pixel-alignment for each cell's size. LOKSpecialPositioning stores
/// both 'output-area' and 'visible-doc-position' in pure logical unit (twips for LOK).
/// This allows the cursor/selection messages to be in regular(print) twips unit like in Writer.
class LOKSpecialPositioning
{
public:
    LOKSpecialPositioning(const ImpEditView& rImpEditView, MapUnit eUnit, const tools::Rectangle& rOutputArea,
                          const Point& rVisDocStartPos);

    void ReInit(MapUnit eUnit, const tools::Rectangle& rOutputArea, const Point& rVisDocStartPos);

    void SetOutputArea(const tools::Rectangle& rOutputArea);
    const tools::Rectangle& GetOutputArea() const;
    void SetVisDocStartPos(const Point& rVisDocStartPos);

    bool IsVertical() const;
    bool IsTopToBottom() const;

    tools::Long GetVisDocLeft() const { return maVisDocStartPos.X(); }
    tools::Long GetVisDocTop() const  { return maVisDocStartPos.Y(); }
    // coverity[ tainted_data_return : FALSE ] version 2023.12.2
    tools::Long GetVisDocRight() const  { return maVisDocStartPos.X() + (!IsVertical() ? maOutArea.GetWidth() : maOutArea.GetHeight()); }
    // coverity[ tainted_data_return : FALSE ] version 2023.12.2
    tools::Long GetVisDocBottom() const { return maVisDocStartPos.Y() + (!IsVertical() ? maOutArea.GetHeight() : maOutArea.GetWidth()); }
    tools::Rectangle GetVisDocArea() const;

    Point            GetWindowPos(const Point& rDocPos, MapUnit eDocPosUnit) const;
    tools::Rectangle GetWindowPos(const tools::Rectangle& rDocRect, MapUnit eDocRectUnit) const;

    void SetFlags(LOKSpecialFlags eFlags) { meFlags = eFlags; }
    bool IsLayoutRTL() { return bool(meFlags & LOKSpecialFlags::LayoutRTL); }

    Point GetRefPoint() const;

private:
    Point convertUnit(const Point& rPos, MapUnit ePosUnit) const;
    tools::Rectangle convertUnit(const tools::Rectangle& rRect, MapUnit eRectUnit) const;

    const ImpEditView& mrImpEditView;
    tools::Rectangle maOutArea;
    Point maVisDocStartPos;
    MapUnit meUnit;
    LOKSpecialFlags meFlags;
};

class ImpEditView : public vcl::unohelper::DragAndDropClient
{
    friend class EditView;
    friend class EditEngine;
    friend class ImpEditEngine;
    using vcl::unohelper::DragAndDropClient::dragEnter;
    using vcl::unohelper::DragAndDropClient::dragExit;
    using vcl::unohelper::DragAndDropClient::dragOver;

private:
    EditView* mpEditView;
    std::unique_ptr<vcl::Cursor, o3tl::default_delete<vcl::Cursor>> mpCursor;
    std::optional<Color> mxBackgroundColor;
    /// Containing view shell, if any.
    OutlinerViewShell* mpViewShell;
    /// Another shell, just listening to our state, if any.
    OutlinerViewShell* mpOtherShell;
    EditEngine* mpEditEngine;
    VclPtr<vcl::Window> mpOutputWindow;
    EditView::OutWindowSet maOutWindowSet;
    std::optional<PointerStyle> mxPointer;
    std::unique_ptr<DragAndDropInfo> mpDragAndDropInfo;

    rtl::Reference<vcl::unohelper::DragAndDropWrapper> mxDnDListener;

    OUString maDicNameSingle;

    tools::Long mnInvalidateMore;
    EVControlBits mnControl;
    sal_uInt32 mnTravelXPos;
    CursorFlags maExtraCursorFlags;
    sal_uInt16 mnCursorBidiLevel;
    sal_uInt16 mnScrollDiffX;
    bool mbReadOnly;
    bool mbClickedInSelection;
    bool mbActiveDragAndDropListener;

    Point maAnchorPoint;
    tools::Rectangle maOutputArea;
    Point maVisDocStartPos;
    EESelectionMode meSelectionMode;
    EditSelection maEditSelection;
    EEAnchorMode meAnchorMode;
#if ENABLE_YRS
public:
    /// when SwAnnotationWin::UpdateData() is called, the EE is cleared
    /// and recreated, so use ESelection not EditSelection to survive this!
    ::std::unordered_map<OString, ::std::pair<OUString, ESelection>> m_PeerCursors;
private:
#endif

    /// mechanism to change from the classic refresh mode that simply
    // invalidates the area where text was changed. When set, the invalidate
    // and the direct repaint of the Window-plugged EditView will be suppressed.
    // Instead, a consumer that has registered using an EditViewCallbacks
    // incarnation has to handle that. Used e.g. to represent the edited text
    // in Draw/Impress in an OverlayObject which avoids evtl. expensive full
    // repaints of the EditView(s)
    EditViewCallbacks* mpEditViewCallbacks;
    std::unique_ptr<LOKSpecialPositioning> mpLOKSpecialPositioning;
    bool mbBroadcastLOKViewCursor:1;
    bool mbSuppressLOKMessages:1;
    bool mbNegativeX:1;

    EditViewCallbacks* getEditViewCallbacks() const
    {
        return mpEditViewCallbacks;
    }

    void lokSelectionCallback(const std::optional<tools::PolyPolygon> &pPolyPoly, bool bStartHandleVisible, bool bEndHandleVisible);

    void setEditViewCallbacks(EditViewCallbacks* pEditViewCallbacks)
    {
        mpEditViewCallbacks = pEditViewCallbacks;
    }

    void InvalidateAtWindow(const tools::Rectangle& rRect);

    css::uno::Reference<css::datatransfer::clipboard::XClipboard> GetClipboard() const;

    void SetBroadcastLOKViewCursor(bool bSet)
    {
        mbBroadcastLOKViewCursor = bSet;
    }

protected:

    // DragAndDropClient
    void dragGestureRecognized(const css::datatransfer::dnd::DragGestureEvent& dge) override;
    void dragDropEnd( const css::datatransfer::dnd::DragSourceDropEvent& dsde ) override;
    void drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde) override;
    void dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) override;
    void dragExit( const css::datatransfer::dnd::DropTargetEvent& dte ) override;
    void dragOver(const css::datatransfer::dnd::DropTargetDragEvent& dtde) override;

    void ShowDDCursor( const tools::Rectangle& rRect );
    void HideDDCursor();

    void ImplDrawHighlightRect(OutputDevice& rTarget, const Point& rDocPosTopLeftconst Point& rDocPosBottomRight, tools::PolyPolygon* pPolyPoly, bool bLOKCalcRTL);
    tools::Rectangle ImplGetEditCursor(EditPaM const& rPaM, CursorFlags aShowCursorFlags, sal_Int32& nTextPortionStart, ParaPortion const& rParaPortion) const;

public:
    ImpEditView(EditView* pView, EditEngine& rEditEngine, vcl::Window* pWindow);
    virtual ~ImpEditView() override;

    EditView* GetEditViewPtr() { return mpEditView; }

    EditEngine& getEditEngine() const { return *mpEditEngine; }
    ImpEditEngine& getImpEditEngine() const { return getEditEngine().getImpl(); }


    sal_uInt16 GetScrollDiffX() const { return mnScrollDiffX; }
    void SetScrollDiffX(sal_uInt16 n) { mnScrollDiffX = n; }

    sal_uInt16 GetCursorBidiLevel() const { return mnCursorBidiLevel; }
    void SetCursorBidiLevel(sal_uInt16 n) { mnCursorBidiLevel = n; }

    Point           GetDocPos( const Point& rWindowPos ) const;
    Point           GetWindowPos( const Point& rDocPos ) const;
    tools::Rectangle       GetWindowPos( const tools::Rectangle& rDocPos ) const;

    void                SetOutputArea( const tools::Rectangle& rRect );
    void                ResetOutputArea( const tools::Rectangle& rRect );
    const tools::Rectangle& GetOutputArea() const { return maOutputArea; }

    bool            IsVertical() const;
    bool            IsTopToBottom() const;

    bool            PostKeyEvent( const KeyEvent& rKeyEvent, vcl::Window const * pFrameWin );

    bool            MouseButtonUp( const MouseEvent& rMouseEvent );
    bool            MouseButtonDown( const MouseEvent& rMouseEvent );
    void            ReleaseMouse();
    bool            MouseMove( const MouseEvent& rMouseEvent );
    bool            Command(const CommandEvent& rCEvt);

    void            CutCopy( css::uno::Reference< css::datatransfer::clipboard::XClipboard > const & ;rxClipboard, bool bCut );
    void            Paste( css::uno::Reference< css::datatransfer::clipboard::XClipboard > const & rxClipboard, bool bUseSpecial = false, SotClipboardFormatId format = SotClipboardFormatId::NONE);

    void SetVisDocStartPos(const Point& rPos) { maVisDocStartPos = rPos; }

    tools::Long GetVisDocLeft() const { return maVisDocStartPos.X(); }
    tools::Long GetVisDocTop() const { return maVisDocStartPos.Y(); }
    // coverity[ tainted_data_return : FALSE ] version 2023.12.2
    tools::Long GetVisDocRight() const  { return maVisDocStartPos.X() + ( !IsVertical() ? maOutputArea.GetWidth() : maOutputArea.GetHeight() ); }
    // coverity[ tainted_data_return : FALSE ] version 2023.12.2
    tools::Long GetVisDocBottom() const { return maVisDocStartPos.Y() + ( !IsVertical() ? maOutputArea.GetHeight() : maOutputArea.GetWidth() ); }
    tools::Rectangle       GetVisDocArea() const;

    const EditSelection&  GetEditSelection() const { return maEditSelection; }
    void SetEditSelection(const EditSelection& rEditSelection);
    void SetEditSelection(const EditPaM& rEditPaM) { SetEditSelection(EditSelection(rEditPaM)); }
    bool HasSelection() const { return maEditSelection.HasRange(); }

    void SelectionChanged();
    void DrawSelectionXOR()
    {
        DrawSelectionXOR(maEditSelection);
    }
    void            DrawSelectionXOR( EditSelection, vcl::Region* pRegion = nullptr, OutputDevice* pTargetDevice = nullptr );
    void GetSelectionRectangles(EditSelection aTmpSel, std::vector<tools::Rectangle>& rLogicRects);

    void ScrollStateChange();

    OutputDevice&   GetOutputDevice() const;
    weld::Widget*   GetPopupParent(tools::Rectangle& rRect) const;
    vcl::Window* GetWindow() const { return mpOutputWindow; }

    void            SetSelectionMode( EESelectionMode eMode );

    PointerStyle GetPointer()
    {
        if ( !mxPointer )
        {
            mxPointer = IsVertical() ? PointerStyle::TextVertical : PointerStyle::Text;
            return *mxPointer;
        }

        if(PointerStyle::Text == *mxPointer && IsVertical())
        {
            mxPointer = PointerStyle::TextVertical;
        }
        else if(PointerStyle::TextVertical == *mxPointer && !IsVertical())
        {
            mxPointer = PointerStyle::Text;
        }

        return *mxPointer;
    }

    vcl::Cursor* GetCursor()
    {
        if (!mpCursor)
            mpCursor.reset(new vcl::Cursor);
        return mpCursor.get();
    }

    void            AddDragAndDropListeners();
    void            RemoveDragAndDropListeners();

    bool            IsBulletArea( const Point& rPos, sal_Int32* pPara );

//  For the Selection Engine...
    void            CreateAnchor();
    void            DeselectAll();
    bool            SetCursorAtPoint( const Point& rPointPixel );
    bool            IsSelectionAtPoint( const Point& rPosPixel );
    bool            IsInSelection( const EditPaM& rPaM );

    bool            IsSelectionFullPara() const;
    bool            IsSelectionInSinglePara() const;

    void            SetAnchorMode( EEAnchorMode eMode );
    EEAnchorMode GetAnchorMode() const { return meAnchorMode; }
    void            CalcAnchorPoint();
    void            RecalcOutputArea();

    tools::Rectangle GetEditCursor() const;

    ::std::optional<::std::tuple<tools::Rectangle, tools::Rectangle, CursorFlags, sal_Int32>>
    ImplGetCursorRectAndMaybeScroll(EditPaM const& rPos,
        ParaPortion const& rParaPortion, bool bGotoCursor);

    void            ShowCursor( bool bGotoCursor, bool bForceVisCursor );
    Pair            Scroll( tools::Long ndX, tools::Long ndY, ScrollRangeCheck nRangeCheck = ScrollRangeCheck::NoNegative );

    void SetInsertMode( bool bInsert );
    bool IsInsertMode() const { return !(mnControl & EVControlBits::OVERWRITE); }

    bool IsPasteEnabled() const { return bool(mnControl & EVControlBits::ENABLEPASTE); }

    bool DoSingleLinePaste() const { return bool(mnControl & EVControlBits::SINGLELINEPASTE); }
    bool DoAutoScroll() const { return bool(mnControl & EVControlBits::AUTOSCROLL); }
    bool DoAutoSize() const { return bool(mnControl & EVControlBits::AUTOSIZE); }
    bool DoAutoWidth() const { return bool(mnControl & EVControlBits::AUTOSIZEX); }
    bool DoAutoHeight() const { return bool(mnControl & EVControlBits::AUTOSIZEY); }
    bool DoInvalidateMore() const { return bool(mnControl & EVControlBits::INVONEMORE ); }

    void        SetBackgroundColor( const Color& rColor );
    const Color& GetBackgroundColor() const;

    /// Informs this edit view about which view shell contains it.
    void RegisterViewShell(OutlinerViewShell* pViewShell);
    const OutlinerViewShell* GetViewShell() const;
    /// Informs this edit view about which other shell listens to it.
    void RegisterOtherShell(OutlinerViewShell* pViewShell);

    bool            IsWrongSpelledWord( const EditPaM& rPaM, bool bMarkIfWrong );
    OUString        SpellIgnoreWord();

    const SvxFieldItem* GetField( const Point& rPos, sal_Int32* pPara, sal_Int32* pPos ) const;
    void            DeleteSelected();

    //  If possible invalidate more than OutputArea, for the DrawingEngine text frame
    void SetInvalidateMore(sal_uInt16 nPixel)
    {
        mnInvalidateMore = nPixel;
    }
    sal_uInt16 GetInvalidateMore() const
    {
        return sal_uInt16(mnInvalidateMore);
    }

    void InitLOKSpecialPositioning(MapUnit eUnit, const tools::Rectangle& rOutputArea,
                                   const Point& rVisDocStartPos);
    void SetLOKSpecialOutputArea(const tools::Rectangle& rOutputArea);
    const tools::Rectangle & GetLOKSpecialOutputArea() const;
    void SetLOKSpecialVisArea(const tools::Rectangle& rVisArea);
    tools::Rectangle GetLOKSpecialVisArea() const;
    bool HasLOKSpecialPositioning() const;

    void SetLOKSpecialFlags(LOKSpecialFlags eFlags);

    void SuppressLOKMessages(bool bSet) { mbSuppressLOKMessages = bSet; }
    bool IsSuppressLOKMessages() const { return mbSuppressLOKMessages; }

    void SetNegativeX(bool bSet) { mbNegativeX = bSet; }
    bool IsNegativeX() const { return mbNegativeX; }
};


//  ImpEditEngine


class ImpEditEngine : public SfxListener, public svl::StyleSheetUser
{
    friend class EditEngine;
#if ENABLE_YRS
    friend class EditDoc;
#endif

    typedef EditEngine::ViewsType ViewsType;

private:
    std::shared_ptr<editeng::SharedVclResources> pSharedVCL;

    // Document Specific data ...
    ParaPortionList maParaPortionList; // Formatting
    Size maPaperSize; // Layout
    Size maMinAutoPaperSize; // Layout ?
    Size maMaxAutoPaperSize; // Layout ?
    tools::Long mnMinColumnWrapHeight = 0; // Corresponds to graphic object height
    EditDoc maEditDoc; // Document content

    // Engine Specific data ...
    EditEngine* mpEditEngine;
    ViewsType maEditViews;
    EditView*  mpActiveView;
    std::unique_ptr<TextRanger> mpTextRanger;

    SfxStyleSheetPool* mpStylePool;
    SfxItemPool* mpTextObjectPool;

    VclPtr<VirtualDevice> mpVirtDev;
    VclPtr<OutputDevice> mpRefDev;
    VclPtr<VirtualDevice> mpOwnDev;

    svtools::ColorConfig maColorConfig;

    mutable std::unique_ptr<SfxItemSet> pEmptyItemSet;
    EditUndoManager* mpUndoManager;
    std::optional<ESelection> moUndoMarkSelection;

    std::unique_ptr<ImplIMEInfos> mpIMEInfos;

    OUString maWordDelimiters;

    EditSelFunctionSet  maSelFuncSet;
    EditSelectionEngine maSelEngine;

    Color               maBackgroundColor;

    ScalingParameters maCustomScalingParameters;
    ScalingParameters maScalingParameters;
    bool mbRoundToNearestPt;

    CharCompressType mnAsianCompressionMode;

    EEHorizontalTextDirection meDefaultHorizontalTextDirection;

    sal_Int32 mnBigTextObjectStart;
    css::uno::Reference<css::linguistic2::XSpellChecker1> mxSpeller;
    css::uno::Reference<css::linguistic2::XHyphenator>    mxHyphenator;
    std::unique_ptr<SpellInfo> mpSpellInfo;
    mutable css::uno::Reference <css::i18n::XBreakIterator> mxBI;
    mutable css::uno::Reference <css::i18n::XExtendedInputSequenceChecker> mxISC;

    std::unique_ptr<ConvInfo> mpConvInfo;

    OUString maAutoCompleteText;

    InternalEditStatus maStatus;

    LanguageType meDefLanguage;

    OnDemandLocaleDataWrapper       mxLocaleDataWrapper;
    OnDemandTransliterationWrapper  mxTransliterationWrapper;

    // For Formatting / Update...
    std::vector<std::unique_ptr<DeletedNodeInfo>> maDeletedNodes;
    tools::Rectangle maInvalidRect;
    tools::Long mnCurTextHeight;
    sal_uInt16 mnOnePixelInRef;

    IdleFormattter maIdleFormatter;
    Timer maOnlineSpellTimer;

    // For Chaining
    sal_Int32 mnOverflowingPara = -1;
    sal_Int32 mnOverflowingLine = -1;
    bool mbNeedsChainingHandling = false;

    sal_Int16 mnColumns = 1;
    sal_Int32 mnColumnSpacing = 0;

    // If it is detected at one point that the StatusHdl has to be called, but
    // this should not happen immediately (critical section):
    Timer maStatusTimer;
    Size maLOKSpecialPaperSize;

    Link<EditStatus&,void>         maStatusHdlLink;
    Link<EENotify&,void>           maNotifyHdl;
    Link<HtmlImportInfo&,void>     maHtmlImportHdl;
    Link<RtfImportInfo&,void>      maRtfImportHdl;
    Link<MoveParagraphsInfo&,void> maBeginMovingParagraphsHdl;
    Link<MoveParagraphsInfo&,void> maEndMovingParagraphsHdl;
    Link<PasteOrDropInfos&,void>   maBeginPasteOrDropHdl;
    Link<PasteOrDropInfos&,void>   maEndPasteOrDropHdl;
    Link<LinkParamNone*,void>      maModifyHdl;
    Link<EditView*,void>           maBeginDropHdl;
    Link<EditView*,void>           maEndDropHdl;

    bool mbKernAsianPunctuation : 1;
    bool mbAddExtLeading : 1;
    bool mbIsFormatting : 1;
    bool mbFormatted : 1;
    bool mbInSelection : 1;
    bool mbIsInUndo : 1;
    bool mbUpdateLayout : 1;
    bool mbUndoEnabled : 1;
    bool mbDowning : 1;
    bool mbUseAutoColor : 1;
    bool mbForceAutoColor : 1;
    bool mbCallParaInsertedOrDeleted : 1;
    bool mbFirstWordCapitalization : 1;   // specifies if auto-correction should capitalize the first word or not
    bool mbLastTryMerge : 1;
    bool mbReplaceLeadingSingleQuotationMark : 1;
    bool mbSkipOutsideFormat : 1;
    bool mbFuzzing : 1;

    bool mbNbspRunNext;  // can't be a bitfield as it is passed as bool&

    // Methods...


    void                ParaAttribsChanged( ContentNode const * pNode, bool bIgnoreUndoCheck = false );
    void                TextModified();
    void                CalcHeight(ParaPortion& rParaPortion);
    bool isInEmptyClusterAtTheEnd(const ParaPortion& rParaPortion, bool bIsScaling);

    void                InsertUndo( std::unique_ptr<EditUndo> pUndo, bool bTryMerge = false );
    void                ResetUndoManager();
    bool            HasUndoManager() const  { return mpUndoManager != nullptr; }

    std::unique_ptr<EditUndoSetAttribs> CreateAttribUndo( EditSelection aSel, const SfxItemSet& rSet );

    std::unique_ptr<EditTextObject> GetEmptyTextObject();

    std::tuple<const ParaPortion*, const EditLine*, tools::Long> GetPortionAndLine(Point aDocPos);
    EditPaM             GetPaM( Point aDocPos, bool bSmart = true );
    bool IsTextPos(const Point& rDocPos, sal_uInt16 nBorder);
    tools::Long GetXPos(ParaPortion const& rParaPortion, EditLine const& rLine, sal_Int32 nIndex, bool bPreferPortionStart = falseconst;
    tools::Long GetPortionXOffset(ParaPortion const& rParaPortion, EditLine const;rLine, sal_Int32 nTextPortion) const;
    sal_Int32 GetChar(ParaPortion const& rParaPortion, EditLine const& rLine, tools::Long nX, bool bSmart = true);
    Range GetLineXPosStartEnd(ParaPortion const& rParaPortion, EditLine const& rLine) const;

    void                ParaAttribsToCharAttribs( ContentNode* pNode );
    void                GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const;

    std::unique_ptr<EditTextObject>
                        CreateTextObject(EditSelection aSelection, SfxItemPool*, bool bAllowBigObjects = false, sal_Int32 nBigObjStart = 0);
    EditSelection       InsertTextObject( const EditTextObject&, EditPaM aPaM );
    EditSelection       PasteText( css::uno::Reference< css::datatransfer::XTransferable > const &&nbsp;rxDataObj, const OUString& rBaseURL, const EditPaM& rPaM, bool bUseSpecial, SotClipboardFormatId format = SotClipboardFormatId::NONE);

    void                CheckPageOverflow();

    void                Clear();
    EditPaM             RemoveText();

    bool createLinesForEmptyParagraph(ParaPortion& rParaPortion);
    tools::Long calculateMaxLineWidth(tools::Long nStartX, SvxLRSpaceItem const& rLRItem,
                                      const SvxFontUnitMetrics& rMetrics);
    void populateRubyInfo(ParaPortion& rParaPortion, EditLine* pLine);
    bool CreateLines(sal_Int32 nPara, sal_uInt32 nStartPosY);

    void                CreateAndInsertEmptyLine(ParaPortion& rParaPortion);
    bool                FinishCreateLines(ParaPortion& rParaPortion);
    void                CreateTextPortions(ParaPortion& rParaPortion, sal_Int32& rStartPos);
    void                RecalcTextPortion(ParaPortion& rParaPortion, sal_Int32 nStartPos, sal_Int32 nNewChars);
    sal_Int32           SplitTextPortion(ParaPortion& rParaPortion, sal_Int32 nPos,  EditLine* pCurLine = nullptr);
    void                SeekCursor( ContentNode* pNode, sal_Int32 nPos, SvxFont& rFont, OutputDevice* pOut = nullptr );
    void                RecalcFormatterFontMetrics( FormatterFontMetric& rCurMetrics, SvxFont& rFont );
    void                CheckAutoPageSize();

    void                ImpBreakLine(ParaPortion& rParaPortion, EditLine& rLine, TextPortion const * pPortion, sal_Int32 nPortionStart, tools::Long nRemainingWidth, bool bCanHyphenate);
    void                ImpAdjustBlocks(ParaPortion& rParaPortion, EditLine& rLine, tools::Long nRemainingSpace );
    EditPaM             ImpConnectParagraphs(ContentNode* pLeft, ContentNode* pRight, bool bBackward = falsebool isUpdateCursors = true);
    EditPaM             ImpDeleteSelection(const EditSelection& rCurSel);
    EditPaM             ImpInsertParaBreak( EditPaM& rPaM, bool bKeepEndingAttribs = true );
    EditPaM             ImpInsertParaBreak( const EditSelection& rEditSelection );
    EditPaM             ImpInsertText(const EditSelection& aCurEditSelection, const OUString& rStr);
    EditPaM             ImpInsertFeature(const EditSelection& rCurSel, const SfxPoolItem& rItem);
    void                ImpRemoveChars( const EditPaM& rPaM, sal_Int32 nChars );
    void                ImpRemoveParagraph( sal_Int32 nPara );
    EditSelection       ImpMoveParagraphs( Range aParagraphs, sal_Int32 nNewPos );

    EditPaM             ImpFastInsertText( EditPaM aPaM, const OUString& rStr );
    EditPaM             ImpFastInsertParagraph( sal_Int32 nPara );

    bool                ImplHasText() const;

    void ImpFindKashidas(ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEnd,
                         std::vector<sal_Int32>& rArray, sal_Int32 nRemainingSpace);

    void                InsertContent(std::unique_ptr<ContentNode> pNode, sal_Int32 nPos);
    EditPaM             SplitContent( sal_Int32 nNode, sal_Int32 nSepPos );
    EditPaM             ConnectContents( sal_Int32 nLeftNode, bool bBackward );

    void                ShowParagraph( sal_Int32 nParagraph, bool bShow );

    EditPaM             PageUp( const EditPaM& rPaM, EditView const * pView);
    EditPaM             PageDown( const EditPaM& rPaM, EditView const * pView);
    EditPaM             CursorUp( const EditPaM& rPaM, EditView const * pEditView );
    EditPaM             CursorDown( const EditPaM& rPaM, EditView const * pEditView );
    EditPaM             CursorLeft( const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode = css::i18n::CharacterIteratorMode::SKIPCELL );
    EditPaM             CursorRight( const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode = css::i18n::CharacterIteratorMode::SKIPCELL );
    EditPaM             CursorStartOfLine( const EditPaM& rPaM );
    EditPaM             CursorEndOfLine( const EditPaM& rPaM );
    static EditPaM      CursorStartOfParagraph( const EditPaM& rPaM );
    static EditPaM      CursorEndOfParagraph( const EditPaM& rPaM );
    EditPaM             CursorStartOfDoc();
    EditPaM             CursorEndOfDoc();
    EditPaM             WordLeft( const EditPaM& rPaM );
    EditPaM             WordRight( const EditPaM& rPaM, sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES );
    EditPaM             StartOfWord( const EditPaM& rPaM );
    EditPaM             EndOfWord( const EditPaM& rPaM );
    EditSelection       SelectWord( const EditSelection& rCurSelection, sal_Int16 nWordType = css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, bool bAcceptStartOfWord = truebool bAcceptEndOfWord = false );
    EditSelection       SelectSentence( const EditSelection& rCurSel ) const;
    EditPaM             CursorVisualLeftRight( EditView const * pEditView, const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode, bool bToLeft );
    EditPaM             CursorVisualStartEnd( EditView const * pEditView, const EditPaM& rPaM, bool bStart );


    void                InitScriptTypes( sal_Int32 nPara );
    sal_uInt16          GetI18NScriptType( const EditPaM& rPaM, sal_Int32* pEndPos = nullptr ) const;
    SvtScriptType       GetItemScriptType( const EditSelection& rSel ) const;
    bool                IsScriptChange( const EditPaM& rPaM ) const;
    bool                HasScriptType( sal_Int32 nPara, sal_uInt16 nType ) const;

    bool                ImplCalcAsianCompression( ContentNode* pNode, TextPortion* pTextPortion, sal_Int32 nStartPos,
                                                double* pDXArray, sal_uInt16 n100thPercentFromMax, bool bManipulateDXArray );
    void                ImplExpandCompressedPortions(EditLine& rLine, ParaPortion& rParaPortion, tools::Long nRemainingWidth);

    void                ImplInitLayoutMode(OutputDevice& rOutDev, sal_Int32 nPara, sal_Int32 nIndex);
    static LanguageType ImplCalcDigitLang(LanguageType eCurLang);
    static void         ImplInitDigitMode(OutputDevice& rOutDev, LanguageType eLang);
    static OUString     convertDigits(std::u16string_view rString, sal_Int32 nStt, sal_Int32 nLen, LanguageType eDigitLang);

    EditPaM             ReadText( SvStream& rInput, EditSelection aSel );
    EditPaM             ReadRTF( SvStream& rInput, EditSelection aSel );
    EditPaM             ReadXML( SvStream& rInput, EditSelection aSel );
    EditPaM             ReadHTML( SvStream& rInput, const OUString& rBaseURL, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs );
    ErrCode             WriteText( SvStream& rOutput, EditSelection aSel );
    ErrCode             WriteRTF( SvStream& rOutput, EditSelection aSel, bool bClipboard );
    void                WriteXML(SvStream& rOutput, const EditSelection& rSel);

    void                WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, sal_Int32 nPara, sal_Int32 nPos,
                            const std::vector<std::unique_ptr<SvxFontItem>>& rFontTable, SvxColorList& rColorList );
    bool                WriteItemListAsRTF( ItemList& rLst, SvStream& rOutput, sal_Int32 nPara, sal_Int32 nPos,
                            const std::vector<std::unique_ptr<SvxFontItem>>& rFontTable, SvxColorList& rColorList );
    sal_Int32           LogicToTwips( sal_Int32 n );

    double scaleXSpacingValue(tools::Long nXValue) const
    {
        if (!maStatus.DoStretch() || maScalingParameters.fSpacingX == 1.0)
            return nXValue;

        return double(nXValue) * maScalingParameters.fSpacingX;
    }

    double scaleYSpacingValue(sal_uInt16 nYValue) const
    {
        if (!maStatus.DoStretch() || maScalingParameters.fSpacingY == 1.0)
            return nYValue;

        return double(nYValue) * maScalingParameters.fSpacingY;
    }

    double scaleXFontValue(tools::Long nXValue) const
    {
        if (!maStatus.DoStretch() || (maScalingParameters.fFontX == 1.0))
            return nXValue;

        return double(nXValue) * maScalingParameters.fFontX;
    }

    double scaleYFontValue(sal_uInt16 nYValue) const
    {
        if (!maStatus.DoStretch() || (maScalingParameters.fFontY == 1.0))
            return nYValue;

        return double(nYValue) * maScalingParameters.fFontY;
    }

    void setRoundToNearestPt(bool bRound) { mbRoundToNearestPt = bRound; }
    double roundToNearestPt(double fInput) const;

    ContentNode*        GetPrevVisNode( ContentNode const * pCurNode );
    ContentNode*        GetNextVisNode( ContentNode const * pCurNode );

    const ParaPortion*  GetPrevVisPortion( const ParaPortion* pCurPortion ) const;
    const ParaPortion*  GetNextVisPortion( const ParaPortion* pCurPortion ) const;

    void                SetBackgroundColor( const Color& rColor ) { maBackgroundColor = rColor; }
    const Color&        GetBackgroundColor() const { return maBackgroundColor; }

    tools::Long                CalcVertLineSpacing(Point& rStartPos) const;

    Color               GetAutoColor() const;
    void EnableAutoColor( bool b ) { mbUseAutoColor = b; }
    bool IsAutoColorEnabled() const { return mbUseAutoColor; }
    void ForceAutoColor( bool b ) { mbForceAutoColor = b; }
    bool IsForceAutoColor() const { return mbForceAutoColor; }

    VirtualDevice* GetVirtualDevice(const MapMode& rMapMode, DrawModeFlags nDrawMode)
    {
        if (!mpVirtDev)
            mpVirtDev = VclPtr<VirtualDevice>::Create();

        if ((mpVirtDev->GetMapMode().GetMapUnit() != rMapMode.GetMapUnit()) ||
            (mpVirtDev->GetMapMode().GetScaleX() != rMapMode.GetScaleX()) ||
            (mpVirtDev->GetMapMode().GetScaleY() != rMapMode.GetScaleY()) )
        {
            MapMode aMapMode(rMapMode);
            aMapMode.SetOrigin(Point(0, 0));
            mpVirtDev->SetMapMode(aMapMode);
        }

        mpVirtDev->SetDrawMode(nDrawMode);

        return mpVirtDev;
    }

    void EraseVirtualDevice() { mpVirtDev.disposeAndClear(); }

    DECL_LINK( StatusTimerHdl, Timer *, void);
    DECL_LINK( IdleFormatHdl, Timer *, void);
    DECL_LINK( OnlineSpellHdl, Timer *, void);
    DECL_LINK( DocModified, LinkParamNone*, void );

    void                CheckIdleFormatter();

    const ParaPortion* FindParaPortion(const ContentNode* pNode) const
    {
        sal_Int32 nPos = maEditDoc.GetPos( pNode );
        DBG_ASSERT( nPos < GetParaPortions().Count(), "Portionloser Node?" );
        return GetParaPortions().SafeGetObject(nPos);
    }

    ParaPortion* FindParaPortion(ContentNode const * pNode)
    {
        sal_Int32 nPos = maEditDoc.GetPos( pNode );
        DBG_ASSERT( nPos < GetParaPortions().Count(), "Portionloser Node?" );
        return GetParaPortions().SafeGetObject(nPos);
    }

    css::uno::Reference< css::datatransfer::XTransferable > CreateTransferable( const EditSelection& rSelection );

    css::uno::Reference < css::i18n::XBreakIterator > const & ImplGetBreakIterator() const;
    css::uno::Reference < css::i18n::XExtendedInputSequenceChecker > const & ImplGetInputSequenceChecker() const;

    void ImplUpdateOverflowingParaNum(tools::Long);
    void ImplUpdateOverflowingLineNum(tools::Long, sal_uInt32, tools::Long);

    void CreateSpellInfo( bool bMultipleDocs );
    /// Obtains a view shell ID from the active EditView.
    ViewShellId CreateViewShellId();

    ImpEditEngine(EditEngine* pEditEngine, SfxItemPool* pPool);
    void InitDoc(bool bKeepParaAttribs);
    EditDoc&                GetEditDoc()            { return maEditDoc; }
    const EditDoc&          GetEditDoc() const      { return maEditDoc; }

    const ParaPortionList&  GetParaPortions() const { return maParaPortionList; }
    ParaPortionList&        GetParaPortions()       { return maParaPortionList; }

    tools::Long Calc1ColumnTextHeight();

    void IdleFormatAndLayout(EditView* pCurView) { maIdleFormatter.DoIdleFormat(pCurView); }

protected:
    virtual void            Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;

public:
                            virtual ~ImpEditEngine() override;
                            ImpEditEngine(const ImpEditEngine&) = delete;
    ImpEditEngine&          operator=(const ImpEditEngine&) = delete;

    EditUndoManager& GetUndoManager()
    {
        if (!mpUndoManager)
        {
            mpUndoManager = new EditUndoManager();
            mpUndoManager->SetEditEngine(mpEditEngine);
        }
        return *mpUndoManager;
    }

    EditUndoManager* SetUndoManager(EditUndoManager* pNew)
    {
        EditUndoManager* pRetval = mpUndoManager;

        if (mpUndoManager)
        {
            mpUndoManager->SetEditEngine(nullptr);
        }

        mpUndoManager = pNew;

        if (mpUndoManager)
        {
            mpUndoManager->SetEditEngine(mpEditEngine);
        }

        return pRetval;
    }

    // @return the previous bUpdateLayout state
    bool                    SetUpdateLayout( bool bUpdate, EditView* pCurView = nullptr, bool bForceUpdate = false );
    bool IsUpdateLayout() const   { return mbUpdateLayout; }

    ViewsType& GetEditViews() { return maEditViews; }
    const ViewsType& GetEditViews() const { return maEditViews; }
    void InsertView(EditView* pEditView, size_t nIndex);
    EditView* RemoveView( EditView* pView );
    void RemoveView(size_t nIndex);
    bool HasView( EditView* pView ) const;

    void SetValidPaperSize( const Size& rSz );
    const Size& GetPaperSize() const { return maPaperSize; }
    void SetPaperSize(const Size& rNewSize);

    void                    SetPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::B2DPolyPolygon* pLinePolyPolygon);

    void                    SetVertical( bool bVertical);
    bool                    IsEffectivelyVertical() const                      { return GetEditDoc().IsEffectivelyVertical(); }
    bool                    IsTopToBottom() const                   { return GetEditDoc().IsTopToBottom(); }
    bool                    GetVertical() const               { return GetEditDoc().GetVertical(); }
    void                    SetRotation( TextRotation nRotation);
    TextRotation            GetRotation() const                     { return GetEditDoc().GetRotation(); }

    void SetTextColumns(sal_Int16 nColumns, sal_Int32 nSpacing);

    bool IsPageOverflow( ) const;

    void                    SetFixedCellHeight( bool bUseFixedCellHeight );
    bool                    IsFixedCellHeight() const { return GetEditDoc().IsFixedCellHeight(); }

    void                        SetDefaultHorizontalTextDirection( EEHorizontalTextDirection eHTextDir ) { meDefaultHorizontalTextDirection = eHTextDir; }
    EEHorizontalTextDirection   GetDefaultHorizontalTextDirection() const { return meDefaultHorizontalTextDirection; }


    void                    InitWritingDirections( sal_Int32 nPara );
    bool                    IsRightToLeft( sal_Int32 nPara ) const;
    sal_uInt8               GetRightToLeft( sal_Int32 nPara, sal_Int32 nChar, sal_Int32* pStart = nullptr, sal_Int32* pEnd = nullptr );
    bool                    HasDifferentRTLLevels( const ContentNode* pNode );

    void                    SetTextRanger( std::unique_ptr<TextRanger> pRanger );
    TextRanger*             GetTextRanger() const { return mpTextRanger.get(); }

    const Size& GetMinAutoPaperSize() const { return maMinAutoPaperSize; }
    void SetMinAutoPaperSize(const Size& rSize) { maMinAutoPaperSize = rSize; }

    const Size& GetMaxAutoPaperSize() const { return maMaxAutoPaperSize; }
    void SetMaxAutoPaperSize(const Size& rSize) { maMaxAutoPaperSize = rSize; }

    void SetMinColumnWrapHeight(tools::Long nVal) { mnMinColumnWrapHeight = nVal; }

    // Returns the height of the text, excluding empty lines in the end
    tools::Long FormatParagraphs(o3tl::sorted_vector<sal_Int32>& rRepaintParagraphs, bool bIsScaling);
    void ScaleContentToFitWindow(o3tl::sorted_vector<sal_Int32>& rRepaintParagraphs);
    void FormatDoc();
    void FormatFullDoc();
    void EnsureDocumentFormatted();

    void                    Draw( OutputDevice& rOutDev, const Point& rStartPos, Degree10 nOrientation );
    void                    Draw( OutputDevice& rOutDev, const tools::Rectangle& rOutRect, const Point&&nbsp;rStartDocPos, bool bClip );
    void                    UpdateViews( EditView* pCurView = nullptr );
    Point CalculateTextPaintStartPosition(ImpEditView& rView) const;
    void                    Paint( ImpEditView* pView, const tools::Rectangle& rRect, OutputDevice* pTargetDevice );
    void Paint(
        OutputDevice& rOutDev, tools::Rectangle aClipRect, Point aStartPos, Degree10 nOrientation = 0_deg10,
        const std::function<void(const DrawPortionInfo&)>& rDrawPortion = std::function<void(const DrawPortionInfo&)>(),
        const std::function<void(const DrawBulletInfo&)>& rDrawBullet = std::function<void(const DrawBulletInfo&)>());

    bool                MouseButtonUp( const MouseEvent& rMouseEvent, EditView* pView );
    bool                MouseButtonDown( const MouseEvent& rMouseEvent, EditView* pView );
    void                ReleaseMouse();
    bool                MouseMove( const MouseEvent& rMouseEvent, EditView* pView );
    bool                    Command(const CommandEvent& rCEvt, EditView* pView);

    EditSelectionEngine&    GetSelEngine() { return maSelEngine; }
    OUString                GetText( const ESelection& rESelection );
    OUString                GetSelected( const EditSelection& rSel ) const;

    const SfxItemSet& GetEmptyItemSet() const;

    bool                    UpdateSelection(EditSelection &);
    void                    UpdateSelections();
    void UpdateSelectionsDelete(ESelection const& rDeleted);
    void UpdateSelectionsInsert(ESelection const& rInserted);

    void                EnableUndo( bool bEnable );
    bool IsUndoEnabled() const { return mbUndoEnabled; }
    void SetUndoMode( bool b ) { mbIsInUndo = b; }
    bool IsInUndo() const { return mbIsInUndo; }

    void SetCallParaInsertedOrDeleted( bool b ) { mbCallParaInsertedOrDeleted = b; }
    bool IsCallParaInsertedOrDeleted() const { return mbCallParaInsertedOrDeleted; }

    bool IsFormatted() const { return mbFormatted; }
    bool IsFormatting() const { return mbIsFormatting; }

    void            SetText(const OUString& rText);
    EditPaM         DeleteSelected(const EditSelection& rEditSelection);
    EditPaM         InsertTextUserInput( const EditSelection& rCurEditSelection, sal_Unicode cbool bOverwrite );
    EditPaM         InsertText(const EditSelection& aCurEditSelection, const OUString& rStr);
    EditPaM         AutoCorrect( const EditSelection& rCurEditSelection, sal_Unicode c, bool bOverwrite, vcl::Window const * pFrameWin = nullptr );
    EditPaM         DeleteLeftOrRight( const EditSelection& rEditSelection, sal_uInt8 nMode, DeleteMode nDelMode );
    EditPaM         InsertParaBreak(const EditSelection& rEditSelection);
    EditPaM         InsertLineBreak(const EditSelection& aEditSelection);
    EditPaM         InsertTab(const EditSelection& rEditSelection);
    EditPaM         InsertField(const EditSelection& rCurSel, const SvxFieldItem& rFld);
    bool            UpdateFields();

    ErrCode         Read( SvStream& rInput, const OUString& rBaseURL, EETextFormat eFormat, SvKeyValueIterator* pHTTPHeaderAttrs = nullptr );
    EditPaM         Read( SvStream& rInput, const OUString& rBaseURL, EETextFormat eFormat, const EditSelection& rSel, SvKeyValueIterator* pHTTPHeaderAttrs = nullptr);
    void            Write( SvStream& rOutput, EETextFormat eFormat );
    void            Write(SvStream& rOutput, EETextFormat eFormat, const EditSelection& rSel);
    OString         GetSimpleHtml() const;

    std::unique_ptr<EditTextObject> CreateTextObject(sal_Int32 nPara, sal_Int32 nParas);
    std::unique_ptr<EditTextObject> CreateTextObject();
    std::unique_ptr<EditTextObject> CreateTextObject(const EditSelection& rSel);
    void            SetText( const EditTextObject& rTextObject );
    EditSelection   InsertText( const EditTextObject& rTextObject, EditSelection aSel );

    EditSelection const& MoveCursor(const KeyEvent& rKeyEvent, EditView* pEditView,
                                    CursorFlags* pOutCursorFlags = nullptr);

    EditSelection   MoveParagraphs( Range aParagraphs, sal_Int32 nNewPos, EditView* pCurView );

    tools::Long     CalcTextHeight();
    sal_uInt32      GetTextHeight() const;
    sal_uInt32      CalcTextWidth( bool bIgnoreExtraSpace);
    sal_uInt32      CalcParaWidth( sal_Int32 nParagraph, bool bIgnoreExtraSpace );
    sal_uInt32      CalcLineWidth(ParaPortion const& rPortion, EditLine const& rLine, bool bIgnoreExtraSpace);
    sal_Int32       GetLineCount( sal_Int32 nParagraph );
    sal_Int32       GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine );
    void            GetLineBoundaries( /*out*/sal_Int32& rStart, /*out*/sal_Int32& rEnd, sal_Int32 nParagraph, sal_Int32 nLine );
    sal_Int32       GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex );
    sal_uInt16      GetLineHeight( sal_Int32 nParagraph, sal_Int32 nLine );
    sal_uInt32 GetParaHeight(sal_Int32 nParagraph) const;
    Point           GetDocPosTopLeft( sal_Int32 nParagraph );
    tools::Rectangle GetParaBounds( sal_Int32 nPara );

    SfxItemSet      GetAttribs( sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, GetAttribsFlags nFlags = GetAttribsFlags::ALL ) const;
    SfxItemSet      GetAttribs( EditSelection aSel, EditEngineAttribs nOnlyHardAttrib = EditEngineAttribs::All  );
    void            SetAttribs( EditSelection aSel, const SfxItemSet& rSet, SetAttribsMode nSpecial = SetAttribsMode::NONE, bool bSetSelection = true );
    void            RemoveAttribs( const ESelection& rSelection, bool bRemoveParaAttribs, sal_uInt16 nWhich );
    void            RemoveCharAttribs( EditSelection aSel, EERemoveParaAttribsMode eMode, sal_uInt16 nWhich );
    void            RemoveCharAttribs( sal_Int32 nPara, sal_uInt16 nWhich = 0, bool bRemoveFeatures = false );
    void            SetFlatMode( bool bFlat );

    void                SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet );
    const SfxItemSet&   GetParaAttribs( sal_Int32 nPara ) const;

    bool            HasParaAttrib( sal_Int32 nPara, sal_uInt16 nWhich ) const;
    const SfxPoolItem&  GetParaAttrib( sal_Int32 nPara, sal_uInt16 nWhich ) const;
    template<class T>
    const T&            GetParaAttrib( sal_Int32 nPara, TypedWhichId<T> nWhich ) const
    {
        return static_cast<const T&>(GetParaAttrib(nPara, sal_uInt16(nWhich)));
    }

    tools::Rectangle PaMtoEditCursor(EditPaM aPaM, CursorFlags aFlags = CursorFlags());
    tools::Rectangle GetEditCursor(ParaPortion const& rPortion, EditLine const& rLine, sal_Int32 nIndex, CursorFlags aFlags);

    bool            IsModified() const { return maEditDoc.IsModified(); }
    void            SetModifyFlag(bool b) { maEditDoc.SetModified( b ); }
    void            SetModifyHdl( const Link<LinkParamNone*,void>& rLink ) { maModifyHdl = rLink; }

    bool IsInSelectionMode() const { return mbInSelection; }

//  For Undo/Redo
    void            Undo( EditView* pView );
    void            Redo( EditView* pView );

//  OV-Special
    void            InvalidateFromParagraph( sal_Int32 nFirstInvPara );
    void            InsertParagraph( sal_Int32 nPara, const EditTextObject& rTxtObj, bool bAppend );
    void            InsertParagraph(sal_Int32 nPara, const OUString& rTxt);
    EditPaM         InsertParagraph( sal_Int32 nPara );
    std::optional<EditSelection> SelectParagraph( sal_Int32 nPara );
    void            SetParagraphText(sal_Int32 nPara, const OUString& rTxt);

    void            SetStatusEventHdl( const Link<EditStatus&, void>& rLink ) { maStatusHdlLink = rLink; }
    const Link<EditStatus&,void>& GetStatusEventHdl() const               { return maStatusHdlLink; }

    void            SetNotifyHdl( const Link<EENotify&,void>& rLink )     { maNotifyHdl = rLink; }
    const Link<EENotify&,void>&   GetNotifyHdl() const            { return maNotifyHdl; }

    void            FormatAndLayout( EditView* pCurView = nullptr, bool bCalledFromUndo = false );

    const svtools::ColorConfig& GetColorConfig() const { return maColorConfig; }
    static bool     IsVisualCursorTravelingEnabled();
    static bool     DoVisualCursorTraveling();

    EditSelection         ConvertSelection( sal_Int32 nStartPara, sal_Int32 nStartPos, sal_Int32 nEndPara, sal_Int32 nEndPos );

    EPaM CreateEPaM( const EditPaM& rPaM ) const
    {
        return EPaM(maEditDoc.GetPos(rPaM.GetNode()), rPaM.GetIndex());
    }

    EditPaM CreateEditPaM( const EPaM& rEPaM )
    {
        DBG_ASSERT( rEPaM.nPara < maEditDoc.Count(), "CreateEditPaM: invalid paragraph" );
        DBG_ASSERT(maEditDoc.GetObject(rEPaM.nPara)->Len() >= rEPaM.nIndex, "CreateEditPaM: invalid Index");
        return EditPaM(maEditDoc.GetObject(rEPaM.nPara), rEPaM.nIndex);
    }

    ESelection CreateESel(const EditSelection& rSel) const
    {
        ESelection aESel;
        aESel.start = CreateEPaM(rSel.Min());
        aESel.end = CreateEPaM(rSel.Max());
        return aESel;
    }

    EditSelection CreateSel(const ESelection& rSel)
    {
        DBG_ASSERT( rSel.start.nPara < maEditDoc.Count(), "CreateSel: invalid start paragraph" );
        DBG_ASSERT( rSel.end.nPara < maEditDoc.Count(), "CreateSel: invalid end paragraph" );
        EditSelection aSel(CreateEditPaM(rSel.start), CreateEditPaM(rSel.end));
        DBG_ASSERT( !aSel.DbgIsBuggy( maEditDoc ), "CreateSel: incorrect selection!" );
        return aSel;
    }

    EditSelection CreateNormalizedSel(const ESelection& rSel)
    {
        return ConvertSelection(rSel.start.nPara, rSel.start.nIndex, rSel.end.nPara, rSel.end.nIndex);
    }

    void                SetStyleSheetPool( SfxStyleSheetPool* pSPool );
    SfxStyleSheetPool*  GetStyleSheetPool() const { return mpStylePool; }

    void                SetStyleSheet( EditSelection aSel, SfxStyleSheet* pStyle );
    void                SetStyleSheet( sal_Int32 nPara, SfxStyleSheet* pStyle );
    const SfxStyleSheet* GetStyleSheet( sal_Int32 nPara ) const;
    SfxStyleSheet*      GetStyleSheet( sal_Int32 nPara );

    void                UpdateParagraphsWithStyleSheet( SfxStyleSheet* pStyle );
    void                RemoveStyleFromParagraphs( SfxStyleSheet const * pStyle );

    bool isUsedByModel() const override { return true; }

    OutputDevice*       GetRefDevice() const { return mpRefDev.get(); }
    void                SetRefDevice(OutputDevice* mpRefDef);

    const MapMode&      GetRefMapMode() const { return mpRefDev->GetMapMode(); }
    void                SetRefMapMode(const MapMode& rMapMode);

    void SetControlWord( EEControlBits nWord );
    InternalEditStatus& GetStatus() { return maStatus; }
    InternalEditStatus const& GetStatus() constreturn maStatus; }

    void                CallStatusHdl();
    void                DelayedCallStatusHdl()  { maStatusTimer.Start(); }

    void                UndoActionStart( sal_uInt16 nId );
    void                UndoActionStart( sal_uInt16 nId, const ESelection& rSel );
    void                UndoActionEnd();

    EditView*           GetActiveView() const   { return mpActiveView; }
    void                SetActiveView( EditView* pView );

    css::uno::Reference< css::linguistic2::XSpellChecker1 > const &
                        GetSpeller();
    void                SetSpeller( css::uno::Reference< css::linguistic2::XSpellChecker1 > const &xSpl )
                            { mxSpeller = xSpl; }
    const css::uno::Reference< css::linguistic2::XHyphenator >&
                        GetHyphenator() const { return mxHyphenator; }
    void                SetHyphenator( css::uno::Reference< css::linguistic2::XHyphenator > const &xHyph )
                            { mxHyphenator = xHyph; }

    void GetAllMisspellRanges( std::vector<editeng::MisspellRanges>& rRanges ) const;
    void SetAllMisspellRanges( const std::vector<editeng::MisspellRanges>& rRanges );

    SpellInfo*          GetSpellInfo() const { return mpSpellInfo.get(); }

    void SetDefaultLanguage(LanguageType eLang) { meDefLanguage = eLang; }
    LanguageType GetDefaultLanguage() const { return meDefLanguage; }

    editeng::LanguageSpan GetLanguage( sal_Int32 nPara, sal_Int32 nPos );
    editeng::LanguageSpan GetLanguage( const EditPaM& rPaM, sal_Int32* pEndPos = nullptr const;
    css::lang::Locale   GetLocale( const EditPaM& rPaM ) const;

    void DoOnlineSpelling( ContentNode* pThisNodeOnly = nullptr, bool bSpellAtCursorPos = falsebool bInterruptible = true );
    EESpellState        Spell(EditView* pEditView, weld::Widget* pDialogParent, bool bMultipleDoc);
    EESpellState        HasSpellErrors();
    void                ClearSpellErrors();
    EESpellState        StartThesaurus(EditView* pEditView, weld::Widget* pDialogParent);
    css::uno::Reference< css::linguistic2::XSpellAlternatives >
                        ImpSpell( EditView* pEditView );

    // text conversion functions
    void                Convert(EditView* pEditView, weld::Widget* pDialogParent, LanguageType nSrcLang, LanguageType nDestLang, const vcl::Font *pDestFont, sal_Int32 nOptions, bool bIsInteractive, bool bMultipleDoc);
    void                ImpConvert( OUString &rConvTxt, LanguageType &rConvTxtLang, EditView* pEditView, LanguageType nSrcLang, const ESelection &rConvRange,
                                    bool bAllowImplicitChangesForNotConvertibleText, LanguageType nTargetLang, const vcl::Font *pTargetFont );
    ConvInfo *          GetConvInfo() const { return mpConvInfo.get(); }
    bool                HasConvertibleTextPortion( LanguageType nLang );
    void                SetLanguageAndFont( const ESelection &rESel,
                                LanguageType nLang, sal_uInt16 nLangWhichId,
                                const vcl::Font *pFont,  sal_uInt16 nFontWhichId );

    // returns true if input sequence checking should be applied
    bool                IsInputSequenceCheckingRequired( sal_Unicode nChar, const EditSelection& rCurSel ) const;

    //find the next error within the given selection - forward only!
    css::uno::Reference< css::linguistic2::XSpellAlternatives >
                        ImpFindNextError(EditSelection& rSelection);
    //spell and return a sentence
    bool                SpellSentence(EditView const & rView, svx::SpellPortions& rToFill );
    //put spelling back to start of current sentence - needed after switch of grammar support
    void                PutSpellingToSentenceStart( EditView const & rEditView );
    //applies a changed sentence
    void                ApplyChangedSentence(EditView const & rEditView, const svx::SpellPortions& ;rNewPortions, bool bRecheck );
    //adds one or more portions of text to the SpellPortions depending on language changes
    void                AddPortionIterated(
                          EditView const & rEditView,
                          const EditSelection &rSel,
                          const css::uno::Reference< css::linguistic2::XSpellAlternatives >& xAlt,
                          svx::SpellPortions& rToFill);
    //adds one portion to the SpellPortions
    void                AddPortion(
                            const EditSelection &rSel,
                            const css::uno::Reference< css::linguistic2::XSpellAlternatives >& xAlt,
                            svx::SpellPortions& rToFill,
                            bool bIsField );

    bool                    Search( const SvxSearchItem& rSearchItem, EditView* pView );
    bool                    ImpSearch( const SvxSearchItem& rSearchItem, const EditSelection& rSearchSelection, const EditPaM& rStartPos, EditSelection& rFoundSel );
    sal_Int32               StartSearchAndReplace( EditView* pEditView, const SvxSearchItem& rSearchItem );
    bool                    HasText( const SvxSearchItem& rSearchItem );

    void                    SetEditTextObjectPool( SfxItemPool* pP )    { mpTextObjectPool = pP; }
    SfxItemPool*            GetEditTextObjectPool() const               { return mpTextObjectPool; }

    const SvxNumberFormat * GetNumberFormat( const ContentNode* pNode ) const;
    sal_Int32               GetSpaceBeforeAndMinLabelWidth( const ContentNode *pNode, sal_Int32 *pnSpaceBefore = nullptr, sal_Int32 *pnMinLabelWidth = nullptr ) const;

    const SvxLRSpaceItem&   GetLRSpaceItem( ContentNode* pNode );
    SvxAdjust               GetJustification( sal_Int32 nPara ) const;
    SvxCellJustifyMethod    GetJustifyMethod( sal_Int32 nPara ) const;
    SvxCellVerJustify       GetVerJustification( sal_Int32 nPara ) const;
    SvxFontUnitMetrics GetFontUnitMetrics(ContentNode* pNode);

    void setScalingParameters(ScalingParameters const& rScalingParameters);

    const ScalingParameters & getScalingParameters()
    {
        return maScalingParameters;
    }

    sal_Int32 GetBigTextObjectStart() const { return mnBigTextObjectStart; }

    EditEngine*  GetEditEnginePtr() const    { return mpEditEngine; }

    void                StartOnlineSpellTimer()     { maOnlineSpellTimer.Start(); }
    void                StopOnlineSpellTimer()      { maOnlineSpellTimer.Stop(); }

    const OUString& GetAutoCompleteText() const { return maAutoCompleteText; }
    void                SetAutoCompleteText(const OUString& rStr, bool bUpdateTipWindow);

    EditSelection       TransliterateText( const EditSelection& rSelection, TransliterationFlags nTransliterationMode );
    short               ReplaceTextOnly( ContentNode* pNode, sal_Int32 nCurrentStart, std::u16string_view rText, const css::uno::Sequence< sal_Int32 >& rOffsets );

    void                SetAsianCompressionMode( CharCompressType n );
    CharCompressType    GetAsianCompressionMode() const { return mnAsianCompressionMode; }

    void                SetKernAsianPunctuation( bool b );
    bool                IsKernAsianPunctuation() const { return mbKernAsianPunctuation; }

    sal_Int32 GetOverflowingParaNum() const { return mnOverflowingPara; }
    sal_Int32 GetOverflowingLineNum() const { return mnOverflowingLine; }
    void ClearOverflowingParaNum() { mnOverflowingPara = -1; }


    void                SetAddExtLeading( bool b );
    bool IsAddExtLeading() const { return mbAddExtLeading; }

    static std::shared_ptr<SvxForbiddenCharactersTable> const & GetForbiddenCharsTable();
    static void         SetForbiddenCharsTable( const std::shared_ptr<SvxForbiddenCharactersTable>&&nbsp;xForbiddenChars );

    /** sets a link that is called at the beginning of a drag operation at an edit view */
    void                SetBeginDropHdl( const Link<EditView*,void>& rLink ) { maBeginDropHdl = rLink; }
    const Link<EditView*,void>&  GetBeginDropHdl() const { return maBeginDropHdl; }

    /** sets a link that is called at the end of a drag operation at an edit view */
    void            SetEndDropHdl( const Link<EditView*,void>& rLink ) { maEndDropHdl = rLink; }
    const Link<EditView*,void>&  GetEndDropHdl() const { return maEndDropHdl; }

    /// specifies if auto-correction should capitalize the first word or not (default is on)
    void SetFirstWordCapitalization( bool bCapitalize ) { mbFirstWordCapitalization = bCapitalize; }
    bool IsFirstWordCapitalization() const { return mbFirstWordCapitalization; }

    /** specifies if auto-correction should replace a leading single quotation
        mark (apostrophe) or not (default is on) */

    void            SetReplaceLeadingSingleQuotationMark( bool bReplace ) { mbReplaceLeadingSingleQuotationMark = bReplace; }
    bool            IsReplaceLeadingSingleQuotationMark() const { return mbReplaceLeadingSingleQuotationMark; }

    /** Whether last AutoCorrect inserted a NO-BREAK SPACE that may need to be removed again. */
    bool            IsNbspRunNext() const { return mbNbspRunNext; }

    void EnableSkipOutsideFormat(bool set) { mbSkipOutsideFormat = set; }

    void Dispose();
    void SetLOKSpecialPaperSize(const Size& rSize) { maLOKSpecialPaperSize = rSize; }
    const Size& GetLOKSpecialPaperSize() const { return maLOKSpecialPaperSize; }

    enum class CallbackResult
    {
        Continue,
        SkipThisPortion, // Do not call callback until next portion
        Stop, // Stop iteration
    };
    struct LineAreaInfo
    {
        ParaPortion& rPortion; // Current ParaPortion
        EditLine* pLine; // Current line, or nullptr for paragraph start
        tools::Long nHeightNeededToNotWrap;
        tools::Rectangle aArea; // The area for the line (or for rPortion's first line offset)
                                // Bottom coordinate *does not* belong to the area
        sal_Int32 nPortion;
        sal_Int32 nLine;
        sal_Int16 nColumn; // Column number; when overflowing, equal to total number of columns
    };
    using IterateLinesAreasFunc = std::function<CallbackResult(const LineAreaInfo&)>;
    enum IterFlag // bitmask
    {
        none = 0,
        inclILS = 1, // rArea includes interline space
    };

    void IterateLineAreas(const IterateLinesAreasFunc& f, IterFlag eOptions);

    tools::Long GetColumnWidth(const Size& rPaperSize) const;
    Point MoveToNextLine(Point& rMovePos, tools::Long nLineHeight, sal_Int16& nColumn,
                         Point aOrigin, tools::Long* pnHeightNeededToNotWrap = nullptr) const;

    tools::Long getWidthDirectionAware(const Size& sz) const;
    tools::Long getHeightDirectionAware(const Size& sz) const;
    void adjustXDirectionAware(Point& pt, tools::Long x) const;
    void adjustYDirectionAware(Point& pt, tools::Long y) const;
    void setXDirectionAwareFrom(Point& ptDest, const Point& ptSrc) const;
    void setYDirectionAwareFrom(Point& ptDest, const Point& ptSrc) const;
    tools::Long getYOverflowDirectionAware(const Point& pt, const tools::Rectangle&&nbsp;rectMax) const;
    bool isXOverflowDirectionAware(const Point& pt, const tools::Rectangle& rectMax) const;
    // Offset of the rectangle's direction-aware corners in document coordinates
    tools::Long getBottomDocOffset(const tools::Rectangle& rect) const;
    Size getTopLeftDocOffset(const tools::Rectangle& rect) const;

    void SetDefTab( sal_uInt16 nDefTab );

    bool PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, vcl::Window const * pFrameWin );
    static bool IsSimpleCharInput( const KeyEvent& rKeyEvent );
    void RemoveParagraph( sal_Int32 nPara );

#ifdef DBG_UTIL
    void DumpData(bool bInfoBox);
#endif
#if defined( DBG_UTIL ) || (OSL_DEBUG_LEVEL > 1)
    static bool bDebugPaint;
#endif
};

void ConvertItem( std::unique_ptr<SfxPoolItem>& rPoolItem, MapUnit eSourceUnit, MapUnit eDestUnit );
void ConvertAndPutItems( SfxItemSet& rDest, const SfxItemSet& rSource, const MapUnit* pSourceUnit = nullptr, const MapUnit* pDestUnit = nullptr );
AsianCompressionFlags GetCharTypeForCompression( sal_Unicode cChar );


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=90 H=100 G=95

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge