1cfa72a831
Before commit 653b53287c
, editengine
objects had a pair IsVertical/SetVertical, which queried and set
a boolean flag (and SetVertical also had a second argument to set
another flag).
The mentioned commit had introduced an inconsistency, changing
SetVertical to only set a single flag, but at the same time making
IsVertical to return a synthesized result from two values: vertical
and rotation. Additionally, GetDirectVertical was introduced to
complement SetVertical.
In many places, the use of synthetic IsVertical looks suspicious,
especially where it is used in combinations with SetVertical. But
here I don't change existing logic, and only rename the methods,
so that in case someone sees an actual problem, it would be easier
to spot the method mismatch.
The end result is that now we have a proper getter/setter pair
GetVertical/SetVertical, and also IsEffectivelyVertical, named to
reflect that it calculates its return value.
Change-Id: I38e2b7c5bd7af0787dd7a1c48e1385138dac80b1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119315
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
831 lines
27 KiB
C++
831 lines
27 KiB
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 "editattr.hxx"
|
|
#include "edtspell.hxx"
|
|
#include "eerdll2.hxx"
|
|
#include <editeng/svxfont.hxx>
|
|
#include <svl/itemset.hxx>
|
|
#include <svl/style.hxx>
|
|
#include <svl/itempool.hxx>
|
|
#include <svl/languageoptions.hxx>
|
|
#include <tools/lineend.hxx>
|
|
#include <o3tl/typed_flags_set.hxx>
|
|
|
|
#include <memory>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
class ImpEditEngine;
|
|
class SvxTabStop;
|
|
enum class TextRotation;
|
|
|
|
|
|
#define CHARPOSGROW 16
|
|
#define DEFTAB 720
|
|
|
|
void CreateFont( SvxFont& rFont, const SfxItemSet& rSet, bool bSearchInParent = true, SvtScriptType nScriptType = SvtScriptType::NONE );
|
|
sal_uInt16 GetScriptItemId( sal_uInt16 nItemId, SvtScriptType nScriptType );
|
|
bool IsScriptItemValid( sal_uInt16 nItemId, short nScriptType );
|
|
|
|
EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const SfxPoolItem& rAttr, sal_Int32 nS, sal_Int32 nE );
|
|
|
|
class ContentNode;
|
|
class EditDoc;
|
|
|
|
struct EPaM
|
|
{
|
|
sal_Int32 nPara;
|
|
sal_Int32 nIndex;
|
|
|
|
EPaM() : nPara(0), nIndex(0) {}
|
|
EPaM( sal_Int32 nP, sal_Int32 nI ) : nPara(nP), nIndex(nI) {}
|
|
EPaM( const EPaM& r) : nPara(r.nPara), nIndex(r.nIndex) {}
|
|
EPaM& operator = ( const EPaM& r ) { nPara = r.nPara; nIndex = r.nIndex; return *this; }
|
|
inline bool operator == ( const EPaM& r ) const;
|
|
inline bool operator < ( const EPaM& r ) const;
|
|
};
|
|
|
|
inline bool EPaM::operator < ( const EPaM& r ) const
|
|
{
|
|
return ( nPara < r.nPara ) || ( ( nPara == r.nPara ) && nIndex < r.nIndex );
|
|
}
|
|
|
|
inline bool EPaM::operator == ( const EPaM& r ) const
|
|
{
|
|
return ( nPara == r.nPara ) && ( nIndex == r.nIndex );
|
|
}
|
|
|
|
struct ScriptTypePosInfo
|
|
{
|
|
short nScriptType;
|
|
sal_Int32 nStartPos;
|
|
sal_Int32 nEndPos;
|
|
|
|
ScriptTypePosInfo( short Type, sal_Int32 Start, sal_Int32 End )
|
|
: nScriptType(Type)
|
|
, nStartPos(Start)
|
|
, nEndPos(End)
|
|
{
|
|
}
|
|
};
|
|
|
|
typedef std::vector<ScriptTypePosInfo> ScriptTypePosInfos;
|
|
|
|
struct WritingDirectionInfo
|
|
{
|
|
sal_uInt8 nType;
|
|
sal_Int32 nStartPos;
|
|
sal_Int32 nEndPos;
|
|
|
|
WritingDirectionInfo( sal_uInt8 Type, sal_Int32 Start, sal_Int32 End )
|
|
: nType(Type)
|
|
, nStartPos(Start)
|
|
, nEndPos(End)
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
typedef std::vector<WritingDirectionInfo> WritingDirectionInfos;
|
|
|
|
class ContentAttribsInfo
|
|
{
|
|
private:
|
|
typedef std::vector<std::unique_ptr<EditCharAttrib> > CharAttribsType;
|
|
|
|
SfxItemSet aPrevParaAttribs;
|
|
CharAttribsType aPrevCharAttribs;
|
|
|
|
public:
|
|
ContentAttribsInfo( const SfxItemSet& rParaAttribs );
|
|
|
|
const SfxItemSet& GetPrevParaAttribs() const { return aPrevParaAttribs; }
|
|
const CharAttribsType& GetPrevCharAttribs() const { return aPrevCharAttribs; }
|
|
|
|
void RemoveAllCharAttribsFromPool(SfxItemPool& rPool) const;
|
|
void AppendCharAttrib(EditCharAttrib* pNew);
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<Color> SvxColorList;
|
|
|
|
|
|
|
|
|
|
class ItemList
|
|
{
|
|
private:
|
|
typedef std::vector<const SfxPoolItem*> DummyItemList;
|
|
DummyItemList aItemPool;
|
|
sal_Int32 CurrentItem;
|
|
|
|
public:
|
|
ItemList();
|
|
const SfxPoolItem* First();
|
|
const SfxPoolItem* Next();
|
|
sal_Int32 Count() { return aItemPool.size(); };
|
|
void Insert( const SfxPoolItem* pItem );
|
|
void Clear() { aItemPool.clear(); };
|
|
};
|
|
|
|
|
|
|
|
class ContentAttribs
|
|
{
|
|
private:
|
|
SfxStyleSheet* pStyle;
|
|
SfxItemSet aAttribSet;
|
|
|
|
public:
|
|
ContentAttribs( SfxItemPool& rItemPool );
|
|
|
|
void dumpAsXml(xmlTextWriterPtr pWriter) const;
|
|
|
|
SvxTabStop FindTabStop( sal_Int32 nCurPos, sal_uInt16 nDefTab );
|
|
SfxItemSet& GetItems() { return aAttribSet; }
|
|
const SfxItemSet& GetItems() const { return aAttribSet; }
|
|
const SfxStyleSheet* GetStyleSheet() const { return pStyle; }
|
|
SfxStyleSheet* GetStyleSheet() { return pStyle; }
|
|
void SetStyleSheet( SfxStyleSheet* pS );
|
|
|
|
const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const;
|
|
template<class T>
|
|
const T& GetItem( TypedWhichId<T> nWhich ) const
|
|
{
|
|
return static_cast<const T&>(GetItem(sal_uInt16(nWhich)));
|
|
}
|
|
bool HasItem( sal_uInt16 nWhich ) const;
|
|
};
|
|
|
|
|
|
|
|
class CharAttribList
|
|
{
|
|
public:
|
|
typedef std::vector<std::unique_ptr<EditCharAttrib> > AttribsType;
|
|
|
|
private:
|
|
AttribsType aAttribs;
|
|
SvxFont aDefFont; // faster than ever from the pool!
|
|
bool bHasEmptyAttribs;
|
|
|
|
public:
|
|
CharAttribList();
|
|
~CharAttribList();
|
|
|
|
void dumpAsXml(xmlTextWriterPtr pWriter) const;
|
|
|
|
void DeleteEmptyAttribs( SfxItemPool& rItemPool );
|
|
|
|
const EditCharAttrib* FindAttrib( sal_uInt16 nWhich, sal_Int32 nPos ) const;
|
|
EditCharAttrib* FindAttrib( sal_uInt16 nWhich, sal_Int32 nPos );
|
|
const EditCharAttrib* FindNextAttrib( sal_uInt16 nWhich, sal_Int32 nFromPos ) const;
|
|
EditCharAttrib* FindEmptyAttrib( sal_uInt16 nWhich, sal_Int32 nPos );
|
|
const EditCharAttrib* FindFeature( sal_Int32 nPos ) const;
|
|
|
|
|
|
void ResortAttribs();
|
|
void OptimizeRanges( SfxItemPool& rItemPool );
|
|
|
|
sal_Int32 Count() const;
|
|
|
|
void InsertAttrib( EditCharAttrib* pAttrib );
|
|
|
|
SvxFont& GetDefFont() { return aDefFont; }
|
|
|
|
bool HasEmptyAttribs() const { return bHasEmptyAttribs; }
|
|
void SetHasEmptyAttribs(bool b);
|
|
bool HasBoundingAttrib( sal_Int32 nBound ) const;
|
|
bool HasAttrib( sal_Int32 nStartPos, sal_Int32 nEndPos ) const;
|
|
|
|
AttribsType& GetAttribs() { return aAttribs;}
|
|
const AttribsType& GetAttribs() const { return aAttribs;}
|
|
|
|
void Remove(const EditCharAttrib* p);
|
|
void Remove(sal_Int32 nPos);
|
|
|
|
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
|
|
static void DbgCheckAttribs(CharAttribList const& rAttribs);
|
|
#endif
|
|
};
|
|
|
|
|
|
|
|
class ContentNode
|
|
{
|
|
private:
|
|
OUString maString;
|
|
ContentAttribs aContentAttribs;
|
|
CharAttribList aCharAttribList;
|
|
std::unique_ptr<WrongList> mpWrongList;
|
|
|
|
void UnExpandPosition( sal_Int32 &rStartPos, bool bBiasStart );
|
|
|
|
public:
|
|
ContentNode( SfxItemPool& rItemPool );
|
|
ContentNode( const OUString& rStr, const ContentAttribs& rContentAttribs );
|
|
~ContentNode();
|
|
ContentNode(const ContentNode&) = delete;
|
|
ContentNode& operator=(const ContentNode&) = delete;
|
|
|
|
void dumpAsXml(xmlTextWriterPtr pWriter) const;
|
|
|
|
ContentAttribs& GetContentAttribs() { return aContentAttribs; }
|
|
const ContentAttribs& GetContentAttribs() const { return aContentAttribs; }
|
|
CharAttribList& GetCharAttribs() { return aCharAttribList; }
|
|
const CharAttribList& GetCharAttribs() const { return aCharAttribList; }
|
|
|
|
void ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNewChars, SfxItemPool& rItemPool );
|
|
void CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDelChars, SfxItemPool& rItemPool );
|
|
void AppendAttribs( ContentNode* pNextNode );
|
|
void CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool, bool bKeepEndingAttribs );
|
|
|
|
void SetStyleSheet( SfxStyleSheet* pS, bool bRecalcFont = true );
|
|
void SetStyleSheet( SfxStyleSheet* pS, const SvxFont& rFontFromStyle );
|
|
SfxStyleSheet* GetStyleSheet() { return aContentAttribs.GetStyleSheet(); }
|
|
|
|
void CreateDefFont();
|
|
|
|
void EnsureWrongList();
|
|
WrongList* GetWrongList();
|
|
const WrongList* GetWrongList() const;
|
|
void SetWrongList( WrongList* p );
|
|
|
|
void CreateWrongList();
|
|
void DestroyWrongList();
|
|
|
|
bool IsFeature( sal_Int32 nPos ) const;
|
|
|
|
sal_Int32 Len() const;
|
|
const OUString& GetString() const { return maString;}
|
|
|
|
/// return length including expanded fields
|
|
sal_uLong GetExpandedLen() const;
|
|
/// return content including expanded fields
|
|
OUString GetExpandedText(sal_Int32 nStartPos = 0, sal_Int32 nEndPos = -1) const;
|
|
/// re-write offsets in the expanded text to string offsets
|
|
void UnExpandPositions( sal_Int32 &rStartPos, sal_Int32 &rEndPos );
|
|
|
|
void SetChar(sal_Int32 nPos, sal_Unicode c);
|
|
void Insert(const OUString& rStr, sal_Int32 nPos);
|
|
void Append(std::u16string_view rStr);
|
|
void Erase(sal_Int32 nPos);
|
|
void Erase(sal_Int32 nPos, sal_Int32 nCount);
|
|
OUString Copy(sal_Int32 nPos) const;
|
|
OUString Copy(sal_Int32 nPos, sal_Int32 nCount) const;
|
|
sal_Unicode GetChar(sal_Int32 nPos) const;
|
|
};
|
|
|
|
|
|
|
|
class EditPaM
|
|
{
|
|
private:
|
|
ContentNode* pNode;
|
|
sal_Int32 nIndex;
|
|
|
|
public:
|
|
EditPaM();
|
|
EditPaM(ContentNode* p, sal_Int32 n);
|
|
|
|
const ContentNode* GetNode() const { return pNode;}
|
|
ContentNode* GetNode() { return pNode;}
|
|
void SetNode(ContentNode* p);
|
|
|
|
sal_Int32 GetIndex() const { return nIndex; }
|
|
void SetIndex( sal_Int32 n ) { nIndex = n; }
|
|
|
|
bool DbgIsBuggy( EditDoc const & rDoc ) const;
|
|
|
|
friend bool operator == ( const EditPaM& r1, const EditPaM& r2 );
|
|
friend bool operator != ( const EditPaM& r1, const EditPaM& r2 );
|
|
bool operator !() const { return !pNode && !nIndex; }
|
|
};
|
|
|
|
enum class PortionKind
|
|
{
|
|
TEXT = 0,
|
|
TAB = 1,
|
|
LINEBREAK = 2,
|
|
FIELD = 3,
|
|
HYPHENATOR = 4
|
|
};
|
|
|
|
enum class DeleteMode {
|
|
Simple, RestOfWord, RestOfContent
|
|
};
|
|
|
|
enum class AsianCompressionFlags {
|
|
Normal = 0x00,
|
|
Kana = 0x01,
|
|
PunctuationLeft = 0x02,
|
|
PunctuationRight = 0x04,
|
|
};
|
|
namespace o3tl {
|
|
template<> struct typed_flags<AsianCompressionFlags> : is_typed_flags<AsianCompressionFlags, 0x07> {};
|
|
}
|
|
|
|
|
|
|
|
// struct ExtraPortionInfos
|
|
|
|
struct ExtraPortionInfo
|
|
{
|
|
tools::Long nOrgWidth;
|
|
tools::Long nWidthFullCompression;
|
|
|
|
tools::Long nPortionOffsetX;
|
|
|
|
sal_uInt16 nMaxCompression100thPercent;
|
|
|
|
AsianCompressionFlags nAsianCompressionTypes;
|
|
bool bFirstCharIsRightPunktuation;
|
|
bool bCompressed;
|
|
|
|
std::unique_ptr<tools::Long[]> pOrgDXArray;
|
|
std::vector< sal_Int32 > lineBreaksList;
|
|
|
|
|
|
ExtraPortionInfo();
|
|
~ExtraPortionInfo();
|
|
|
|
void SaveOrgDXArray( const tools::Long* pDXArray, sal_Int32 nLen );
|
|
};
|
|
|
|
|
|
|
|
class TextPortion
|
|
{
|
|
private:
|
|
std::unique_ptr<ExtraPortionInfo> xExtraInfos;
|
|
sal_Int32 nLen;
|
|
Size aOutSz;
|
|
PortionKind nKind;
|
|
sal_uInt8 nRightToLeftLevel;
|
|
sal_Unicode nExtraValue;
|
|
|
|
|
|
public:
|
|
TextPortion( sal_Int32 nL )
|
|
: nLen( nL )
|
|
, aOutSz( -1, -1 )
|
|
, nKind( PortionKind::TEXT )
|
|
, nRightToLeftLevel( 0 )
|
|
, nExtraValue( 0 )
|
|
{
|
|
}
|
|
|
|
TextPortion( const TextPortion& r )
|
|
: nLen( r.nLen )
|
|
, aOutSz( r.aOutSz )
|
|
, nKind( r.nKind )
|
|
, nRightToLeftLevel( r.nRightToLeftLevel )
|
|
, nExtraValue( r.nExtraValue )
|
|
{
|
|
}
|
|
|
|
|
|
sal_Int32 GetLen() const { return nLen; }
|
|
void SetLen( sal_Int32 nL ) { nLen = nL; }
|
|
|
|
Size& GetSize() { return aOutSz; }
|
|
const Size& GetSize() const { return aOutSz; }
|
|
|
|
void SetKind(PortionKind n) { nKind = n; }
|
|
PortionKind GetKind() const { return nKind; }
|
|
|
|
void SetRightToLeftLevel( sal_uInt8 n ) { nRightToLeftLevel = n; }
|
|
sal_uInt8 GetRightToLeftLevel() const { return nRightToLeftLevel; }
|
|
bool IsRightToLeft() const { return (nRightToLeftLevel&1); }
|
|
|
|
sal_Unicode GetExtraValue() const { return nExtraValue; }
|
|
void SetExtraValue( sal_Unicode n ) { nExtraValue = n; }
|
|
|
|
ExtraPortionInfo* GetExtraInfos() const { return xExtraInfos.get(); }
|
|
void SetExtraInfos( ExtraPortionInfo* p ) { xExtraInfos.reset(p); }
|
|
};
|
|
|
|
|
|
|
|
class TextPortionList
|
|
{
|
|
typedef std::vector<std::unique_ptr<TextPortion> > PortionsType;
|
|
PortionsType maPortions;
|
|
|
|
public:
|
|
TextPortionList();
|
|
~TextPortionList();
|
|
TextPortionList(TextPortionList&&) = default;
|
|
TextPortionList& operator=(TextPortionList&&) = default;
|
|
|
|
void Reset();
|
|
sal_Int32 FindPortion(
|
|
sal_Int32 nCharPos, sal_Int32& rPortionStart, bool bPreferStartingPortion = false) const;
|
|
sal_Int32 GetStartPos(sal_Int32 nPortion);
|
|
void DeleteFromPortion(sal_Int32 nDelFrom);
|
|
sal_Int32 Count() const;
|
|
const TextPortion& operator[](sal_Int32 nPos) const;
|
|
TextPortion& operator[](sal_Int32 nPos);
|
|
|
|
void Append(TextPortion* p);
|
|
void Insert(sal_Int32 nPos, TextPortion* p);
|
|
void Remove(sal_Int32 nPos);
|
|
sal_Int32 GetPos(const TextPortion* p) const;
|
|
};
|
|
|
|
class ParaPortion;
|
|
|
|
|
|
|
|
class EditLine
|
|
{
|
|
public:
|
|
typedef std::vector<tools::Long> CharPosArrayType;
|
|
|
|
private:
|
|
CharPosArrayType aPositions;
|
|
tools::Long nTxtWidth;
|
|
tools::Long nStartPosX;
|
|
sal_Int32 nStart; // could be replaced by nStartPortion
|
|
sal_Int32 nEnd; // could be replaced by nEndPortion
|
|
sal_Int32 nStartPortion;
|
|
sal_Int32 nEndPortion;
|
|
sal_uInt16 nHeight; // Total height of the line
|
|
sal_uInt16 nTxtHeight; // Pure Text height
|
|
sal_uInt16 nMaxAscent;
|
|
bool bHangingPunctuation:1;
|
|
bool bInvalid:1; // for skillful formatting
|
|
|
|
public:
|
|
EditLine();
|
|
|
|
bool IsIn( sal_Int32 nIndex ) const
|
|
{ return ( (nIndex >= nStart ) && ( nIndex < nEnd ) ); }
|
|
|
|
bool IsIn( sal_Int32 nIndex, bool bInclEnd ) const
|
|
{ return ( ( nIndex >= nStart ) && ( bInclEnd ? ( nIndex <= nEnd ) : ( nIndex < nEnd ) ) ); }
|
|
|
|
void SetStart( sal_Int32 n ) { nStart = n; }
|
|
sal_Int32 GetStart() const { return nStart; }
|
|
sal_Int32& GetStart() { return nStart; }
|
|
|
|
void SetEnd( sal_Int32 n ) { nEnd = n; }
|
|
sal_Int32 GetEnd() const { return nEnd; }
|
|
sal_Int32& GetEnd() { return nEnd; }
|
|
|
|
void SetStartPortion( sal_Int32 n ) { nStartPortion = n; }
|
|
sal_Int32 GetStartPortion() const { return nStartPortion; }
|
|
sal_Int32& GetStartPortion() { return nStartPortion; }
|
|
|
|
void SetEndPortion( sal_Int32 n ) { nEndPortion = n; }
|
|
sal_Int32 GetEndPortion() const { return nEndPortion; }
|
|
sal_Int32& GetEndPortion() { return nEndPortion; }
|
|
|
|
void SetHeight( sal_uInt16 nH, sal_uInt16 nTxtH = 0 );
|
|
sal_uInt16 GetHeight() const { return nHeight; }
|
|
sal_uInt16 GetTxtHeight() const { return nTxtHeight; }
|
|
|
|
void SetTextWidth( tools::Long n ) { nTxtWidth = n; }
|
|
tools::Long GetTextWidth() const { return nTxtWidth; }
|
|
|
|
void SetMaxAscent( sal_uInt16 n ) { nMaxAscent = n; }
|
|
sal_uInt16 GetMaxAscent() const { return nMaxAscent; }
|
|
|
|
void SetHangingPunctuation( bool b ) { bHangingPunctuation = b; }
|
|
bool IsHangingPunctuation() const { return bHangingPunctuation; }
|
|
|
|
sal_Int32 GetLen() const { return nEnd - nStart; }
|
|
|
|
tools::Long GetStartPosX() const { return nStartPosX; }
|
|
void SetStartPosX( tools::Long start );
|
|
Size CalcTextSize( ParaPortion& rParaPortion );
|
|
|
|
bool IsInvalid() const { return bInvalid; }
|
|
bool IsValid() const { return !bInvalid; }
|
|
void SetInvalid() { bInvalid = true; }
|
|
void SetValid() { bInvalid = false; }
|
|
|
|
bool IsEmpty() const { return nEnd <= nStart; }
|
|
|
|
CharPosArrayType& GetCharPosArray() { return aPositions;}
|
|
const CharPosArrayType& GetCharPosArray() const { return aPositions;}
|
|
|
|
EditLine* Clone() const;
|
|
|
|
friend bool operator == ( const EditLine& r1, const EditLine& r2 );
|
|
};
|
|
|
|
|
|
|
|
class EditLineList
|
|
{
|
|
typedef std::vector<std::unique_ptr<EditLine> > LinesType;
|
|
LinesType maLines;
|
|
|
|
public:
|
|
EditLineList();
|
|
~EditLineList();
|
|
EditLineList(EditLineList&&) = default;
|
|
EditLineList& operator=(EditLineList&&) = default;
|
|
|
|
void Reset();
|
|
void DeleteFromLine(sal_Int32 nDelFrom);
|
|
sal_Int32 FindLine(sal_Int32 nChar, bool bInclEnd);
|
|
sal_Int32 Count() const;
|
|
const EditLine& operator[](sal_Int32 nPos) const;
|
|
EditLine& operator[](sal_Int32 nPos);
|
|
|
|
void Append(EditLine* p);
|
|
void Insert(sal_Int32 nPos, EditLine* p);
|
|
};
|
|
|
|
|
|
|
|
class ParaPortion
|
|
{
|
|
friend class ImpEditEngine; // to adjust the height
|
|
private:
|
|
EditLineList aLineList;
|
|
TextPortionList aTextPortionList;
|
|
ContentNode* pNode;
|
|
tools::Long nHeight;
|
|
|
|
ScriptTypePosInfos aScriptInfos;
|
|
WritingDirectionInfos aWritingDirectionInfos;
|
|
|
|
sal_Int32 nInvalidPosStart;
|
|
sal_Int32 nFirstLineOffset; // For Writer-LineSpacing-Interpretation
|
|
sal_Int32 nBulletX;
|
|
sal_Int32 nInvalidDiff;
|
|
|
|
bool bInvalid : 1;
|
|
bool bSimple : 1; // only linear Tap
|
|
bool bVisible : 1; // Belongs to the node!
|
|
bool bForceRepaint : 1;
|
|
|
|
public:
|
|
ParaPortion( ContentNode* pNode );
|
|
~ParaPortion();
|
|
ParaPortion( ParaPortion&& ) = default;
|
|
ParaPortion& operator=( ParaPortion&& ) = default;
|
|
|
|
sal_Int32 GetLineNumber( sal_Int32 nIndex ) const;
|
|
|
|
EditLineList& GetLines() { return aLineList; }
|
|
const EditLineList& GetLines() const { return aLineList; }
|
|
|
|
bool IsInvalid() const { return bInvalid; }
|
|
bool IsSimpleInvalid() const { return bSimple; }
|
|
void SetValid() { bInvalid = false; bSimple = true;}
|
|
|
|
bool MustRepaint() const { return bForceRepaint; }
|
|
void SetMustRepaint( bool bRP ) { bForceRepaint = bRP; }
|
|
|
|
sal_Int32 GetBulletX() const { return nBulletX; }
|
|
void SetBulletX( sal_Int32 n ) { nBulletX = n; }
|
|
|
|
void MarkInvalid( sal_Int32 nStart, sal_Int32 nDiff);
|
|
void MarkSelectionInvalid( sal_Int32 nStart );
|
|
|
|
void SetVisible( bool bVisible );
|
|
bool IsVisible() const { return bVisible; }
|
|
|
|
bool IsEmpty() { return GetTextPortions().Count() == 1 && GetTextPortions()[0].GetLen() == 0; }
|
|
|
|
tools::Long GetHeight() const { return ( bVisible ? nHeight : 0 ); }
|
|
sal_Int32 GetFirstLineOffset() const { return ( bVisible ? nFirstLineOffset : 0 ); }
|
|
void ResetHeight() { nHeight = 0; nFirstLineOffset = 0; }
|
|
|
|
ContentNode* GetNode() const { return pNode; }
|
|
TextPortionList& GetTextPortions() { return aTextPortionList; }
|
|
const TextPortionList& GetTextPortions() const { return aTextPortionList; }
|
|
|
|
sal_Int32 GetInvalidPosStart() const { return nInvalidPosStart; }
|
|
short GetInvalidDiff() const { return nInvalidDiff; }
|
|
|
|
void CorrectValuesBehindLastFormattedLine( sal_Int32 nLastFormattedLine );
|
|
#if OSL_DEBUG_LEVEL > 0
|
|
static bool DbgCheckTextPortions(ParaPortion const&);
|
|
#endif
|
|
};
|
|
|
|
|
|
|
|
class ParaPortionList
|
|
{
|
|
mutable sal_Int32 nLastCache;
|
|
std::vector<ParaPortion> maPortions;
|
|
public:
|
|
ParaPortionList();
|
|
~ParaPortionList();
|
|
|
|
void Reset();
|
|
tools::Long GetYOffset(const ParaPortion* pPPortion) const;
|
|
sal_Int32 FindParagraph(tools::Long nYOffset) const;
|
|
|
|
const ParaPortion* SafeGetObject(sal_Int32 nPos) const;
|
|
ParaPortion* SafeGetObject(sal_Int32 nPos);
|
|
|
|
sal_Int32 GetPos(const ParaPortion* p) const;
|
|
ParaPortion& operator[](sal_Int32 nPos);
|
|
const ParaPortion& operator[](sal_Int32 nPos) const;
|
|
|
|
ParaPortion Remove(sal_Int32 nPos);
|
|
ParaPortion& Insert(sal_Int32 nPos, ParaPortion&& p);
|
|
void Append(ParaPortion&& p);
|
|
sal_Int32 Count() const;
|
|
|
|
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
|
|
// temporary:
|
|
static void DbgCheck(ParaPortionList const&, EditDoc const& rDoc);
|
|
#endif
|
|
};
|
|
|
|
|
|
|
|
class EditSelection
|
|
{
|
|
private:
|
|
EditPaM aStartPaM;
|
|
EditPaM aEndPaM;
|
|
|
|
public:
|
|
EditSelection(); // No constructor and destructor
|
|
// are automatically executed correctly!
|
|
EditSelection( const EditPaM& rStartAndAnd );
|
|
EditSelection( const EditPaM& rStart, const EditPaM& rEnd );
|
|
|
|
EditPaM& Min() { return aStartPaM; }
|
|
EditPaM& Max() { return aEndPaM; }
|
|
|
|
const EditPaM& Min() const { return aStartPaM; }
|
|
const EditPaM& Max() const { return aEndPaM; }
|
|
|
|
bool HasRange() const { return aStartPaM != aEndPaM; }
|
|
bool IsInvalid() const { return !aStartPaM || !aEndPaM; }
|
|
bool DbgIsBuggy( EditDoc const & rDoc ) const;
|
|
|
|
void Adjust( const EditDoc& rNodes );
|
|
|
|
EditSelection& operator = ( const EditPaM& r );
|
|
bool operator == ( const EditSelection& r ) const
|
|
{ return ( aStartPaM == r.aStartPaM ) && ( aEndPaM == r.aEndPaM ); }
|
|
bool operator != ( const EditSelection& r ) const { return !( r == *this ); }
|
|
};
|
|
|
|
|
|
|
|
class DeletedNodeInfo
|
|
{
|
|
private:
|
|
ContentNode* mpInvalidNode;
|
|
sal_Int32 nInvalidParagraph;
|
|
|
|
public:
|
|
DeletedNodeInfo( ContentNode* pNode, sal_Int32 nPos )
|
|
: mpInvalidNode(pNode)
|
|
, nInvalidParagraph(nPos)
|
|
{
|
|
}
|
|
|
|
ContentNode* GetNode() const { return mpInvalidNode; }
|
|
sal_Int32 GetPosition() const { return nInvalidParagraph; }
|
|
};
|
|
|
|
|
|
|
|
class EditDoc
|
|
{
|
|
private:
|
|
mutable sal_Int32 nLastCache;
|
|
std::vector<std::unique_ptr<ContentNode> > maContents;
|
|
|
|
rtl::Reference<SfxItemPool> pItemPool;
|
|
Link<LinkParamNone*,void> aModifyHdl;
|
|
|
|
SvxFont aDefFont; //faster than ever from the pool!!
|
|
sal_uInt16 nDefTab;
|
|
bool bIsVertical:1;
|
|
TextRotation mnRotation;
|
|
bool bIsFixedCellHeight:1;
|
|
|
|
bool bModified:1;
|
|
bool bDisableAttributeExpanding:1;
|
|
|
|
private:
|
|
void ImplDestroyContents();
|
|
|
|
public:
|
|
EditDoc( SfxItemPool* pItemPool );
|
|
~EditDoc();
|
|
|
|
void dumpAsXml(xmlTextWriterPtr pWriter) const;
|
|
void ClearSpellErrors();
|
|
|
|
bool IsModified() const { return bModified; }
|
|
void SetModified( bool b );
|
|
|
|
void DisableAttributeExpanding() { bDisableAttributeExpanding = true; }
|
|
|
|
void SetModifyHdl( const Link<LinkParamNone*,void>& rLink ) { aModifyHdl = rLink; }
|
|
|
|
void CreateDefFont( bool bUseStyles );
|
|
const SvxFont& GetDefFont() const { return aDefFont; }
|
|
|
|
void SetDefTab( sal_uInt16 nTab ) { nDefTab = nTab ? nTab : DEFTAB; }
|
|
sal_uInt16 GetDefTab() const { return nDefTab; }
|
|
|
|
void SetVertical( bool bVertical ) { bIsVertical = bVertical; }
|
|
bool IsEffectivelyVertical() const;
|
|
bool IsTopToBottom() const;
|
|
bool GetVertical() const;
|
|
void SetRotation( TextRotation nRotation ) { mnRotation = nRotation; }
|
|
TextRotation GetRotation() const { return mnRotation; }
|
|
|
|
void SetFixedCellHeight( bool bUseFixedCellHeight ) { bIsFixedCellHeight = bUseFixedCellHeight; }
|
|
bool IsFixedCellHeight() const { return bIsFixedCellHeight; }
|
|
|
|
EditPaM Clear();
|
|
EditPaM RemoveText();
|
|
void RemoveChars( EditPaM aPaM, sal_Int32 nChars );
|
|
EditPaM InsertText( EditPaM aPaM, const OUString& rStr );
|
|
EditPaM InsertParaBreak( EditPaM aPaM, bool bKeepEndingAttribs );
|
|
EditPaM InsertFeature( EditPaM aPaM, const SfxPoolItem& rItem );
|
|
EditPaM ConnectParagraphs( ContentNode* pLeft, ContentNode* pRight );
|
|
|
|
OUString GetText( LineEnd eEnd ) const;
|
|
sal_uLong GetTextLen() const;
|
|
|
|
OUString GetParaAsString( sal_Int32 nNode ) const;
|
|
static OUString GetParaAsString(const ContentNode* pNode, sal_Int32 nStartPos = 0, sal_Int32 nEndPos = -1);
|
|
|
|
EditPaM GetStartPaM() const;
|
|
EditPaM GetEndPaM() const;
|
|
|
|
SfxItemPool& GetItemPool() { return *pItemPool; }
|
|
const SfxItemPool& GetItemPool() const { return *pItemPool; }
|
|
|
|
void RemoveItemsFromPool(const ContentNode& rNode);
|
|
|
|
void InsertAttrib( const SfxPoolItem& rItem, ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEnd );
|
|
void InsertAttrib( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEnd, const SfxPoolItem& rPoolItem );
|
|
void InsertAttribInSelection( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEnd, const SfxPoolItem& rPoolItem );
|
|
bool RemoveAttribs( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEnd, sal_uInt16 nWhich );
|
|
bool RemoveAttribs( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEnd, EditCharAttrib*& rpStarting, EditCharAttrib*& rpEnding, sal_uInt16 nWhich );
|
|
static void FindAttribs( ContentNode* pNode, sal_Int32 nStartPos, sal_Int32 nEndPos, SfxItemSet& rCurSet );
|
|
|
|
sal_Int32 GetPos(const ContentNode* pNode) const;
|
|
const ContentNode* GetObject(sal_Int32 nPos) const;
|
|
ContentNode* GetObject(sal_Int32 nPos);
|
|
sal_Int32 Count() const;
|
|
const ContentNode* operator[](sal_Int32 nPos) const;
|
|
ContentNode* operator[](sal_Int32 nPos);
|
|
void Insert(sal_Int32 nPos, ContentNode* p);
|
|
/// deletes
|
|
void Remove(sal_Int32 nPos);
|
|
/// does not delete
|
|
void Release(sal_Int32 nPos);
|
|
|
|
static OUString GetSepStr( LineEnd eEnd );
|
|
};
|
|
|
|
inline EditCharAttrib* GetAttrib(CharAttribList::AttribsType& rAttribs, sal_Int32 nAttr)
|
|
{
|
|
return (nAttr < static_cast<sal_Int32>(rAttribs.size())) ? rAttribs[nAttr].get() : nullptr;
|
|
}
|
|
|
|
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
|
|
void CheckOrderedList(const CharAttribList::AttribsType& rAttribs);
|
|
#endif
|
|
|
|
class EditEngineItemPool final : public SfxItemPool
|
|
{
|
|
private:
|
|
std::shared_ptr<DefItems> m_xDefItems;
|
|
public:
|
|
EditEngineItemPool();
|
|
private:
|
|
virtual ~EditEngineItemPool() override;
|
|
};
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|