summaryrefslogtreecommitdiffstats
path: root/editeng/source/editeng/editdoc.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'editeng/source/editeng/editdoc.cxx')
-rw-r--r--editeng/source/editeng/editdoc.cxx1898
1 files changed, 188 insertions, 1710 deletions
diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx
index 36a7d5727434..e482eea38652 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -50,19 +50,23 @@
#include <rtl/ustrbuf.hxx>
#include <sal/log.hxx>
+#include <o3tl/safeint.hxx>
#include <osl/diagnose.h>
#include <svl/grabbagitem.hxx>
+#include <svl/voiditem.hxx>
#include <tools/debug.hxx>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <libxml/xmlwriter.h>
#include <algorithm>
#include <cassert>
+#include <cstddef>
#include <limits>
#include <memory>
#include <set>
#include <string_view>
+#include <utility>
using namespace ::com::sun::star;
@@ -153,454 +157,230 @@ bool IsScriptItemValid( sal_uInt16 nItemId, short nScriptType )
return bValid;
}
-const SfxItemInfo aItemInfos[EDITITEMCOUNT] = {
- { SID_ATTR_FRAMEDIRECTION, true }, // EE_PARA_WRITINGDIR
- { 0, true }, // EE_PARA_XMLATTRIBS
- { SID_ATTR_PARA_HANGPUNCTUATION, true }, // EE_PARA_HANGINGPUNCTUATION
- { SID_ATTR_PARA_FORBIDDEN_RULES, true }, // EE_PARA_FORBIDDENRULES
- { SID_ATTR_PARA_SCRIPTSPACE, true }, // EE_PARA_ASIANCJKSPACING
- { SID_ATTR_NUMBERING_RULE, true }, // EE_PARA_NUMBULL
- { 0, true }, // EE_PARA_HYPHENATE
- { 0, true }, // EE_PARA_HYPHENATE_NO_CAPS
- { 0, true }, // EE_PARA_BULLETSTATE
- { 0, true }, // EE_PARA_OUTLLRSPACE
- { SID_ATTR_PARA_OUTLLEVEL, true }, // EE_PARA_OUTLLEVEL
- { SID_ATTR_PARA_BULLET, true }, // EE_PARA_BULLET
- { SID_ATTR_LRSPACE, true }, // EE_PARA_LRSPACE
- { SID_ATTR_ULSPACE, true }, // EE_PARA_ULSPACE
- { SID_ATTR_PARA_LINESPACE, true }, // EE_PARA_SBL
- { SID_ATTR_PARA_ADJUST, true }, // EE_PARA_JUST
- { SID_ATTR_TABSTOP, true }, // EE_PARA_TABS
- { SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD, true }, // EE_PARA_JUST_METHOD
- { SID_ATTR_ALIGN_VER_JUSTIFY, true }, // EE_PARA_VER_JUST
- { SID_ATTR_CHAR_COLOR, true }, // EE_CHAR_COLOR
- { SID_ATTR_CHAR_FONT, true }, // EE_CHAR_FONTINFO
- { SID_ATTR_CHAR_FONTHEIGHT, true }, // EE_CHAR_FONTHEIGHT
- { SID_ATTR_CHAR_SCALEWIDTH, true }, // EE_CHAR_FONTWIDTH
- { SID_ATTR_CHAR_WEIGHT, true }, // EE_CHAR_WEIGHT
- { SID_ATTR_CHAR_UNDERLINE, true }, // EE_CHAR_UNDERLINE
- { SID_ATTR_CHAR_STRIKEOUT, true }, // EE_CHAR_STRIKEOUT
- { SID_ATTR_CHAR_POSTURE, true }, // EE_CHAR_ITALIC
- { SID_ATTR_CHAR_CONTOUR, true }, // EE_CHAR_OUTLINE
- { SID_ATTR_CHAR_SHADOWED, true }, // EE_CHAR_SHADOW
- { SID_ATTR_CHAR_ESCAPEMENT, true }, // EE_CHAR_ESCAPEMENT
- { SID_ATTR_CHAR_AUTOKERN, true }, // EE_CHAR_PAIRKERNING
- { SID_ATTR_CHAR_KERNING, true }, // EE_CHAR_KERNING
- { SID_ATTR_CHAR_WORDLINEMODE, true }, // EE_CHAR_WLM
- { SID_ATTR_CHAR_LANGUAGE, true }, // EE_CHAR_LANGUAGE
- { SID_ATTR_CHAR_CJK_LANGUAGE, true }, // EE_CHAR_LANGUAGE_CJK
- { SID_ATTR_CHAR_CTL_LANGUAGE, true }, // EE_CHAR_LANGUAGE_CTL
- { SID_ATTR_CHAR_CJK_FONT, true }, // EE_CHAR_FONTINFO_CJK
- { SID_ATTR_CHAR_CTL_FONT, true }, // EE_CHAR_FONTINFO_CTL
- { SID_ATTR_CHAR_CJK_FONTHEIGHT, true }, // EE_CHAR_FONTHEIGHT_CJK
- { SID_ATTR_CHAR_CTL_FONTHEIGHT, true }, // EE_CHAR_FONTHEIGHT_CTL
- { SID_ATTR_CHAR_CJK_WEIGHT, true }, // EE_CHAR_WEIGHT_CJK
- { SID_ATTR_CHAR_CTL_WEIGHT, true }, // EE_CHAR_WEIGHT_CTL
- { SID_ATTR_CHAR_CJK_POSTURE, true }, // EE_CHAR_ITALIC_CJK
- { SID_ATTR_CHAR_CTL_POSTURE, true }, // EE_CHAR_ITALIC_CTL
- { SID_ATTR_CHAR_EMPHASISMARK, true }, // EE_CHAR_EMPHASISMARK
- { SID_ATTR_CHAR_RELIEF, true }, // EE_CHAR_RELIEF
- { 0, true }, // EE_CHAR_RUBI_DUMMY
- { 0, true }, // EE_CHAR_XMLATTRIBS
- { SID_ATTR_CHAR_OVERLINE, true }, // EE_CHAR_OVERLINE
- { SID_ATTR_CHAR_CASEMAP, true }, // EE_CHAR_CASEMAP
- { SID_ATTR_CHAR_GRABBAG, true }, // EE_CHAR_GRABBAG
- { SID_ATTR_CHAR_BACK_COLOR, true }, // EE_CHAR_BKGCOLOR
- { 0, true }, // EE_FEATURE_TAB
- { 0, true }, // EE_FEATURE_LINEBR
- { SID_ATTR_CHAR_CHARSETCOLOR, true }, // EE_FEATURE_NOTCONV
- { SID_FIELD, false }, // EE_FEATURE_FIELD
-};
-
EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const SfxPoolItem& rAttr, sal_Int32 nS, sal_Int32 nE )
{
// Create a new attribute in the pool
- const SfxPoolItem& rNew = rPool.Put( rAttr );
-
- EditCharAttrib* pNew = nullptr;
- switch( rNew.Which() )
+ switch( rAttr.Which() )
{
case EE_CHAR_LANGUAGE:
case EE_CHAR_LANGUAGE_CJK:
case EE_CHAR_LANGUAGE_CTL:
{
- pNew = new EditCharAttribLanguage( static_cast<const SvxLanguageItem&>(rNew), nS, nE );
+ return new EditCharAttribLanguage(rPool, rAttr, nS, nE);
}
break;
case EE_CHAR_COLOR:
{
- pNew = new EditCharAttribColor( static_cast<const SvxColorItem&>(rNew), nS, nE );
+ return new EditCharAttribColor(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_FONTINFO:
case EE_CHAR_FONTINFO_CJK:
case EE_CHAR_FONTINFO_CTL:
{
- pNew = new EditCharAttribFont( static_cast<const SvxFontItem&>(rNew), nS, nE );
+ return new EditCharAttribFont(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_FONTHEIGHT:
case EE_CHAR_FONTHEIGHT_CJK:
case EE_CHAR_FONTHEIGHT_CTL:
{
- pNew = new EditCharAttribFontHeight( static_cast<const SvxFontHeightItem&>(rNew), nS, nE );
+ return new EditCharAttribFontHeight(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_FONTWIDTH:
{
- pNew = new EditCharAttribFontWidth( static_cast<const SvxCharScaleWidthItem&>(rNew), nS, nE );
+ return new EditCharAttribFontWidth(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_WEIGHT:
case EE_CHAR_WEIGHT_CJK:
case EE_CHAR_WEIGHT_CTL:
{
- pNew = new EditCharAttribWeight( static_cast<const SvxWeightItem&>(rNew), nS, nE );
+ return new EditCharAttribWeight(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_UNDERLINE:
{
- pNew = new EditCharAttribUnderline( static_cast<const SvxUnderlineItem&>(rNew), nS, nE );
+ return new EditCharAttribUnderline(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_OVERLINE:
{
- pNew = new EditCharAttribOverline( static_cast<const SvxOverlineItem&>(rNew), nS, nE );
+ return new EditCharAttribOverline(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_EMPHASISMARK:
{
- pNew = new EditCharAttribEmphasisMark( static_cast<const SvxEmphasisMarkItem&>(rNew), nS, nE );
+ return new EditCharAttribEmphasisMark(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_RELIEF:
{
- pNew = new EditCharAttribRelief( static_cast<const SvxCharReliefItem&>(rNew), nS, nE );
+ return new EditCharAttribRelief(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_STRIKEOUT:
{
- pNew = new EditCharAttribStrikeout( static_cast<const SvxCrossedOutItem&>(rNew), nS, nE );
+ return new EditCharAttribStrikeout(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_ITALIC:
case EE_CHAR_ITALIC_CJK:
case EE_CHAR_ITALIC_CTL:
{
- pNew = new EditCharAttribItalic( static_cast<const SvxPostureItem&>(rNew), nS, nE );
+ return new EditCharAttribItalic(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_OUTLINE:
{
- pNew = new EditCharAttribOutline( static_cast<const SvxContourItem&>(rNew), nS, nE );
+ return new EditCharAttribOutline(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_SHADOW:
{
- pNew = new EditCharAttribShadow( static_cast<const SvxShadowedItem&>(rNew), nS, nE );
+ return new EditCharAttribShadow(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_ESCAPEMENT:
{
- pNew = new EditCharAttribEscapement( static_cast<const SvxEscapementItem&>(rNew), nS, nE );
+ return new EditCharAttribEscapement(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_PAIRKERNING:
{
- pNew = new EditCharAttribPairKerning( static_cast<const SvxAutoKernItem&>(rNew), nS, nE );
+ return new EditCharAttribPairKerning(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_KERNING:
{
- pNew = new EditCharAttribKerning( static_cast<const SvxKerningItem&>(rNew), nS, nE );
+ return new EditCharAttribKerning(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_WLM:
{
- pNew = new EditCharAttribWordLineMode( static_cast<const SvxWordLineModeItem&>(rNew), nS, nE );
+ return new EditCharAttribWordLineMode(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_XMLATTRIBS:
{
- pNew = new EditCharAttrib( rNew, nS, nE ); // Attribute is only for holding XML information...
+ return new EditCharAttrib(rPool, rAttr, nS, nE); // Attribute is only for holding XML information...
}
break;
case EE_CHAR_CASEMAP:
{
- pNew = new EditCharAttribCaseMap( static_cast<const SvxCaseMapItem&>(rNew), nS, nE );
+ return new EditCharAttribCaseMap(rPool, rAttr, nS, nE );
}
break;
case EE_CHAR_GRABBAG:
{
- pNew = new EditCharAttribGrabBag( static_cast<const SfxGrabBagItem&>(rNew), nS, nE );
+ return new EditCharAttribGrabBag(rPool, rAttr, nS, nE );
}
break;
case EE_FEATURE_TAB:
{
- pNew = new EditCharAttribTab( static_cast<const SfxVoidItem&>(rNew), nS );
+ return new EditCharAttribTab(rPool, rAttr, nS );
}
break;
case EE_FEATURE_LINEBR:
{
- pNew = new EditCharAttribLineBreak( static_cast<const SfxVoidItem&>(rNew), nS );
+ return new EditCharAttribLineBreak(rPool, rAttr, nS );
}
break;
case EE_FEATURE_FIELD:
{
- pNew = new EditCharAttribField( static_cast<const SvxFieldItem&>(rNew), nS );
+ return new EditCharAttribField(rPool, rAttr, nS );
}
break;
case EE_CHAR_BKGCOLOR:
{
- pNew = new EditCharAttribBackgroundColor( static_cast<const SvxColorItem&>(rNew), nS, nE );
+ return new EditCharAttribBackgroundColor(rPool, rAttr, nS, nE );
}
break;
default:
- {
- OSL_FAIL( "Invalid Attribute!" );
- }
- }
- return pNew;
-}
-
-TextPortionList::TextPortionList()
-{
-}
-
-TextPortionList::~TextPortionList()
-{
-}
-
-void TextPortionList::Reset()
-{
- maPortions.clear();
-}
-
-void TextPortionList::DeleteFromPortion(sal_Int32 nDelFrom)
-{
- assert((nDelFrom < static_cast<sal_Int32>(maPortions.size())) || ((nDelFrom == 0) && maPortions.empty()));
- PortionsType::iterator it = maPortions.begin();
- std::advance(it, nDelFrom);
- maPortions.erase(it, maPortions.end());
-}
-
-sal_Int32 TextPortionList::Count() const
-{
- return static_cast<sal_Int32>(maPortions.size());
-}
-
-const TextPortion& TextPortionList::operator[](sal_Int32 nPos) const
-{
- return *maPortions[nPos];
-}
-
-TextPortion& TextPortionList::operator[](sal_Int32 nPos)
-{
- return *maPortions[nPos];
-}
-
-void TextPortionList::Append(TextPortion* p)
-{
- maPortions.push_back(std::unique_ptr<TextPortion>(p));
-}
-
-void TextPortionList::Insert(sal_Int32 nPos, TextPortion* p)
-{
- maPortions.insert(maPortions.begin()+nPos, std::unique_ptr<TextPortion>(p));
-}
-
-void TextPortionList::Remove(sal_Int32 nPos)
-{
- maPortions.erase(maPortions.begin()+nPos);
-}
-
-namespace {
-
-class FindTextPortionByAddress
-{
- const TextPortion* mp;
-public:
- explicit FindTextPortionByAddress(const TextPortion* p) : mp(p) {}
- bool operator() (const std::unique_ptr<TextPortion>& v) const
- {
- return v.get() == mp;
- }
-};
-
-}
-
-sal_Int32 TextPortionList::GetPos(const TextPortion* p) const
-{
- PortionsType::const_iterator it =
- std::find_if(maPortions.begin(), maPortions.end(), FindTextPortionByAddress(p));
-
- if (it == maPortions.end())
- return std::numeric_limits<sal_Int32>::max(); // not found.
-
- return std::distance(maPortions.begin(), it);
-}
-
-sal_Int32 TextPortionList::FindPortion(
- sal_Int32 nCharPos, sal_Int32& nPortionStart, bool bPreferStartingPortion) const
-{
- // When nCharPos at portion limit, the left portion is found
- sal_Int32 nTmpPos = 0;
- sal_Int32 n = maPortions.size();
- for (sal_Int32 i = 0; i < n; ++i)
- {
- const TextPortion& rPortion = *maPortions[i];
- nTmpPos = nTmpPos + rPortion.GetLen();
- if ( nTmpPos >= nCharPos )
- {
- // take this one if we don't prefer the starting portion, or if it's the last one
- if ( ( nTmpPos != nCharPos ) || !bPreferStartingPortion || ( i == n-1 ) )
- {
- nPortionStart = nTmpPos - rPortion.GetLen();
- return i;
- }
- }
- }
- OSL_FAIL( "FindPortion: Not found!" );
- return n - 1;
-}
-
-sal_Int32 TextPortionList::GetStartPos(sal_Int32 nPortion)
-{
- sal_Int32 nPos = 0;
- for (sal_Int32 i = 0; i < nPortion; ++i)
- {
- const TextPortion& rPortion = *maPortions[i];
- nPos = nPos + rPortion.GetLen();
- }
- return nPos;
-}
-
-ExtraPortionInfo::ExtraPortionInfo()
-: nOrgWidth(0)
-, nWidthFullCompression(0)
-, nPortionOffsetX(0)
-, nMaxCompression100thPercent(0)
-, nAsianCompressionTypes(AsianCompressionFlags::Normal)
-, bFirstCharIsRightPunktuation(false)
-, bCompressed(false)
-{
-}
-
-ExtraPortionInfo::~ExtraPortionInfo()
-{
-}
-
-void ExtraPortionInfo::SaveOrgDXArray( const sal_Int32* pDXArray, sal_Int32 nLen )
-{
- if (pDXArray)
- {
- pOrgDXArray.reset(new sal_Int32[nLen]);
- memcpy( pOrgDXArray.get(), pDXArray, nLen * sizeof(sal_Int32) );
+ break;
}
- else
- pOrgDXArray.reset();
-}
-
-ParaPortion::ParaPortion( ContentNode* pN ) :
- pNode(pN),
- nHeight(0),
- nInvalidPosStart(0),
- nFirstLineOffset(0),
- nBulletX(0),
- nInvalidDiff(0),
- bInvalid(true),
- bSimple(false),
- bVisible(true),
- bForceRepaint(false)
-{
-}
-ParaPortion::~ParaPortion()
-{
+ OSL_FAIL( "Invalid Attribute!" );
+ return nullptr;
}
-void ParaPortion::MarkInvalid( sal_Int32 nStart, sal_Int32 nDiff )
+void ParaPortion::MarkInvalid(sal_Int32 nStart, sal_Int32 nDiff)
{
- if ( !bInvalid )
+ if (!mbInvalid)
{
-// nInvalidPosEnd = nStart; // ??? => CreateLines
- nInvalidPosStart = ( nDiff >= 0 ) ? nStart : ( nStart + nDiff );
- nInvalidDiff = nDiff;
+// mnInvalidPosEnd = nStart; // ??? => CreateLines
+ mnInvalidPosStart = nDiff >= 0 ? nStart : nStart + nDiff;
+ mnInvalidDiff = nDiff;
}
else
{
// Simple tap in succession
- if ( ( nDiff > 0 ) && ( nInvalidDiff > 0 ) &&
- ( ( nInvalidPosStart+nInvalidDiff ) == nStart ) )
+ if (nDiff > 0 && mnInvalidDiff > 0 && (mnInvalidPosStart + mnInvalidDiff) == nStart)
{
- nInvalidDiff = nInvalidDiff + nDiff;
+ mnInvalidDiff = mnInvalidDiff + nDiff;
}
// Simple delete in succession
- else if ( ( nDiff < 0 ) && ( nInvalidDiff < 0 ) && ( nInvalidPosStart == nStart ) )
+ else if (nDiff < 0 && mnInvalidDiff < 0 && mnInvalidPosStart == nStart)
{
- nInvalidPosStart = nInvalidPosStart + nDiff;
- nInvalidDiff = nInvalidDiff + nDiff;
+ mnInvalidPosStart = mnInvalidPosStart + nDiff;
+ mnInvalidDiff = mnInvalidDiff + nDiff;
}
else
{
-// nInvalidPosEnd = pNode->Len();
- DBG_ASSERT( ( nDiff >= 0 ) || ( (nStart+nDiff) >= 0 ), "MarkInvalid: Diff out of Range" );
- nInvalidPosStart = std::min( nInvalidPosStart, ( nDiff < 0 ? nStart+nDiff : nDiff ) );
- nInvalidDiff = 0;
- bSimple = false;
+// mnInvalidPosEnd = pNode->Len();
+ DBG_ASSERT(nDiff >= 0 || (nStart + nDiff) >= 0, "MarkInvalid: Diff out of Range");
+ mnInvalidPosStart = std::min(mnInvalidPosStart, nDiff < 0 ? nStart + nDiff : nDiff);
+ mnInvalidDiff = 0;
+ mbSimple = false;
}
}
- bInvalid = true;
- aScriptInfos.clear();
- aWritingDirectionInfos.clear();
+ mbInvalid = true;
+ maScriptInfos.clear();
+ maWritingDirectionInfos.clear();
}
-void ParaPortion::MarkSelectionInvalid( sal_Int32 nStart )
+void ParaPortion::MarkSelectionInvalid(sal_Int32 nStart)
{
- if ( !bInvalid )
+ if ( !mbInvalid )
{
- nInvalidPosStart = nStart;
+ mnInvalidPosStart = nStart;
}
else
{
- nInvalidPosStart = std::min( nInvalidPosStart, nStart );
+ mnInvalidPosStart = std::min(mnInvalidPosStart, nStart);
}
- nInvalidDiff = 0;
- bInvalid = true;
- bSimple = false;
- aScriptInfos.clear();
- aWritingDirectionInfos.clear();
+ mnInvalidDiff = 0;
+ mbInvalid = true;
+ mbSimple = false;
+ maScriptInfos.clear();
+ maWritingDirectionInfos.clear();
}
sal_Int32 ParaPortion::GetLineNumber( sal_Int32 nIndex ) const
{
- SAL_WARN_IF( !aLineList.Count(), "editeng", "Empty ParaPortion in GetLine!" );
- DBG_ASSERT( bVisible, "Why GetLine() on an invisible paragraph?" );
+ SAL_WARN_IF(!maLineList.Count(), "editeng", "Empty ParaPortion in GetLine!");
+ DBG_ASSERT(mbVisible, "Why GetLine() on an invisible paragraph?");
- for ( sal_Int32 nLine = 0; nLine < aLineList.Count(); nLine++ )
+ for ( sal_Int32 nLine = 0; nLine < maLineList.Count(); nLine++ )
{
- if ( aLineList[nLine].IsIn( nIndex ) )
+ if (maLineList[nLine].IsIn(nIndex))
return nLine;
}
// Then it should be at the end of the last line!
- DBG_ASSERT( nIndex == aLineList[ aLineList.Count() - 1 ].GetEnd(), "Index dead wrong!" );
- return (aLineList.Count()-1);
-}
-
-void ParaPortion::SetVisible( bool bMakeVisible )
-{
- bVisible = bMakeVisible;
+ DBG_ASSERT(nIndex == maLineList[maLineList.Count() - 1].GetEnd(), "Index dead wrong!");
+ return (maLineList.Count() - 1);
}
void ParaPortion::CorrectValuesBehindLastFormattedLine( sal_Int32 nLastFormattedLine )
{
- sal_Int32 nLines = aLineList.Count();
+ sal_Int32 nLines = maLineList.Count();
DBG_ASSERT( nLines, "CorrectPortionNumbersFromLine: Empty Portion?" );
if ( nLastFormattedLine < ( nLines - 1 ) )
{
- const EditLine& rLastFormatted = aLineList[ nLastFormattedLine ];
- const EditLine& rUnformatted = aLineList[ nLastFormattedLine+1 ];
+ const EditLine& rLastFormatted = maLineList[ nLastFormattedLine ];
+ const EditLine& rUnformatted = maLineList[ nLastFormattedLine+1 ];
sal_Int32 nPortionDiff = rUnformatted.GetStartPortion() - rLastFormatted.GetEndPortion();
sal_Int32 nTextDiff = rUnformatted.GetStart() - rLastFormatted.GetEnd();
nTextDiff++; // LastFormatted->GetEnd() was included => 1 deducted too much!
@@ -615,7 +395,7 @@ void ParaPortion::CorrectValuesBehindLastFormattedLine( sal_Int32 nLastFormatted
{
for ( sal_Int32 nL = nLastFormattedLine+1; nL < nLines; nL++ )
{
- EditLine& rLine = aLineList[ nL ];
+ EditLine& rLine = maLineList[ nL ];
rLine.GetStartPortion() = rLine.GetStartPortion() + nPDiff;
rLine.GetEndPortion() = rLine.GetEndPortion() + nPDiff;
@@ -627,7 +407,7 @@ void ParaPortion::CorrectValuesBehindLastFormattedLine( sal_Int32 nLastFormatted
}
}
}
- DBG_ASSERT( aLineList[ aLineList.Count()-1 ].GetEnd() == pNode->Len(), "CorrectLines: The end is not right!" );
+ DBG_ASSERT(maLineList[maLineList.Count() - 1].GetEnd() == mpNode->Len(), "CorrectLines: The end is not right!");
}
// Shared reverse lookup acceleration pieces ...
@@ -673,75 +453,44 @@ sal_Int32 FastGetPos(const Array& rArray, const Val* p, sal_Int32& rLastPos)
}
-ParaPortionList::ParaPortionList() : nLastCache( 0 )
-{
-}
-
-ParaPortionList::~ParaPortionList()
+sal_Int32 ParaPortionList::GetPos(const ParaPortion* p) const
{
+ return FastGetPos(maPortions, p, nLastCache);
}
-sal_Int32 ParaPortionList::GetPos(const ParaPortion* p) const
+std::unique_ptr<ParaPortion> ParaPortionList::Release(sal_Int32 nPos)
{
- sal_Int32 nArrayLen = maPortions.size();
-
- // Through certain filter code-paths we do a lot of appends, which in
- // turn call GetPos - creating some N^2 nightmares. If we have a
- // non-trivially large list, do a few checks from the end first.
- if (nLastCache > 16 && nArrayLen > 16)
+ if (nPos < 0 || maPortions.size() <= o3tl::make_unsigned(nPos))
{
- sal_Int32 nEnd;
- if (nLastCache > nArrayLen - 2)
- nEnd = nArrayLen;
- else
- nEnd = nLastCache + 2;
-
- for (sal_Int32 nIdx = nLastCache - 2; nIdx < nEnd; ++nIdx)
- {
- if (&maPortions.at(nIdx) == p)
- {
- nLastCache = nIdx;
- return nIdx;
- }
- }
+ SAL_WARN( "editeng", "ParaPortionList::Release - out of bounds pos " << nPos);
+ return nullptr;
}
- // The world's lamest linear search from svarray...
- for (sal_Int32 nIdx = 0; nIdx < nArrayLen; ++nIdx)
- if (&maPortions.at(nIdx) == p)
- {
- nLastCache = nIdx;
- return nLastCache;
- }
-
- // XXX "not found" condition for sal_Int32 indexes
- return EE_PARA_NOT_FOUND;
-}
-
-ParaPortion& ParaPortionList::operator [](sal_Int32 nPos)
-{
- return maPortions[nPos];
-}
-
-const ParaPortion& ParaPortionList::operator [](sal_Int32 nPos) const
-{
- return maPortions[nPos];
+ std::unique_ptr<ParaPortion> p = std::move(maPortions[nPos]);
+ maPortions.erase(maPortions.begin()+nPos);
+ return p;
}
-ParaPortion ParaPortionList::Remove(sal_Int32 nPos)
+void ParaPortionList::Remove(sal_Int32 nPos)
{
- auto it = maPortions.begin()+nPos;
- ParaPortion val = std::move(*it);
- maPortions.erase(it);
- return val;
+ if (nPos < 0 || maPortions.size() <= o3tl::make_unsigned(nPos))
+ {
+ SAL_WARN( "editeng", "ParaPortionList::Remove - out of bounds pos " << nPos);
+ return;
+ }
+ maPortions.erase(maPortions.begin()+nPos);
}
-ParaPortion& ParaPortionList::Insert(sal_Int32 nPos, ParaPortion&& p)
+void ParaPortionList::Insert(sal_Int32 nPos, std::unique_ptr<ParaPortion> p)
{
+ if (nPos < 0 || maPortions.size() < o3tl::make_unsigned(nPos))
+ {
+ SAL_WARN( "editeng", "ParaPortionList::Insert - out of bounds pos " << nPos);
+ return;
+ }
maPortions.insert(maPortions.begin()+nPos, std::move(p));
- return maPortions[nPos];
}
-void ParaPortionList::Append(ParaPortion&& p)
+void ParaPortionList::Append(std::unique_ptr<ParaPortion> p)
{
maPortions.push_back(std::move(p));
}
@@ -767,9 +516,10 @@ tools::Long ParaPortionList::GetYOffset(const ParaPortion* pPPortion) const
tools::Long nHeight = 0;
for (const auto & rPortion : maPortions)
{
- if ( pPPortion == &rPortion )
+ const ParaPortion* pTmpPortion = rPortion.get();
+ if ( pTmpPortion == pPPortion )
return nHeight;
- nHeight += rPortion.GetHeight();
+ nHeight += pTmpPortion->GetHeight();
}
OSL_FAIL( "GetYOffset: Portion not found" );
return nHeight;
@@ -780,23 +530,13 @@ sal_Int32 ParaPortionList::FindParagraph(tools::Long nYOffset) const
tools::Long nY = 0;
for (size_t i = 0, n = maPortions.size(); i < n; ++i)
{
- nY += maPortions[i].GetHeight(); // should also be correct even in bVisible!
+ nY += maPortions[i]->GetHeight(); // should also be correct even in bVisible!
if ( nY > nYOffset )
return i <= SAL_MAX_INT32 ? static_cast<sal_Int32>(i) : SAL_MAX_INT32;
}
return EE_PARA_NOT_FOUND;
}
-const ParaPortion* ParaPortionList::SafeGetObject(sal_Int32 nPos) const
-{
- return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? &maPortions[nPos] : nullptr;
-}
-
-ParaPortion* ParaPortionList::SafeGetObject(sal_Int32 nPos)
-{
- return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? &maPortions[nPos] : nullptr;
-}
-
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
void
ParaPortionList::DbgCheck(ParaPortionList const& rParas, EditDoc const& rDoc)
@@ -811,15 +551,9 @@ ParaPortionList::DbgCheck(ParaPortionList const& rParas, EditDoc const& rDoc)
}
#endif
-ContentAttribsInfo::ContentAttribsInfo( const SfxItemSet& rParaAttribs ) :
- aPrevParaAttribs( rParaAttribs)
-{
-}
-
-void ContentAttribsInfo::RemoveAllCharAttribsFromPool(SfxItemPool& rPool) const
+ContentAttribsInfo::ContentAttribsInfo( SfxItemSet aParaAttribs ) :
+ aPrevParaAttribs(std::move( aParaAttribs))
{
- for (const std::unique_ptr<EditCharAttrib>& rAttrib : aPrevCharAttribs)
- rPool.Remove(*rAttrib->GetItem());
}
void ContentAttribsInfo::AppendCharAttrib(EditCharAttrib* pNew)
@@ -864,6 +598,13 @@ void ConvertItem( std::unique_ptr<SfxPoolItem>& rPoolItem, MapUnit eSourceUnit,
assert(dynamic_cast<const SvxTabStopItem *>(rPoolItem.get()) != nullptr);
SvxTabStopItem& rItem = static_cast<SvxTabStopItem&>(*rPoolItem);
SvxTabStopItem* pNewItem(new SvxTabStopItem(EE_PARA_TABS));
+
+ if (sal_Int32 nDefTabDistance = rItem.GetDefaultDistance())
+ {
+ pNewItem->SetDefaultDistance(
+ OutputDevice::LogicToLogic(nDefTabDistance, eSourceUnit, eDestUnit));
+ }
+
for ( sal_uInt16 i = 0; i < rItem.Count(); i++ )
{
const SvxTabStop& rTab = rItem[i];
@@ -898,7 +639,7 @@ void ConvertAndPutItems( SfxItemSet& rDest, const SfxItemSet& rSource, const Map
sal_uInt16 nSlot = pDestPool->GetTrueSlotId( nWhich );
if ( nSlot )
{
- sal_uInt16 nW = pSourcePool->GetTrueWhich( nSlot );
+ sal_uInt16 nW = pSourcePool->GetTrueWhichIDFromSlotID( nSlot );
if ( nW )
nSourceWhich = nW;
}
@@ -922,179 +663,6 @@ void ConvertAndPutItems( SfxItemSet& rDest, const SfxItemSet& rSource, const Map
}
}
-EditLine::EditLine() :
- nTxtWidth(0),
- nStartPosX(0),
- nStart(0),
- nEnd(0),
- nStartPortion(0), // to be able to tell the difference between a line
- // without Portions from one with the Portion number 0
- nEndPortion(0),
- nHeight(0),
- nTxtHeight(0),
- nMaxAscent(0),
- bHangingPunctuation(false),
- bInvalid(true)
-{
-}
-
-EditLine* EditLine::Clone() const
-{
- EditLine* pL = new EditLine;
- pL->aPositions = aPositions;
- pL->nStartPosX = nStartPosX;
- pL->nStart = nStart;
- pL->nEnd = nEnd;
- pL->nStartPortion = nStartPortion;
- pL->nEndPortion = nEndPortion;
- pL->nHeight = nHeight;
- pL->nTxtWidth = nTxtWidth;
- pL->nTxtHeight = nTxtHeight;
- pL->nMaxAscent = nMaxAscent;
-
- return pL;
-}
-
-bool operator == ( const EditLine& r1, const EditLine& r2 )
-{
- if ( r1.nStart != r2.nStart )
- return false;
-
- if ( r1.nEnd != r2.nEnd )
- return false;
-
- if ( r1.nStartPortion != r2.nStartPortion )
- return false;
-
- if ( r1.nEndPortion != r2.nEndPortion )
- return false;
-
- return true;
-}
-
-
-void EditLine::SetHeight( sal_uInt16 nH, sal_uInt16 nTxtH )
-{
- nHeight = nH;
- nTxtHeight = ( nTxtH ? nTxtH : nH );
-}
-
-void EditLine::SetStartPosX( sal_Int32 start )
-{
- if (start > 0)
- nStartPosX = start;
- else
- nStartPosX = 0;
-}
-
-Size EditLine::CalcTextSize( ParaPortion& rParaPortion )
-{
- Size aSz;
- Size aTmpSz;
-
- DBG_ASSERT( rParaPortion.GetTextPortions().Count(), "GetTextSize before CreatePortions !" );
-
- for ( sal_Int32 n = nStartPortion; n <= nEndPortion; n++ )
- {
- TextPortion& rPortion = rParaPortion.GetTextPortions()[n];
- switch ( rPortion.GetKind() )
- {
- case PortionKind::TEXT:
- case PortionKind::FIELD:
- case PortionKind::HYPHENATOR:
- {
- aTmpSz = rPortion.GetSize();
- aSz.AdjustWidth(aTmpSz.Width() );
- if ( aSz.Height() < aTmpSz.Height() )
- aSz.setHeight( aTmpSz.Height() );
- }
- break;
- case PortionKind::TAB:
- {
- aSz.AdjustWidth(rPortion.GetSize().Width() );
- }
- break;
- case PortionKind::LINEBREAK: break;
- }
- }
-
- SetHeight( static_cast<sal_uInt16>(aSz.Height()) );
- return aSz;
-}
-
-EditLineList::EditLineList()
-{
-}
-
-EditLineList::~EditLineList()
-{
- Reset();
-}
-
-void EditLineList::Reset()
-{
- maLines.clear();
-}
-
-void EditLineList::DeleteFromLine(sal_Int32 nDelFrom)
-{
- assert(nDelFrom <= (static_cast<sal_Int32>(maLines.size()) - 1));
- LinesType::iterator it = maLines.begin();
- std::advance(it, nDelFrom);
- maLines.erase(it, maLines.end());
-}
-
-sal_Int32 EditLineList::FindLine(sal_Int32 nChar, bool bInclEnd)
-{
- sal_Int32 n = maLines.size();
- for (sal_Int32 i = 0; i < n; ++i)
- {
- const EditLine& rLine = *maLines[i];
- if ( (bInclEnd && (rLine.GetEnd() >= nChar)) ||
- (rLine.GetEnd() > nChar) )
- {
- return i;
- }
- }
-
- DBG_ASSERT( !bInclEnd, "Line not found: FindLine" );
- return n - 1;
-}
-
-sal_Int32 EditLineList::Count() const
-{
- return maLines.size();
-}
-
-const EditLine& EditLineList::operator[](sal_Int32 nPos) const
-{
- return *maLines[nPos];
-}
-
-EditLine& EditLineList::operator[](sal_Int32 nPos)
-{
- return *maLines[nPos];
-}
-
-void EditLineList::Append(EditLine* p)
-{
- maLines.push_back(std::unique_ptr<EditLine>(p));
-}
-
-void EditLineList::Insert(sal_Int32 nPos, EditLine* p)
-{
- maLines.insert(maLines.begin()+nPos, std::unique_ptr<EditLine>(p));
-}
-
-EditPaM::EditPaM() : pNode(nullptr), nIndex(0) {}
-EditPaM::EditPaM(ContentNode* p, sal_Int32 n) : pNode(p), nIndex(n) {}
-
-
-void EditPaM::SetNode(ContentNode* p)
-{
- pNode = p;
-}
-
bool EditPaM::DbgIsBuggy( EditDoc const & rDoc ) const
{
return !pNode ||
@@ -1107,29 +675,6 @@ bool EditSelection::DbgIsBuggy( EditDoc const & rDoc ) const
return aStartPaM.DbgIsBuggy( rDoc ) || aEndPaM.DbgIsBuggy( rDoc );
}
-EditSelection::EditSelection()
-{
-}
-
-EditSelection::EditSelection( const EditPaM& rStartAndAnd ) :
- aStartPaM(rStartAndAnd),
- aEndPaM(rStartAndAnd)
-{
-}
-
-EditSelection::EditSelection( const EditPaM& rStart, const EditPaM& rEnd ) :
- aStartPaM(rStart),
- aEndPaM(rEnd)
-{
-}
-
-EditSelection& EditSelection::operator = ( const EditPaM& rPaM )
-{
- aStartPaM = rPaM;
- aEndPaM = rPaM;
- return *this;
-}
-
void EditSelection::Adjust( const EditDoc& rNodes )
{
DBG_ASSERT( aStartPaM.GetIndex() <= aStartPaM.GetNode()->Len(), "Index out of range in Adjust(1)" );
@@ -1156,790 +701,28 @@ void EditSelection::Adjust( const EditDoc& rNodes )
}
}
-bool operator == ( const EditPaM& r1, const EditPaM& r2 )
-{
- return ( r1.GetNode() == r2.GetNode() ) &&
- ( r1.GetIndex() == r2.GetIndex() );
-}
-
-bool operator != ( const EditPaM& r1, const EditPaM& r2 )
-{
- return !( r1 == r2 );
-}
-
-ContentNode::ContentNode( SfxItemPool& rPool ) : aContentAttribs( rPool )
-{
-}
-
-ContentNode::ContentNode( const OUString& rStr, const ContentAttribs& rContentAttribs ) :
- maString(rStr), aContentAttribs(rContentAttribs)
-{
-}
-
-ContentNode::~ContentNode()
-{
-}
-
-void ContentNode::ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNew, SfxItemPool& rItemPool )
-{
- if ( !nNew )
- return;
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(aCharAttribList);
-#endif
-
- // Since features are treated differently than normal character attributes,
- // but can also affect the order of the start list. // In every if ..., in the next (n) opportunities due to bFeature or
- // an existing special case, must (n-1) opportunities be provided with
- // bResort. The most likely possibility receives no bResort, so that is
- // not sorted anew when all attributes are the same.
- bool bResort = false;
- bool bExpandedEmptyAtIndexNull = false;
-
- sal_Int32 nAttr = 0;
- CharAttribList::AttribsType& rAttribs = aCharAttribList.GetAttribs();
- EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr);
- while ( pAttrib )
- {
- if ( pAttrib->GetEnd() >= nIndex )
- {
- // Move all attributes behind the insertion point...
- if ( pAttrib->GetStart() > nIndex )
- {
- pAttrib->MoveForward( nNew );
- }
- // 0: Expand empty attribute, if at insertion point
- else if ( pAttrib->IsEmpty() )
- {
- // Do not check Index, an empty one could only be there
- // When later checking it anyhow:
- // Special case: Start == 0; AbsLen == 1, nNew = 1
- // => Expand, because of paragraph break!
- // Start <= nIndex, End >= nIndex => Start=End=nIndex!
-// if ( pAttrib->GetStart() == nIndex )
- pAttrib->Expand( nNew );
- bResort = true;
- if ( pAttrib->GetStart() == 0 )
- bExpandedEmptyAtIndexNull = true;
- }
- // 1: Attribute starts before, goes to index ...
- else if ( pAttrib->GetEnd() == nIndex ) // Start must be before
- {
- // Only expand when there is no feature
- // and if not in exclude list!
- // Otherwise, a UL will go on until a new ULDB, expanding both
-// if ( !pAttrib->IsFeature() && !rExclList.FindAttrib( pAttrib->Which() ) )
- if ( !pAttrib->IsFeature() && !aCharAttribList.FindEmptyAttrib( pAttrib->Which(), nIndex ) )
- {
- if ( !pAttrib->IsEdge() )
- pAttrib->Expand( nNew );
- }
- else
- bResort = true;
- }
- // 2: Attribute starts before, goes past the Index...
- else if ( ( pAttrib->GetStart() < nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
- {
- DBG_ASSERT( !pAttrib->IsFeature(), "Large Feature?!" );
- pAttrib->Expand( nNew );
- }
- // 3: Attribute starts on index...
- else if ( pAttrib->GetStart() == nIndex )
- {
- if ( pAttrib->IsFeature() )
- {
- pAttrib->MoveForward( nNew );
- bResort = true;
- }
- else
- {
- bool bExpand = false;
- if ( nIndex == 0 )
- {
- bExpand = true;
- if( bExpandedEmptyAtIndexNull )
- {
- // Check if this kind of attribute was empty and expanded here...
- sal_uInt16 nW = pAttrib->GetItem()->Which();
- for ( sal_Int32 nA = 0; nA < nAttr; nA++ )
- {
- const EditCharAttrib& r = *aCharAttribList.GetAttribs()[nA];
- if ( ( r.GetStart() == 0 ) && ( r.GetItem()->Which() == nW ) )
- {
- bExpand = false;
- break;
- }
- }
-
- }
- }
- if ( bExpand )
- {
- pAttrib->Expand( nNew );
- bResort = true;
- }
- else
- {
- pAttrib->MoveForward( nNew );
- }
- }
- }
- }
-
- if ( pAttrib->IsEdge() )
- pAttrib->SetEdge(false);
-
- DBG_ASSERT( !pAttrib->IsFeature() || ( pAttrib->GetLen() == 1 ), "Expand: FeaturesLen != 1" );
-
- DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Expand: Attribute distorted!" );
- DBG_ASSERT( ( pAttrib->GetEnd() <= Len() ), "Expand: Attribute larger than paragraph!" );
- if ( pAttrib->IsEmpty() )
- {
- OSL_FAIL( "Empty Attribute after ExpandAttribs?" );
- bResort = true;
- rItemPool.Remove( *pAttrib->GetItem() );
- rAttribs.erase(rAttribs.begin()+nAttr);
- --nAttr;
- }
- ++nAttr;
- pAttrib = GetAttrib(rAttribs, nAttr);
- }
-
- if ( bResort )
- aCharAttribList.ResortAttribs();
-
- if (mpWrongList)
- {
- bool bSep = ( maString[ nIndex ] == ' ' ) || IsFeature( nIndex );
- mpWrongList->TextInserted( nIndex, nNew, bSep );
- }
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(aCharAttribList);
-#endif
-}
-
-void ContentNode::CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDeleted, SfxItemPool& rItemPool )
-{
- if ( !nDeleted )
- return;
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(aCharAttribList);
-#endif
-
- // Since features are treated differently than normal character attributes,
- // but can also affect the order of the start list
- bool bResort = false;
- sal_Int32 nEndChanges = nIndex+nDeleted;
-
- sal_Int32 nAttr = 0;
- CharAttribList::AttribsType& rAttribs = aCharAttribList.GetAttribs();
- EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr);
- while ( pAttrib )
- {
- bool bDelAttr = false;
- if ( pAttrib->GetEnd() >= nIndex )
- {
- // Move all Attribute behind the insert point...
- if ( pAttrib->GetStart() >= nEndChanges )
- {
- pAttrib->MoveBackward( nDeleted );
- }
- // 1. Delete Internal attributes...
- else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() <= nEndChanges ) )
- {
- // Special case: Attribute covers the area exactly
- // => keep as empty Attribute.
- if ( !pAttrib->IsFeature() && ( pAttrib->GetStart() == nIndex ) && ( pAttrib->GetEnd() == nEndChanges ) )
- {
- pAttrib->GetEnd() = nIndex; // empty
- bResort = true;
- }
- else
- bDelAttr = true;
- }
- // 2. Attribute starts earlier, ends inside or behind it ...
- else if ( ( pAttrib->GetStart() <= nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
- {
- DBG_ASSERT( !pAttrib->IsFeature(), "Collapsing Feature!" );
- if ( pAttrib->GetEnd() <= nEndChanges ) // ends inside
- pAttrib->GetEnd() = nIndex;
- else
- pAttrib->Collaps( nDeleted ); // ends behind
- }
- // 3. Attribute starts inside, ending behind ...
- else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() > nEndChanges ) )
- {
- // Features not allowed to expand!
- if ( pAttrib->IsFeature() )
- {
- pAttrib->MoveBackward( nDeleted );
- bResort = true;
- }
- else
- {
- pAttrib->GetStart() = nEndChanges;
- pAttrib->MoveBackward( nDeleted );
- }
- }
- }
- DBG_ASSERT( !pAttrib->IsFeature() || ( pAttrib->GetLen() == 1 ), "Expand: FeaturesLen != 1" );
-
- DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Collapse: Attribute distorted!" );
- DBG_ASSERT( ( pAttrib->GetEnd() <= Len()) || bDelAttr, "Collapse: Attribute larger than paragraph!" );
- if ( bDelAttr )
- {
- bResort = true;
- rItemPool.Remove( *pAttrib->GetItem() );
- rAttribs.erase(rAttribs.begin()+nAttr);
- nAttr--;
- }
- else if ( pAttrib->IsEmpty() )
- aCharAttribList.SetHasEmptyAttribs(true);
-
- nAttr++;
- pAttrib = GetAttrib(rAttribs, nAttr);
- }
-
- if ( bResort )
- aCharAttribList.ResortAttribs();
-
- if (mpWrongList)
- mpWrongList->TextDeleted(nIndex, nDeleted);
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(aCharAttribList);
-#endif
-}
-
-void ContentNode::CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool, bool bKeepEndingAttribs )
-{
- assert(pPrevNode);
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(aCharAttribList);
- CharAttribList::DbgCheckAttribs(pPrevNode->aCharAttribList);
-#endif
-
- sal_Int32 nCut = pPrevNode->Len();
-
- sal_Int32 nAttr = 0;
- CharAttribList::AttribsType& rPrevAttribs = pPrevNode->GetCharAttribs().GetAttribs();
- EditCharAttrib* pAttrib = GetAttrib(rPrevAttribs, nAttr);
- while ( pAttrib )
- {
- if ( pAttrib->GetEnd() < nCut )
- {
- // remain unchanged...
- ;
- }
- else if ( pAttrib->GetEnd() == nCut )
- {
- // must be copied as an empty attributes.
- if ( bKeepEndingAttribs && !pAttrib->IsFeature() && !aCharAttribList.FindAttrib( pAttrib->GetItem()->Which(), 0 ) )
- {
- EditCharAttrib* pNewAttrib = MakeCharAttrib( rPool, *(pAttrib->GetItem()), 0, 0 );
- assert(pNewAttrib);
- aCharAttribList.InsertAttrib( pNewAttrib );
- }
- }
- else if ( pAttrib->IsInside( nCut ) || ( !nCut && !pAttrib->GetStart() && !pAttrib->IsFeature() ) )
- {
- // If cut is done right at the front then the attribute must be
- // kept! Has to be copied and changed.
- EditCharAttrib* pNewAttrib = MakeCharAttrib( rPool, *(pAttrib->GetItem()), 0, pAttrib->GetEnd()-nCut );
- assert(pNewAttrib);
- aCharAttribList.InsertAttrib( pNewAttrib );
- pAttrib->GetEnd() = nCut;
- }
- else
- {
- // Move all attributes in the current node (this)
- CharAttribList::AttribsType::iterator it = rPrevAttribs.begin() + nAttr;
- aCharAttribList.InsertAttrib(it->release());
- rPrevAttribs.erase(it);
- pAttrib->MoveBackward( nCut );
- nAttr--;
- }
- nAttr++;
- pAttrib = GetAttrib(rPrevAttribs, nAttr);
- }
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(aCharAttribList);
- CharAttribList::DbgCheckAttribs(pPrevNode->aCharAttribList);
-#endif
-}
-
-void ContentNode::AppendAttribs( ContentNode* pNextNode )
-{
- assert(pNextNode);
-
- sal_Int32 nNewStart = maString.getLength();
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(aCharAttribList);
- CharAttribList::DbgCheckAttribs(pNextNode->aCharAttribList);
-#endif
-
- sal_Int32 nAttr = 0;
- CharAttribList::AttribsType& rNextAttribs = pNextNode->GetCharAttribs().GetAttribs();
- EditCharAttrib* pAttrib = GetAttrib(rNextAttribs, nAttr);
- while ( pAttrib )
- {
- // Move all attributes in the current node (this)
- bool bMelted = false;
- if ( ( pAttrib->GetStart() == 0 ) && ( !pAttrib->IsFeature() ) )
- {
- // Attributes can possibly be summarized as:
- sal_Int32 nTmpAttr = 0;
- EditCharAttrib* pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr );
- while ( !bMelted && pTmpAttrib )
- {
- if ( pTmpAttrib->GetEnd() == nNewStart )
- {
- if (pTmpAttrib->Which() == pAttrib->Which())
- {
- // prevent adding 2 0-length attributes at same position
- if ((*(pTmpAttrib->GetItem()) == *(pAttrib->GetItem()))
- || (0 == pAttrib->GetLen()))
- {
- pTmpAttrib->GetEnd() =
- pTmpAttrib->GetEnd() + pAttrib->GetLen();
- rNextAttribs.erase(rNextAttribs.begin()+nAttr);
- // Unsubscribe from the pool?!
- bMelted = true;
- }
- else if (0 == pTmpAttrib->GetLen())
- {
- aCharAttribList.Remove(nTmpAttr);
- --nTmpAttr; // to cancel later increment...
- }
- }
- }
- ++nTmpAttr;
- pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr );
- }
- }
-
- if ( !bMelted )
- {
- pAttrib->GetStart() = pAttrib->GetStart() + nNewStart;
- pAttrib->GetEnd() = pAttrib->GetEnd() + nNewStart;
- CharAttribList::AttribsType::iterator it = rNextAttribs.begin() + nAttr;
- aCharAttribList.InsertAttrib(it->release());
- rNextAttribs.erase(it);
- }
- pAttrib = GetAttrib(rNextAttribs, nAttr);
- }
- // For the Attributes that just moved over:
- rNextAttribs.clear();
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(aCharAttribList);
- CharAttribList::DbgCheckAttribs(pNextNode->aCharAttribList);
-#endif
-}
-
-void ContentNode::CreateDefFont()
-{
- // First use the information from the style ...
- SfxStyleSheet* pS = aContentAttribs.GetStyleSheet();
- if ( pS )
- CreateFont( GetCharAttribs().GetDefFont(), pS->GetItemSet() );
-
- // ... then iron out the hard paragraph formatting...
- CreateFont( GetCharAttribs().GetDefFont(),
- GetContentAttribs().GetItems(), pS == nullptr );
-}
-
-void ContentNode::SetStyleSheet( SfxStyleSheet* pS, const SvxFont& rFontFromStyle )
-{
- aContentAttribs.SetStyleSheet( pS );
-
-
- // First use the information from the style ...
- GetCharAttribs().GetDefFont() = rFontFromStyle;
- // ... then iron out the hard paragraph formatting...
- CreateFont( GetCharAttribs().GetDefFont(),
- GetContentAttribs().GetItems(), pS == nullptr );
-}
-
-void ContentNode::SetStyleSheet( SfxStyleSheet* pS, bool bRecalcFont )
-{
- aContentAttribs.SetStyleSheet( pS );
- if ( bRecalcFont )
- CreateDefFont();
-}
-
-bool ContentNode::IsFeature( sal_Int32 nPos ) const
-{
- return maString[nPos] == CH_FEATURE;
-}
-
-sal_Int32 ContentNode::Len() const
-{
- return maString.getLength();
-}
-
-sal_Int32 ContentNode::GetExpandedLen() const
-{
- sal_Int32 nLen = maString.getLength();
-
- // Fields can be longer than the placeholder in the Node
- const CharAttribList::AttribsType& rAttrs = GetCharAttribs().GetAttribs();
- for (sal_Int32 nAttr = rAttrs.size(); nAttr; )
- {
- const EditCharAttrib& rAttr = *rAttrs[--nAttr];
- if (rAttr.Which() == EE_FEATURE_FIELD)
- {
- nLen += static_cast<const EditCharAttribField&>(rAttr).GetFieldValue().getLength();
- --nLen; // Standalone, to avoid corner cases when previous getLength() returns 0
- }
- }
-
- return nLen;
-}
-
-OUString ContentNode::GetExpandedText(sal_Int32 nStartPos, sal_Int32 nEndPos) const
-{
- if ( nEndPos < 0 || nEndPos > Len() )
- nEndPos = Len();
-
- DBG_ASSERT( nStartPos <= nEndPos, "Start and End reversed?" );
-
- sal_Int32 nIndex = nStartPos;
- OUStringBuffer aStr(256);
- const EditCharAttrib* pNextFeature = GetCharAttribs().FindFeature( nIndex );
- while ( nIndex < nEndPos )
- {
- sal_Int32 nEnd = nEndPos;
- if ( pNextFeature && ( pNextFeature->GetStart() < nEnd ) )
- nEnd = pNextFeature->GetStart();
- else
- pNextFeature = nullptr; // Feature does not interest the below
-
- DBG_ASSERT( nEnd >= nIndex, "End in front of the index?" );
- //!! beware of sub string length of -1
- if (nEnd > nIndex)
- aStr.append( GetString().subView(nIndex, nEnd - nIndex) );
-
- if ( pNextFeature )
- {
- switch ( pNextFeature->GetItem()->Which() )
- {
- case EE_FEATURE_TAB: aStr.append( "\t" );
- break;
- case EE_FEATURE_LINEBR: aStr.append( "\x0A" );
- break;
- case EE_FEATURE_FIELD:
- aStr.append( static_cast<const EditCharAttribField*>(pNextFeature)->GetFieldValue() );
- break;
- default: OSL_FAIL( "What feature?" );
- }
- pNextFeature = GetCharAttribs().FindFeature( ++nEnd );
- }
- nIndex = nEnd;
- }
- return aStr.makeStringAndClear();
-}
-
-void ContentNode::UnExpandPosition( sal_Int32 &rPos, bool bBiasStart )
-{
- sal_Int32 nOffset = 0;
-
- const CharAttribList::AttribsType& rAttrs = GetCharAttribs().GetAttribs();
- for (size_t nAttr = 0; nAttr < rAttrs.size(); ++nAttr )
- {
- const EditCharAttrib& rAttr = *rAttrs[nAttr];
- assert (!(nAttr < rAttrs.size() - 1) ||
- rAttrs[nAttr]->GetStart() <= rAttrs[nAttr + 1]->GetStart());
-
- nOffset = rAttr.GetStart();
-
- if (nOffset >= rPos) // happens after the position
- return;
-
- if (rAttr.Which() == EE_FEATURE_FIELD)
- {
- sal_Int32 nChunk = static_cast<const EditCharAttribField&>(rAttr).GetFieldValue().getLength();
- nChunk--; // Character representing the field in the string
-
- if (nOffset + nChunk >= rPos) // we're inside the field
- {
- if (bBiasStart)
- rPos = rAttr.GetStart();
- else
- rPos = rAttr.GetEnd();
- return;
- }
- // Adjust for the position
- rPos -= nChunk;
- }
- }
- assert (rPos <= Len());
-}
-
-/*
- * Fields are represented by a single character in the underlying string
- * and/or selection, however, they can be expanded to the full value of
- * the field. When we're dealing with selection / offsets however we need
- * to deal in character positions inside the real (unexpanded) string.
- * This method maps us back to character offsets.
- */
-void ContentNode::UnExpandPositions( sal_Int32 &rStartPos, sal_Int32 &rEndPos )
-{
- UnExpandPosition( rStartPos, true );
- UnExpandPosition( rEndPos, false );
-}
-
-void ContentNode::SetChar(sal_Int32 nPos, sal_Unicode c)
-{
- maString = maString.replaceAt(nPos, 1, rtl::OUStringChar(c));
-}
-
-void ContentNode::Insert(std::u16string_view rStr, sal_Int32 nPos)
-{
- maString = maString.replaceAt(nPos, 0, rStr);
-}
-
-void ContentNode::Append(std::u16string_view rStr)
-{
- maString += rStr;
-}
-
-void ContentNode::Erase(sal_Int32 nPos)
-{
- maString = maString.copy(0, nPos);
-}
-
-void ContentNode::Erase(sal_Int32 nPos, sal_Int32 nCount)
-{
- maString = maString.replaceAt(nPos, nCount, u"");
-}
-
-OUString ContentNode::Copy(sal_Int32 nPos) const
-{
- return maString.copy(nPos);
-}
-
-OUString ContentNode::Copy(sal_Int32 nPos, sal_Int32 nCount) const
-{
- return maString.copy(nPos, nCount);
-}
-
-sal_Unicode ContentNode::GetChar(sal_Int32 nPos) const
-{
- return maString[nPos];
-}
-
-void ContentNode::EnsureWrongList()
-{
- if (!mpWrongList)
- CreateWrongList();
-}
-
-WrongList* ContentNode::GetWrongList()
-{
- return mpWrongList.get();
-}
-
-const WrongList* ContentNode::GetWrongList() const
-{
- return mpWrongList.get();
-}
-
-void ContentNode::SetWrongList( WrongList* p )
-{
- mpWrongList.reset(p);
-}
-
-void ContentNode::CreateWrongList()
-{
- SAL_WARN_IF( mpWrongList && !mpWrongList->empty(), "editeng", "WrongList already exist!");
- if (!mpWrongList || !mpWrongList->empty())
- mpWrongList.reset(new WrongList);
-}
-
-void ContentNode::DestroyWrongList()
-{
- mpWrongList.reset();
-}
-
-void ContentNode::dumpAsXml(xmlTextWriterPtr pWriter) const
-{
- (void)xmlTextWriterStartElement(pWriter, BAD_CAST("ContentNode"));
- (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("maString"), BAD_CAST(maString.toUtf8().getStr()));
- aContentAttribs.dumpAsXml(pWriter);
- aCharAttribList.dumpAsXml(pWriter);
- (void)xmlTextWriterEndElement(pWriter);
-}
-
-
-ContentAttribs::ContentAttribs( SfxItemPool& rPool )
-: pStyle(nullptr)
-, aAttribSet( rPool )
-{
-}
-
-
-SvxTabStop ContentAttribs::FindTabStop( sal_Int32 nCurPos, sal_uInt16 nDefTab )
-{
- const SvxTabStopItem& rTabs = GetItem( EE_PARA_TABS );
- for ( sal_uInt16 i = 0; i < rTabs.Count(); i++ )
- {
- const SvxTabStop& rTab = rTabs[i];
- if ( rTab.GetTabPos() > nCurPos )
- return rTab;
- }
-
- // Determine DefTab ...
- SvxTabStop aTabStop;
- const sal_Int32 x = nCurPos / nDefTab + 1;
- aTabStop.GetTabPos() = nDefTab * x;
- return aTabStop;
-}
-
-void ContentAttribs::SetStyleSheet( SfxStyleSheet* pS )
-{
- bool bStyleChanged = ( pStyle != pS );
- pStyle = pS;
- // Only when other style sheet, not when current style sheet modified
- if ( !(pStyle && bStyleChanged) )
- return;
-
- // Selectively remove the attributes from the paragraph formatting
- // which are specified in the style, so that the attributes of the
- // style can have an affect.
- const SfxItemSet& rStyleAttribs = pStyle->GetItemSet();
- for ( sal_uInt16 nWhich = EE_PARA_START; nWhich <= EE_CHAR_END; nWhich++ )
- {
- // Don't change bullet on/off
- if ( ( nWhich != EE_PARA_BULLETSTATE ) && ( rStyleAttribs.GetItemState( nWhich ) == SfxItemState::SET ) )
- aAttribSet.ClearItem( nWhich );
- }
-}
-
-const SfxPoolItem& ContentAttribs::GetItem( sal_uInt16 nWhich ) const
-{
- // Hard paragraph attributes take precedence!
- const SfxItemSet* pTakeFrom = &aAttribSet;
- if ( pStyle && ( aAttribSet.GetItemState( nWhich, false ) != SfxItemState::SET ) )
- pTakeFrom = &pStyle->GetItemSet();
-
- return pTakeFrom->Get( nWhich );
-}
-
-bool ContentAttribs::HasItem( sal_uInt16 nWhich ) const
-{
- bool bHasItem = false;
- if ( aAttribSet.GetItemState( nWhich, false ) == SfxItemState::SET )
- bHasItem = true;
- else if ( pStyle && pStyle->GetItemSet().GetItemState( nWhich ) == SfxItemState::SET )
- bHasItem = true;
-
- return bHasItem;
-}
-
-void ContentAttribs::dumpAsXml(xmlTextWriterPtr pWriter) const
-{
- (void)xmlTextWriterStartElement(pWriter, BAD_CAST("ContentAttribs"));
- (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("style"), "%s", pStyle->GetName().toUtf8().getStr());
- aAttribSet.dumpAsXml(pWriter);
- (void)xmlTextWriterEndElement(pWriter);
-}
-
-
-ItemList::ItemList() : CurrentItem( 0 )
-{
-}
-
-const SfxPoolItem* ItemList::First()
-{
- CurrentItem = 0;
- return aItemPool.empty() ? nullptr : aItemPool[ 0 ];
-}
-
-const SfxPoolItem* ItemList::Next()
-{
- if ( CurrentItem + 1 < static_cast<sal_Int32>(aItemPool.size()) )
- {
- ++CurrentItem;
- return aItemPool[ CurrentItem ];
- }
- return nullptr;
-}
-
-void ItemList::Insert( const SfxPoolItem* pItem )
-{
- aItemPool.push_back( pItem );
- CurrentItem = aItemPool.size() - 1;
-}
-
-
EditDoc::EditDoc( SfxItemPool* pPool ) :
- nLastCache(0),
- pItemPool(pPool ? pPool : new EditEngineItemPool()),
- nDefTab(DEFTAB),
- bIsVertical(false),
+ mnLastCache(0),
+ mpItemPool(pPool ? pPool : new EditEngineItemPool()),
+ mnDefTab(DEFTAB),
+ mbIsVertical(false),
mnRotation(TextRotation::NONE),
- bIsFixedCellHeight(false),
- bModified(false),
- bDisableAttributeExpanding(false)
+ mbIsFixedCellHeight(false),
+ mbModified(false),
+ mbDisableAttributeExpanding(false)
{
// Don't create an empty node, Clear() will be called in EditEngine-CTOR
};
EditDoc::~EditDoc()
{
- ImplDestroyContents();
-}
-
-namespace {
-
-class RemoveEachItemFromPool
-{
- EditDoc& mrDoc;
-public:
- explicit RemoveEachItemFromPool(EditDoc& rDoc) : mrDoc(rDoc) {}
- void operator() (const std::unique_ptr<ContentNode>& rNode)
- {
- mrDoc.RemoveItemsFromPool(*rNode);
- }
-};
-
-struct ClearSpellErrorsHandler
-{
- void operator() (std::unique_ptr<ContentNode> const & rNode)
- {
- rNode->DestroyWrongList();
- }
-};
-
-}
-
-void EditDoc::ImplDestroyContents()
-{
- std::for_each(maContents.begin(), maContents.end(), RemoveEachItemFromPool(*this));
maContents.clear();
}
-void EditDoc::RemoveItemsFromPool(const ContentNode& rNode)
-{
- for (sal_Int32 nAttr = 0; nAttr < rNode.GetCharAttribs().Count(); ++nAttr)
- {
- const EditCharAttrib& rAttr = *rNode.GetCharAttribs().GetAttribs()[nAttr];
- GetItemPool().Remove(*rAttr.GetItem());
- }
-}
-
void CreateFont( SvxFont& rFont, const SfxItemSet& rSet, bool bSearchInParent, SvtScriptType nScriptType )
{
vcl::Font aPrevFont( rFont );
rFont.SetAlignment( ALIGN_BASELINE );
- rFont.SetTransparent( true );
sal_uInt16 nWhich_FontInfo = GetScriptItemId( EE_CHAR_FONTINFO, nScriptType );
sal_uInt16 nWhich_Language = GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType );
@@ -1960,7 +743,11 @@ void CreateFont( SvxFont& rFont, const SfxItemSet& rSet, bool bSearchInParent, S
if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_COLOR ) == SfxItemState::SET ) )
rFont.SetColor( rSet.Get( EE_CHAR_COLOR ).GetValue() );
if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_BKGCOLOR ) == SfxItemState::SET ) )
- rFont.SetFillColor( rSet.Get( EE_CHAR_BKGCOLOR ).GetValue() );
+ {
+ auto& aColor = rSet.Get( EE_CHAR_BKGCOLOR ).GetValue();
+ rFont.SetTransparent(aColor.IsTransparent());
+ rFont.SetFillColor(aColor);
+ }
if ( bSearchInParent || ( rSet.GetItemState( nWhich_FontHeight ) == SfxItemState::SET ) )
rFont.SetFontSize( Size( rFont.GetFontSize().Width(), static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich_FontHeight ) ).GetHeight() ) );
if ( bSearchInParent || ( rSet.GetItemState( nWhich_Weight ) == SfxItemState::SET ) )
@@ -2013,74 +800,63 @@ void CreateFont( SvxFont& rFont, const SfxItemSet& rSet, bool bSearchInParent, S
void EditDoc::CreateDefFont( bool bUseStyles )
{
SfxItemSetFixed<EE_PARA_START, EE_CHAR_END> aTmpSet( GetItemPool() );
- CreateFont( aDefFont, aTmpSet );
- aDefFont.SetVertical( IsEffectivelyVertical() );
- aDefFont.SetOrientation( Degree10(IsEffectivelyVertical() ? (IsTopToBottom() ? 2700 : 900) : 0) );
+ CreateFont(maDefFont, aTmpSet);
+ maDefFont.SetVertical( IsEffectivelyVertical() );
+ maDefFont.SetOrientation( Degree10(IsEffectivelyVertical() ? (IsTopToBottom() ? 2700 : 900) : 0) );
- for ( sal_Int32 nNode = 0; nNode < Count(); nNode++ )
+ for (std::unique_ptr<ContentNode>& pNode : maContents)
{
- ContentNode* pNode = GetObject( nNode );
- pNode->GetCharAttribs().GetDefFont() = aDefFont;
- if ( bUseStyles )
+ pNode->GetCharAttribs().GetDefFont() = maDefFont;
+ if (bUseStyles)
pNode->CreateDefFont();
}
}
bool EditDoc::IsEffectivelyVertical() const
{
- return (bIsVertical && mnRotation == TextRotation::NONE) ||
- (!bIsVertical && mnRotation != TextRotation::NONE);
+ return (mbIsVertical && mnRotation == TextRotation::NONE) ||
+ (!mbIsVertical && mnRotation != TextRotation::NONE);
}
bool EditDoc::IsTopToBottom() const
{
- return (bIsVertical && mnRotation == TextRotation::NONE) ||
- (!bIsVertical && mnRotation == TextRotation::TOPTOBOTTOM);
+ return (mbIsVertical && mnRotation == TextRotation::NONE) ||
+ (!mbIsVertical && mnRotation == TextRotation::TOPTOBOTTOM);
}
bool EditDoc::GetVertical() const
{
- return bIsVertical;
+ return mbIsVertical;
}
-sal_Int32 EditDoc::GetPos(const ContentNode* p) const
+sal_Int32 EditDoc::GetPos(const ContentNode* pContentNode) const
{
- return FastGetPos(maContents, p, nLastCache);
+ return FastGetPos(maContents, pContentNode, mnLastCache);
}
const ContentNode* EditDoc::GetObject(sal_Int32 nPos) const
{
- return 0 <= nPos && nPos < static_cast<sal_Int32>(maContents.size()) ? maContents[nPos].get() : nullptr;
+ return 0 <= nPos && o3tl::make_unsigned(nPos) < maContents.size() ? maContents[nPos].get() : nullptr;
}
ContentNode* EditDoc::GetObject(sal_Int32 nPos)
{
- return 0 <= nPos && nPos < static_cast<sal_Int32>(maContents.size()) ? maContents[nPos].get() : nullptr;
+ return 0 <= nPos && o3tl::make_unsigned(nPos) < maContents.size() ? maContents[nPos].get() : nullptr;
}
-const ContentNode* EditDoc::operator[](sal_Int32 nPos) const
-{
- return GetObject(nPos);
-}
-
-ContentNode* EditDoc::operator[](sal_Int32 nPos)
-{
- return GetObject(nPos);
-}
-
-void EditDoc::Insert(sal_Int32 nPos, ContentNode* p)
+void EditDoc::Insert(sal_Int32 nPos, std::unique_ptr<ContentNode> pNode)
{
if (nPos < 0 || nPos == SAL_MAX_INT32)
{
SAL_WARN( "editeng", "EditDoc::Insert - overflow pos " << nPos);
return;
}
- maContents.insert(maContents.begin()+nPos, std::unique_ptr<ContentNode>(p));
+ maContents.insert(maContents.begin()+nPos, std::move(pNode));
}
void EditDoc::Remove(sal_Int32 nPos)
{
- if (nPos < 0 || nPos >= static_cast<sal_Int32>(maContents.size()))
+ if (nPos < 0 || o3tl::make_unsigned(nPos) >= maContents.size())
{
SAL_WARN( "editeng", "EditDoc::Remove - out of bounds pos " << nPos);
return;
@@ -2088,15 +864,17 @@ void EditDoc::Remove(sal_Int32 nPos)
maContents.erase(maContents.begin() + nPos);
}
-void EditDoc::Release(sal_Int32 nPos)
+std::unique_ptr<ContentNode> EditDoc::Release(sal_Int32 nPos)
{
- if (nPos < 0 || nPos >= static_cast<sal_Int32>(maContents.size()))
+ if (nPos < 0 || o3tl::make_unsigned(nPos) >= maContents.size())
{
SAL_WARN( "editeng", "EditDoc::Release - out of bounds pos " << nPos);
- return;
+ return nullptr;
}
- (void)maContents[nPos].release();
+
+ std::unique_ptr<ContentNode> pNode = std::move(maContents[nPos]);
maContents.erase(maContents.begin() + nPos);
+ return pNode;
}
sal_Int32 EditDoc::Count() const
@@ -2168,21 +946,20 @@ EditPaM EditDoc::GetEndPaM() const
sal_Int32 EditDoc::GetTextLen() const
{
- sal_Int32 nLen = 0;
- for ( sal_Int32 nNode = 0; nNode < Count(); nNode++ )
+ sal_Int32 nLength = 0;
+ for (auto const& pContent : maContents)
{
- const ContentNode* pNode = GetObject( nNode );
- nLen += pNode->GetExpandedLen();
+ nLength += pContent->GetExpandedLen();
}
- return nLen;
+ return nLength;
}
EditPaM EditDoc::Clear()
{
- ImplDestroyContents();
+ maContents.clear();
- ContentNode* pNode = new ContentNode( GetItemPool() );
- Insert(0, pNode);
+ ContentNode* pNode = new ContentNode(GetItemPool());
+ Insert(0, std::unique_ptr<ContentNode>(pNode));
CreateDefFont(false);
@@ -2191,6 +968,17 @@ EditPaM EditDoc::Clear()
return EditPaM( pNode, 0 );
}
+namespace
+{
+struct ClearSpellErrorsHandler
+{
+ void operator() (std::unique_ptr<ContentNode> const & rNode)
+ {
+ rNode->DestroyWrongList();
+ }
+};
+}
+
void EditDoc::ClearSpellErrors()
{
std::for_each(maContents.begin(), maContents.end(), ClearSpellErrorsHandler());
@@ -2198,13 +986,9 @@ void EditDoc::ClearSpellErrors()
void EditDoc::SetModified( bool b )
{
- if (bModified == b)
- return;
- bModified = b;
- if ( bModified )
- {
- aModifyHdl.Call( nullptr );
- }
+ mbModified = b;
+ if (mbModified)
+ maModifyHdl.Call(nullptr);
}
EditPaM EditDoc::RemoveText()
@@ -2215,10 +999,10 @@ EditPaM EditDoc::RemoveText()
SfxItemSet aPrevSet( pPrevFirstNode->GetContentAttribs().GetItems() );
vcl::Font aPrevFont( pPrevFirstNode->GetCharAttribs().GetDefFont() );
- ImplDestroyContents();
+ maContents.clear();
- ContentNode* pNode = new ContentNode( GetItemPool() );
- Insert(0, pNode);
+ ContentNode* pNode = new ContentNode(GetItemPool());
+ Insert(0, std::unique_ptr<ContentNode>(pNode));
pNode->SetStyleSheet(pPrevStyle, false);
pNode->GetContentAttribs().GetItems().Set( aPrevSet );
@@ -2226,19 +1010,19 @@ EditPaM EditDoc::RemoveText()
SetModified(true);
- return EditPaM( pNode, 0 );
+ return EditPaM(pNode, 0);
}
-EditPaM EditDoc::InsertText( EditPaM aPaM, const OUString& rStr )
+EditPaM EditDoc::InsertText( EditPaM aPaM, std::u16string_view rStr )
{
- DBG_ASSERT( rStr.indexOf( 0x0A ) == -1, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
- DBG_ASSERT( rStr.indexOf( 0x0D ) == -1, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
- DBG_ASSERT( rStr.indexOf( '\t' ) == -1, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
+ DBG_ASSERT( rStr.find( 0x0A ) == std::u16string_view::npos, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
+ DBG_ASSERT( rStr.find( 0x0D ) == std::u16string_view::npos, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
+ DBG_ASSERT( rStr.find( '\t' ) == std::u16string_view::npos, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
assert(aPaM.GetNode());
aPaM.GetNode()->Insert( rStr, aPaM.GetIndex() );
- aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), rStr.getLength(), GetItemPool() );
- aPaM.SetIndex( aPaM.GetIndex() + rStr.getLength() );
+ aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), rStr.size() );
+ aPaM.SetIndex( aPaM.GetIndex() + rStr.size() );
SetModified( true );
@@ -2260,7 +1044,7 @@ EditPaM EditDoc::InsertParaBreak( EditPaM aPaM, bool bKeepEndingAttribs )
aContentAttribs.GetItems().Put( SfxBoolItem( EE_PARA_BULLETSTATE, true) );
// ContentNode constructor copies also the paragraph attributes
- ContentNode* pNode = new ContentNode( aStr, aContentAttribs );
+ ContentNode* pNode = new ContentNode(aStr, std::move(aContentAttribs));
// Copy the Default Font
pNode->GetCharAttribs().GetDefFont() = aPaM.GetNode()->GetCharAttribs().GetDefFont();
@@ -2278,7 +1062,7 @@ EditPaM EditDoc::InsertParaBreak( EditPaM aPaM, bool bKeepEndingAttribs )
// Character attributes may need to be copied or trimmed:
pNode->CopyAndCutAttribs( aPaM.GetNode(), GetItemPool(), bKeepEndingAttribs );
- Insert(nPos+1, pNode);
+ Insert(nPos+1, std::unique_ptr<ContentNode>(pNode));
SetModified(true);
@@ -2292,7 +1076,7 @@ EditPaM EditDoc::InsertFeature( EditPaM aPaM, const SfxPoolItem& rItem )
assert(aPaM.GetNode());
aPaM.GetNode()->Insert( rtl::OUStringChar(CH_FEATURE), aPaM.GetIndex() );
- aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), 1, GetItemPool() );
+ aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), 1 );
// Create a feature-attribute for the feature...
EditCharAttrib* pAttrib = MakeCharAttrib( GetItemPool(), rItem, aPaM.GetIndex(), aPaM.GetIndex()+1 );
@@ -2315,7 +1099,6 @@ EditPaM EditDoc::ConnectParagraphs( ContentNode* pLeft, ContentNode* pRight )
pLeft->Append(pRight->GetString());
// the one to the right disappears.
- RemoveItemsFromPool(*pRight);
sal_Int32 nRight = GetPos( pRight );
Remove( nRight );
@@ -2328,7 +1111,7 @@ void EditDoc::RemoveChars( EditPaM aPaM, sal_Int32 nChars )
{
// Maybe remove Features!
aPaM.GetNode()->Erase( aPaM.GetIndex(), nChars );
- aPaM.GetNode()->CollapseAttribs( aPaM.GetIndex(), nChars, GetItemPool() );
+ aPaM.GetNode()->CollapseAttribs( aPaM.GetIndex(), nChars );
SetModified( true );
}
@@ -2351,7 +1134,7 @@ void EditDoc::InsertAttribInSelection( ContentNode* pNode, sal_Int32 nStart, sal
// tdf#132288 By default inserting an attribute beside another that is of
// the same type expands the original instead of inserting another. But the
// spell check dialog doesn't want that behaviour
- if (bDisableAttributeExpanding)
+ if (mbDisableAttributeExpanding)
{
pStartingAttrib = nullptr;
pEndingAttrib = nullptr;
@@ -2363,7 +1146,6 @@ void EditDoc::InsertAttribInSelection( ContentNode* pNode, sal_Int32 nStart, sal
{
// Will become a large Attribute.
pEndingAttrib->GetEnd() = pStartingAttrib->GetEnd();
- GetItemPool().Remove( *(pStartingAttrib->GetItem()) );
pNode->GetCharAttribs().Remove(pStartingAttrib);
}
else if ( pStartingAttrib && ( *(pStartingAttrib->GetItem()) == rPoolItem ) )
@@ -2407,7 +1189,7 @@ bool EditDoc::RemoveAttribs( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEn
#endif
// iterate over the attributes ...
- sal_Int32 nAttr = 0;
+ std::size_t nAttr = 0;
CharAttribList::AttribsType& rAttribs = pNode->GetCharAttribs().GetAttribs();
EditCharAttrib* pAttr = GetAttrib(rAttribs, nAttr);
while ( pAttr )
@@ -2485,11 +1267,12 @@ bool EditDoc::RemoveAttribs( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEn
{
DBG_ASSERT( ( pAttr != rpStarting ) && ( pAttr != rpEnding ), "Delete and retain the same attribute?" );
DBG_ASSERT( !pAttr->IsFeature(), "RemoveAttribs: Remove a feature?!" );
- GetItemPool().Remove( *pAttr->GetItem() );
rAttribs.erase(rAttribs.begin()+nAttr);
- nAttr--;
}
- nAttr++;
+ else
+ {
+ nAttr++;
+ }
pAttr = GetAttrib(rAttribs, nAttr);
}
@@ -2567,7 +1350,7 @@ void EditDoc::FindAttribs( ContentNode* pNode, sal_Int32 nStartPos, sal_Int32 nE
assert(pNode);
DBG_ASSERT( nStartPos <= nEndPos, "Invalid region!" );
- sal_uInt16 nAttr = 0;
+ std::size_t nAttr = 0;
EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
// No Selection...
if ( nStartPos == nEndPos )
@@ -2694,319 +1477,14 @@ void EditDoc::dumpAsXml(xmlTextWriterPtr pWriter) const
}
}
-
-namespace {
-
-struct LessByStart
-{
- bool operator() (const std::unique_ptr<EditCharAttrib>& left, const std::unique_ptr<EditCharAttrib>& right) const
- {
- return left->GetStart() < right->GetStart();
- }
-};
-
-}
-
-CharAttribList::CharAttribList()
-: bHasEmptyAttribs(false)
-{
-}
-
-CharAttribList::~CharAttribList()
-{
-}
-
-void CharAttribList::InsertAttrib( EditCharAttrib* pAttrib )
-{
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-// optimize: binary search? !
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- // Maybe just simply iterate backwards:
- // The most common and critical case: Attributes are already sorted
- // (InsertTextObject!) binary search would not be optimal here.
- // => Would bring something!
-
- const sal_Int32 nStart = pAttrib->GetStart(); // may be better for Comp.Opt.
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(*this);
-#endif
-
- if ( pAttrib->IsEmpty() )
- bHasEmptyAttribs = true;
-
- bool bInsert(true);
- for (sal_Int32 i = 0, n = aAttribs.size(); i < n; ++i)
- {
- const EditCharAttrib& rCurAttrib = *aAttribs[i];
- if (rCurAttrib.GetStart() > nStart)
- {
- aAttribs.insert(aAttribs.begin()+i, std::unique_ptr<EditCharAttrib>(pAttrib));
- bInsert = false;
- break;
- }
- }
-
- if (bInsert) aAttribs.push_back(std::unique_ptr<EditCharAttrib>(pAttrib));
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(*this);
-#endif
-}
-
-void CharAttribList::ResortAttribs()
-{
- std::sort(aAttribs.begin(), aAttribs.end(), LessByStart());
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(*this);
-#endif
-}
-
-void CharAttribList::OptimizeRanges( SfxItemPool& rItemPool )
-{
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(*this);
-#endif
- for (sal_Int32 i = 0; i < static_cast<sal_Int32>(aAttribs.size()); ++i)
- {
- EditCharAttrib& rAttr = *aAttribs[i];
- for (sal_Int32 nNext = i+1; nNext < static_cast<sal_Int32>(aAttribs.size()); ++nNext)
- {
- EditCharAttrib& rNext = *aAttribs[nNext];
- if (!rAttr.IsFeature() && rNext.GetStart() == rAttr.GetEnd() && rNext.Which() == rAttr.Which())
- {
- if (*rNext.GetItem() == *rAttr.GetItem())
- {
- rAttr.GetEnd() = rNext.GetEnd();
- rItemPool.Remove(*rNext.GetItem());
- aAttribs.erase(aAttribs.begin()+nNext);
- }
- break; // only 1 attr with same which can start here.
- }
- else if (rNext.GetStart() > rAttr.GetEnd())
- {
- break;
- }
- }
- }
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
- CharAttribList::DbgCheckAttribs(*this);
-#endif
-}
-
-sal_Int32 CharAttribList::Count() const
-{
- return aAttribs.size();
-}
-
-const EditCharAttrib* CharAttribList::FindAttrib( sal_uInt16 nWhich, sal_Int32 nPos ) const
-{
- // Backwards, if one ends where the next starts.
- // => The starting one is the valid one ...
- AttribsType::const_reverse_iterator it = std::find_if(aAttribs.rbegin(), aAttribs.rend(),
- [&nWhich, &nPos](const AttribsType::value_type& rxAttr) {
- return rxAttr->Which() == nWhich && rxAttr->IsIn(nPos); });
- if (it != aAttribs.rend())
- {
- const EditCharAttrib& rAttr = **it;
- return &rAttr;
- }
- return nullptr;
-}
-
-EditCharAttrib* CharAttribList::FindAttrib( sal_uInt16 nWhich, sal_Int32 nPos )
-{
- // Backwards, if one ends where the next starts.
- // => The starting one is the valid one ...
- AttribsType::reverse_iterator it = std::find_if(aAttribs.rbegin(), aAttribs.rend(),
- [&nWhich, &nPos](AttribsType::value_type& rxAttr) {
- return rxAttr->Which() == nWhich && rxAttr->IsIn(nPos); });
- if (it != aAttribs.rend())
- {
- EditCharAttrib& rAttr = **it;
- return &rAttr;
- }
- return nullptr;
-}
-
-const EditCharAttrib* CharAttribList::FindNextAttrib( sal_uInt16 nWhich, sal_Int32 nFromPos ) const
-{
- assert(nWhich);
- for (auto const& attrib : aAttribs)
- {
- const EditCharAttrib& rAttr = *attrib;
- if (rAttr.GetStart() >= nFromPos && rAttr.Which() == nWhich)
- return &rAttr;
- }
- return nullptr;
-}
-
-bool CharAttribList::HasAttrib( sal_Int32 nStartPos, sal_Int32 nEndPos ) const
-{
- return std::any_of(aAttribs.rbegin(), aAttribs.rend(),
- [&nStartPos, &nEndPos](const AttribsType::value_type& rxAttr) {
- return rxAttr->GetStart() < nEndPos && rxAttr->GetEnd() > nStartPos; });
-}
-
-
-namespace {
-
-class FindByAddress
-{
- const EditCharAttrib* mpAttr;
-public:
- explicit FindByAddress(const EditCharAttrib* p) : mpAttr(p) {}
- bool operator() (const std::unique_ptr<EditCharAttrib>& r) const
- {
- return r.get() == mpAttr;
- }
-};
-
-}
-
-void CharAttribList::Remove(const EditCharAttrib* p)
-{
- AttribsType::iterator it = std::find_if(aAttribs.begin(), aAttribs.end(), FindByAddress(p));
- if (it != aAttribs.end())
- aAttribs.erase(it);
-}
-
-void CharAttribList::Remove(sal_Int32 nPos)
-{
- if (nPos >= static_cast<sal_Int32>(aAttribs.size()))
- return;
-
- aAttribs.erase(aAttribs.begin()+nPos);
-}
-
-void CharAttribList::SetHasEmptyAttribs(bool b)
-{
- bHasEmptyAttribs = b;
-}
-
-bool CharAttribList::HasBoundingAttrib( sal_Int32 nBound ) const
-{
- // Backwards, if one ends where the next starts.
- // => The starting one is the valid one ...
- AttribsType::const_reverse_iterator it = aAttribs.rbegin(), itEnd = aAttribs.rend();
- for (; it != itEnd; ++it)
- {
- const EditCharAttrib& rAttr = **it;
- if (rAttr.GetEnd() < nBound)
- return false;
-
- if (rAttr.GetStart() == nBound || rAttr.GetEnd() == nBound)
- return true;
- }
- return false;
-}
-
-EditCharAttrib* CharAttribList::FindEmptyAttrib( sal_uInt16 nWhich, sal_Int32 nPos )
-{
- if ( !bHasEmptyAttribs )
- return nullptr;
-
- for (const std::unique_ptr<EditCharAttrib>& rAttr : aAttribs)
- {
- if (rAttr->GetStart() == nPos && rAttr->GetEnd() == nPos && rAttr->Which() == nWhich)
- return rAttr.get();
- }
- return nullptr;
-}
-
-namespace {
-
-class FindByStartPos
-{
- sal_Int32 mnPos;
-public:
- explicit FindByStartPos(sal_Int32 nPos) : mnPos(nPos) {}
- bool operator() (const std::unique_ptr<EditCharAttrib>& r) const
- {
- return r->GetStart() >= mnPos;
- }
-};
-
-}
-
-const EditCharAttrib* CharAttribList::FindFeature( sal_Int32 nPos ) const
-{
- // First, find the first attribute that starts at or after specified position.
- AttribsType::const_iterator it =
- std::find_if(aAttribs.begin(), aAttribs.end(), FindByStartPos(nPos));
-
- if (it == aAttribs.end())
- // All attributes are before the specified position.
- return nullptr;
-
- // And find the first attribute with feature.
- it = std::find_if(it, aAttribs.end(), [](const std::unique_ptr<EditCharAttrib>& aAttrib) { return aAttrib->IsFeature(); } );
- return it == aAttribs.end() ? nullptr : it->get();
-}
-
-namespace {
-
-class RemoveEmptyAttrItem
-{
- SfxItemPool& mrItemPool;
-public:
- explicit RemoveEmptyAttrItem(SfxItemPool& rPool) : mrItemPool(rPool) {}
- void operator() (const std::unique_ptr<EditCharAttrib>& r)
- {
- if (r->IsEmpty())
- mrItemPool.Remove(*r->GetItem());
- }
-};
-
-}
-
-void CharAttribList::DeleteEmptyAttribs( SfxItemPool& rItemPool )
-{
- std::for_each(aAttribs.begin(), aAttribs.end(), RemoveEmptyAttrItem(rItemPool));
- aAttribs.erase( std::remove_if(aAttribs.begin(), aAttribs.end(), [](const std::unique_ptr<EditCharAttrib>& aAttrib) { return aAttrib->IsEmpty(); } ), aAttribs.end() );
- bHasEmptyAttribs = false;
-}
-
-#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
-void CharAttribList::DbgCheckAttribs(CharAttribList const& rAttribs)
-{
- std::set<std::pair<sal_Int32, sal_uInt16>> zero_set;
- for (const std::unique_ptr<EditCharAttrib>& rAttr : rAttribs.aAttribs)
- {
- assert(rAttr->GetStart() <= rAttr->GetEnd());
- assert(!rAttr->IsFeature() || rAttr->GetLen() == 1);
- if (0 == rAttr->GetLen())
- {
- // not sure if 0-length attributes allowed at all in non-empty para?
- assert(zero_set.insert(std::make_pair(rAttr->GetStart(), rAttr->Which())).second && "duplicate 0-length attribute detected");
- }
- }
- CheckOrderedList(rAttribs.GetAttribs());
-}
-#endif
-
-void CharAttribList::dumpAsXml(xmlTextWriterPtr pWriter) const
-{
- (void)xmlTextWriterStartElement(pWriter, BAD_CAST("CharAttribList"));
- for (auto const & i : aAttribs) {
- i->dumpAsXml(pWriter);
- }
- (void)xmlTextWriterEndElement(pWriter);
-}
-
EditEngineItemPool::EditEngineItemPool()
- : SfxItemPool( "EditEngineItemPool", EE_ITEMS_START, EE_ITEMS_END,
- aItemInfos, nullptr )
+: SfxItemPool("EditEngineItemPool")
{
- m_xDefItems = EditDLL::Get().GetGlobalData()->GetDefItems();
- SetDefaults(&m_xDefItems->getDefaults());
+ registerItemInfoPackage(getItemInfoPackageEditEngine());
}
EditEngineItemPool::~EditEngineItemPool()
{
- ClearDefaults();
SetSecondaryPool(nullptr);
}