Kaydet (Commit) eb92dc08 authored tarafından Michael Stahl's avatar Michael Stahl

sw_redlinehide_4a: SwAutoFormat iterates frames, not nodes

In order to not require moving the delete redlines out of the document
body, rely on the DeleteSel() implementation skipping over the redlines,
and also pass the shell's layout to the various SwDoc functions that
are called.

Previously, the redlines were not deleted by DeleteSel() due to
SwAutoFormat setting RedlineFlags::Ignore.

Change-Id: Ib05ecb534993368d81f66e70124617968b4c8e9a
üst b9a5d497
...@@ -1806,6 +1806,9 @@ void SwDoc::SetTextFormatCollByAutoFormat( const SwPosition& rPos, sal_uInt16 nP ...@@ -1806,6 +1806,9 @@ void SwDoc::SetTextFormatCollByAutoFormat( const SwPosition& rPos, sal_uInt16 nP
{ {
aPam.SetMark(); aPam.SetMark();
aPam.GetMark()->nContent.Assign(pTNd, pTNd->GetText().getLength()); aPam.GetMark()->nContent.Assign(pTNd, pTNd->GetText().getLength());
// sw_redlinehide: don't need layout currently because the only caller
// passes in the properties node
assert(static_cast<SwTextFrame const*>(pTNd->getLayoutFrame(nullptr))->GetTextNodeForParaProps() == pTNd);
getIDocumentContentOperations().InsertItemSet( aPam, *pSet ); getIDocumentContentOperations().InsertItemSet( aPam, *pSet );
} }
} }
......
...@@ -134,34 +134,37 @@ class SwAutoFormat ...@@ -134,34 +134,37 @@ class SwAutoFormat
{ return (' ' == c || '\t' == c || 0x0a == c|| 0x3000 == c /* Jap. space */); } { return (' ' == c || '\t' == c || 0x0a == c|| 0x3000 == c /* Jap. space */); }
void SetColl( sal_uInt16 nId, bool bHdLineOrText = false ); void SetColl( sal_uInt16 nId, bool bHdLineOrText = false );
OUString GoNextPara(); void GoNextPara();
bool HasObjects( const SwNode& rNd ); bool HasObjects(const SwTextFrame &);
// TextNode methods // TextNode methods
const SwTextNode* GetNextNode() const; const SwTextFrame * GetNextNode(bool isCheckEnd = true) const;
static bool IsEmptyLine( const SwTextNode& rNd ) static bool IsEmptyLine(const SwTextFrame & rFrame)
{ return rNd.GetText().isEmpty() || {
rNd.GetText().getLength() == GetLeadingBlanks( rNd.GetText() ); } return rFrame.GetText().isEmpty()
|| rFrame.GetText().getLength() == GetLeadingBlanks(rFrame.GetText());
bool IsOneLine( const SwTextNode& ) const; }
bool IsFastFullLine( const SwTextNode& ) const;
bool IsNoAlphaLine( const SwTextNode&) const; bool IsOneLine(const SwTextFrame &) const;
bool IsEnumericChar( const SwTextNode&) const; bool IsFastFullLine(const SwTextFrame &) const;
static bool IsBlanksInString( const SwTextNode&); bool IsNoAlphaLine(const SwTextFrame &) const;
sal_uInt16 CalcLevel( const SwTextNode&, sal_uInt16 *pDigitLvl = nullptr ) const; bool IsEnumericChar(const SwTextFrame &) const;
sal_Int32 GetBigIndent( sal_Int32& rCurrentSpacePos ) const; static bool IsBlanksInString(const SwTextFrame&);
sal_uInt16 CalcLevel(const SwTextFrame&, sal_uInt16 *pDigitLvl = nullptr) const;
sal_Int32 GetBigIndent(TextFrameIndex & rCurrentSpacePos) const;
static OUString DelLeadingBlanks(const OUString& rStr); static OUString DelLeadingBlanks(const OUString& rStr);
static OUString DelTrailingBlanks( const OUString& rStr ); static OUString DelTrailingBlanks( const OUString& rStr );
static sal_Int32 GetLeadingBlanks( const OUString& rStr ); static sal_Int32 GetLeadingBlanks( const OUString& rStr );
static sal_Int32 GetTrailingBlanks( const OUString& rStr ); static sal_Int32 GetTrailingBlanks( const OUString& rStr );
bool IsFirstCharCapital( const SwTextNode& rNd ) const; bool IsFirstCharCapital(const SwTextFrame & rNd) const;
sal_uInt16 GetDigitLevel( const SwTextNode& rTextNd, sal_Int32& rPos, sal_uInt16 GetDigitLevel(const SwTextFrame& rFrame, TextFrameIndex& rPos,
OUString* pPrefix = nullptr, OUString* pPostfix = nullptr, OUString* pPrefix = nullptr, OUString* pPostfix = nullptr,
OUString* pNumTypes = nullptr ) const; OUString* pNumTypes = nullptr ) const;
/// get the FORMATTED TextFrame /// get the FORMATTED TextFrame
SwTextFrame* GetFrame( const SwTextNode& rTextNd ) const; SwTextFrame* GetFrame( const SwTextNode& rTextNd ) const;
SwTextFrame * EnsureFormatted(SwTextFrame const&) const;
void BuildIndent(); void BuildIndent();
void BuildText(); void BuildText();
...@@ -170,11 +173,10 @@ class SwAutoFormat ...@@ -170,11 +173,10 @@ class SwAutoFormat
void BuildNegIndent( SwTwips nSpaces ); void BuildNegIndent( SwTwips nSpaces );
void BuildHeadLine( sal_uInt16 nLvl ); void BuildHeadLine( sal_uInt16 nLvl );
static bool HasSelBlanks( SwPaM& rPam ); static bool HasBreakAttr(const SwTextFrame &);
static bool HasBreakAttr( const SwTextNode& );
void DeleteSel( SwPaM& rPam ); void DeleteSel( SwPaM& rPam );
void DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect); void DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect);
bool DeleteJoinCurNextPara( const OUString& rNxtPara ); bool DeleteJoinCurNextPara(SwTextFrame const* pNextFrame, bool bIgnoreLeadingBlanks = false);
/// delete in the node start and/or end /// delete in the node start and/or end
void DeleteLeadingTrailingBlanks( bool bStart = true, bool bEnd = true ); void DeleteLeadingTrailingBlanks( bool bStart = true, bool bEnd = true );
void DelEmptyLine( bool bTstNextPara = true ); void DelEmptyLine( bool bTstNextPara = true );
...@@ -186,19 +188,22 @@ class SwAutoFormat ...@@ -186,19 +188,22 @@ class SwAutoFormat
/// execute AutoCorrect on current TextNode /// execute AutoCorrect on current TextNode
void AutoCorrect( sal_Int32 nSttPos = 0 ); void AutoCorrect( sal_Int32 nSttPos = 0 );
bool CanJoin( const SwTextNode* pTextNd ) const bool CanJoin(const SwTextFrame * pNextFrame) const
{ {
return !m_bEnd && pTextNd && return !m_bEnd && pNextFrame
!IsEmptyLine( *pTextNd ) && && !IsEmptyLine(*pNextFrame)
!IsNoAlphaLine( *pTextNd) && && !IsNoAlphaLine(*pNextFrame)
!IsEnumericChar( *pTextNd ) && && !IsEnumericChar(*pNextFrame)
((COMPLETE_STRING - 50 - pTextNd->GetText().getLength()) > // check the last / first nodes here...
m_pCurTextNd->GetText().getLength()) && && ((COMPLETE_STRING - 50 - pNextFrame->GetTextNodeFirst()->GetText().getLength())
!HasBreakAttr( *pTextNd ); > (m_pCurTextFrame->GetMergedPara()
? m_pCurTextFrame->GetMergedPara()->pLastNode
: m_pCurTextNd)->GetText().getLength())
&& !HasBreakAttr(*pNextFrame);
} }
/// is a dot at the end ?? /// is a dot at the end ??
static bool IsSentenceAtEnd( const SwTextNode& rTextNd ); static bool IsSentenceAtEnd(const SwTextFrame & rTextFrame);
bool DoUnderline(); bool DoUnderline();
bool DoTable(); bool DoTable();
...@@ -230,23 +235,28 @@ SwTextFrame* SwAutoFormat::GetFrame( const SwTextNode& rTextNd ) const ...@@ -230,23 +235,28 @@ SwTextFrame* SwAutoFormat::GetFrame( const SwTextNode& rTextNd ) const
{ {
// get the Frame // get the Frame
const SwContentFrame *pFrame = rTextNd.getLayoutFrame( m_pEditShell->GetLayout() ); const SwContentFrame *pFrame = rTextNd.getLayoutFrame( m_pEditShell->GetLayout() );
OSL_ENSURE( pFrame, "For Autoformat a Layout is needed" ); assert(pFrame && "For Autoformat a Layout is needed");
return EnsureFormatted(*static_cast<SwTextFrame const*>(pFrame));
}
SwTextFrame * SwAutoFormat::EnsureFormatted(SwTextFrame const& rFrame) const
{
SwTextFrame *const pFrame(const_cast<SwTextFrame*>(&rFrame));
if( m_aFlags.bAFormatByInput && !pFrame->isFrameAreaDefinitionValid() ) if( m_aFlags.bAFormatByInput && !pFrame->isFrameAreaDefinitionValid() )
{ {
DisableCallbackAction a(const_cast<SwRootFrame&>(*pFrame->getRootFrame())); DisableCallbackAction a(*pFrame->getRootFrame());
SwRect aTmpFrame( pFrame->getFrameArea() ); SwRect aTmpFrame( pFrame->getFrameArea() );
SwRect aTmpPrt( pFrame->getFramePrintArea() ); SwRect aTmpPrt( pFrame->getFramePrintArea() );
pFrame->Calc(pFrame->getRootFrame()->GetCurrShell()->GetOut()); pFrame->Calc(pFrame->getRootFrame()->GetCurrShell()->GetOut());
if( pFrame->getFrameArea() != aTmpFrame || pFrame->getFramePrintArea() != aTmpPrt || if( pFrame->getFrameArea() != aTmpFrame || pFrame->getFramePrintArea() != aTmpPrt ||
( pFrame->IsTextFrame() && !const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pFrame))->GetPaintSwRect().IsEmpty() ) ) !pFrame->GetPaintSwRect().IsEmpty())
{ {
pFrame->SetCompletePaint(); pFrame->SetCompletePaint();
} }
} }
return const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pFrame))->GetFormatted(); return pFrame->GetFormatted();
} }
void SwAutoFormat::SetRedlineText_( sal_uInt16 nActionId ) void SwAutoFormat::SetRedlineText_( sal_uInt16 nActionId )
...@@ -284,7 +294,7 @@ void SwAutoFormat::SetRedlineText_( sal_uInt16 nActionId ) ...@@ -284,7 +294,7 @@ void SwAutoFormat::SetRedlineText_( sal_uInt16 nActionId )
m_pDoc->GetDocumentRedlineManager().SetAutoFormatRedlineComment( &sText, nSeqNo ); m_pDoc->GetDocumentRedlineManager().SetAutoFormatRedlineComment( &sText, nSeqNo );
} }
OUString SwAutoFormat::GoNextPara() void SwAutoFormat::GoNextPara()
{ {
SwNode* pNewNd = nullptr; SwNode* pNewNd = nullptr;
do { do {
...@@ -292,14 +302,14 @@ OUString SwAutoFormat::GoNextPara() ...@@ -292,14 +302,14 @@ OUString SwAutoFormat::GoNextPara()
if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() ) if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() )
{ {
m_bEnd = true; m_bEnd = true;
return OUString(); return;
} }
++m_aNdIdx; sw::GotoNextLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() ) if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() )
{ {
m_bEnd = true; m_bEnd = true;
return OUString(); return;
} }
else else
pNewNd = &m_aNdIdx.GetNode(); pNewNd = &m_aNdIdx.GetNode();
...@@ -311,7 +321,7 @@ OUString SwAutoFormat::GoNextPara() ...@@ -311,7 +321,7 @@ OUString SwAutoFormat::GoNextPara()
if( pNewNd->IsEndNode() ) if( pNewNd->IsEndNode() )
{ {
m_bEnd = true; m_bEnd = true;
return OUString(); return;
} }
else if( pNewNd->IsTableNode() ) else if( pNewNd->IsTableNode() )
m_aNdIdx = *pNewNd->EndOfSectionNode(); m_aNdIdx = *pNewNd->EndOfSectionNode();
...@@ -329,10 +339,9 @@ OUString SwAutoFormat::GoNextPara() ...@@ -329,10 +339,9 @@ OUString SwAutoFormat::GoNextPara()
m_pCurTextNd = static_cast<SwTextNode*>(pNewNd); m_pCurTextNd = static_cast<SwTextNode*>(pNewNd);
m_pCurTextFrame = GetFrame( *m_pCurTextNd ); m_pCurTextFrame = GetFrame( *m_pCurTextNd );
return m_pCurTextNd->GetText();
} }
bool SwAutoFormat::HasObjects( const SwNode& rNd ) bool SwAutoFormat::HasObjects(const SwTextFrame & rFrame)
{ {
// Is there something bound to the paragraph in the paragraph // Is there something bound to the paragraph in the paragraph
// like Frames, DrawObjects, ... // like Frames, DrawObjects, ...
...@@ -343,7 +352,7 @@ bool SwAutoFormat::HasObjects( const SwNode& rNd ) ...@@ -343,7 +352,7 @@ bool SwAutoFormat::HasObjects( const SwNode& rNd )
const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor(); const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
if ((RndStdIds::FLY_AT_PAGE != rAnchor.GetAnchorId()) && if ((RndStdIds::FLY_AT_PAGE != rAnchor.GetAnchorId()) &&
rAnchor.GetContentAnchor() && rAnchor.GetContentAnchor() &&
&rAnchor.GetContentAnchor()->nNode.GetNode() == &rNd ) sw::FrameContainsNode(rFrame, rAnchor.GetContentAnchor()->nNode.GetIndex()))
{ {
bRet = true; bRet = true;
break; break;
...@@ -352,57 +361,61 @@ bool SwAutoFormat::HasObjects( const SwNode& rNd ) ...@@ -352,57 +361,61 @@ bool SwAutoFormat::HasObjects( const SwNode& rNd )
return bRet; return bRet;
} }
const SwTextNode* SwAutoFormat::GetNextNode() const const SwTextFrame* SwAutoFormat::GetNextNode(bool const isCheckEnd) const
{ {
if( m_aNdIdx.GetIndex()+1 >= m_aEndNdIdx.GetIndex() ) SwNodeIndex tmp(m_aNdIdx);
sw::GotoNextLayoutTextFrame(tmp, m_pEditShell->GetLayout());
if ((isCheckEnd && m_aEndNdIdx <= tmp) || !tmp.GetNode().IsTextNode())
return nullptr; return nullptr;
return m_pDoc->GetNodes()[ m_aNdIdx.GetIndex() + 1 ]->GetTextNode(); // note: the returned frame is not necessarily formatted, have to call
// EnsureFormatted for that
return static_cast<SwTextFrame*>(tmp.GetNode().GetTextNode()->getLayoutFrame(m_pEditShell->GetLayout()));
} }
bool SwAutoFormat::IsOneLine( const SwTextNode& rNd ) const bool SwAutoFormat::IsOneLine(const SwTextFrame & rFrame) const
{ {
SwTextFrameInfo aFInfo( GetFrame( rNd ) ); SwTextFrameInfo aFInfo( EnsureFormatted(rFrame) );
return aFInfo.IsOneLine(); return aFInfo.IsOneLine();
} }
bool SwAutoFormat::IsFastFullLine( const SwTextNode& rNd ) const bool SwAutoFormat::IsFastFullLine(const SwTextFrame & rFrame) const
{ {
bool bRet = m_aFlags.bRightMargin; bool bRet = m_aFlags.bRightMargin;
if( bRet ) if( bRet )
{ {
SwTextFrameInfo aFInfo( GetFrame( rNd ) ); SwTextFrameInfo aFInfo( EnsureFormatted(rFrame) );
bRet = aFInfo.IsFilled( m_aFlags.nRightMargin ); bRet = aFInfo.IsFilled( m_aFlags.nRightMargin );
} }
return bRet; return bRet;
} }
bool SwAutoFormat::IsEnumericChar( const SwTextNode& rNd ) const bool SwAutoFormat::IsEnumericChar(const SwTextFrame& rFrame) const
{ {
const OUString& rText = rNd.GetText(); const OUString& rText = rFrame.GetText();
sal_Int32 nBlnks = GetLeadingBlanks( rText ); TextFrameIndex nBlanks(GetLeadingBlanks(rText));
const sal_Int32 nLen = rText.getLength() - nBlnks; const TextFrameIndex nLen = TextFrameIndex(rText.getLength()) - nBlanks;
if( !nLen ) if( !nLen )
return false; return false;
// -, +, * separated by blank ?? // -, +, * separated by blank ??
if (2 < nLen && IsSpace(rText[nBlnks + 1])) if (TextFrameIndex(2) < nLen && IsSpace(rText[sal_Int32(nBlanks) + 1]))
{ {
if (StrChr(pBulletChar, rText[nBlnks])) if (StrChr(pBulletChar, rText[sal_Int32(nBlanks)]))
return true; return true;
// Should there be a symbol font at the position? // Should there be a symbol font at the position?
SwTextFrameInfo aFInfo( GetFrame( rNd ) ); SwTextFrameInfo aFInfo( EnsureFormatted(rFrame) );
if( aFInfo.IsBullet( nBlnks )) if (aFInfo.IsBullet(nBlanks))
return true; return true;
} }
// 1.) / 1. / 1.1.1 / (1). / (1) / .... // 1.) / 1. / 1.1.1 / (1). / (1) / ....
return USHRT_MAX != GetDigitLevel( rNd, nBlnks ); return USHRT_MAX != GetDigitLevel(rFrame, nBlanks);
} }
bool SwAutoFormat::IsBlanksInString( const SwTextNode& rNd ) bool SwAutoFormat::IsBlanksInString(const SwTextFrame& rFrame)
{ {
// Search more than 5 consecutive blanks/tabs in the string. // Search more than 5 consecutive blanks/tabs in the string.
OUString sTmp( DelLeadingBlanks(rNd.GetText()) ); OUString sTmp( DelLeadingBlanks(rFrame.GetText()) );
const sal_Int32 nLen = sTmp.getLength(); const sal_Int32 nLen = sTmp.getLength();
sal_Int32 nIdx = 0; sal_Int32 nIdx = 0;
while (nIdx < nLen) while (nIdx < nLen)
...@@ -421,14 +434,15 @@ bool SwAutoFormat::IsBlanksInString( const SwTextNode& rNd ) ...@@ -421,14 +434,15 @@ bool SwAutoFormat::IsBlanksInString( const SwTextNode& rNd )
return false; return false;
} }
sal_uInt16 SwAutoFormat::CalcLevel( const SwTextNode& rNd, sal_uInt16 *pDigitLvl ) const sal_uInt16 SwAutoFormat::CalcLevel(const SwTextFrame & rFrame,
sal_uInt16 *const pDigitLvl) const
{ {
sal_uInt16 nLvl = 0, nBlnk = 0; sal_uInt16 nLvl = 0, nBlnk = 0;
const OUString& rText = rNd.GetText(); const OUString& rText = rFrame.GetText();
if( pDigitLvl ) if( pDigitLvl )
*pDigitLvl = USHRT_MAX; *pDigitLvl = USHRT_MAX;
if( RES_POOLCOLL_TEXT_MOVE == rNd.GetTextColl()->GetPoolFormatId() ) if (RES_POOLCOLL_TEXT_MOVE == rFrame.GetTextNodeForParaProps()->GetTextColl()->GetPoolFormatId())
{ {
if( m_aFlags.bAFormatByInput ) if( m_aFlags.bAFormatByInput )
{ {
...@@ -439,17 +453,18 @@ sal_uInt16 SwAutoFormat::CalcLevel( const SwTextNode& rNd, sal_uInt16 *pDigitLvl ...@@ -439,17 +453,18 @@ sal_uInt16 SwAutoFormat::CalcLevel( const SwTextNode& rNd, sal_uInt16 *pDigitLvl
// on the *second* invocation of AutoFormat, CalcLevel() will // on the *second* invocation of AutoFormat, CalcLevel() will
// retrieve the stored number, and it will be used by // retrieve the stored number, and it will be used by
// BuildHeadLine() to select the corresponding heading style. // BuildHeadLine() to select the corresponding heading style.
nLvl = rNd.GetAutoFormatLvl(); nLvl = rFrame.GetTextNodeForParaProps()->GetAutoFormatLvl();
const_cast<SwTextNode&>(rNd).SetAutoFormatLvl( 0 ); const_cast<SwTextNode *>(rFrame.GetTextNodeForParaProps())->SetAutoFormatLvl(0);
if( nLvl ) if( nLvl )
return nLvl; return nLvl;
} }
++nLvl; ++nLvl;
} }
for (sal_Int32 n = 0, nEnd = rText.getLength(); n < nEnd; ++n) for (TextFrameIndex n = TextFrameIndex(0),
nEnd = TextFrameIndex(rText.getLength()); n < nEnd; ++n)
{ {
switch (rText[n]) switch (rText[sal_Int32(n)])
{ {
case ' ': if( 3 == ++nBlnk ) case ' ': if( 3 == ++nBlnk )
{ {
...@@ -463,44 +478,49 @@ sal_uInt16 SwAutoFormat::CalcLevel( const SwTextNode& rNd, sal_uInt16 *pDigitLvl ...@@ -463,44 +478,49 @@ sal_uInt16 SwAutoFormat::CalcLevel( const SwTextNode& rNd, sal_uInt16 *pDigitLvl
default: default:
if( pDigitLvl ) if( pDigitLvl )
// test 1.) / 1. / 1.1.1 / (1). / (1) / .... // test 1.) / 1. / 1.1.1 / (1). / (1) / ....
*pDigitLvl = GetDigitLevel( rNd, n ); *pDigitLvl = GetDigitLevel(rFrame, n);
return nLvl; return nLvl;
} }
} }
return nLvl; return nLvl;
} }
sal_Int32 SwAutoFormat::GetBigIndent( sal_Int32& rCurrentSpacePos ) const sal_Int32 SwAutoFormat::GetBigIndent(TextFrameIndex & rCurrentSpacePos) const
{ {
SwTextFrameInfo aFInfo( GetFrame( *m_pCurTextNd ) ); SwTextFrameInfo aFInfo( m_pCurTextFrame );
const SwTextFrame* pNxtFrame = nullptr; const SwTextFrame* pNextFrame = nullptr;
if( !m_bMoreLines ) if( !m_bMoreLines )
{ {
const SwTextNode* pNxtNd = GetNextNode(); pNextFrame = GetNextNode();
if( !CanJoin( pNxtNd ) || !IsOneLine( *pNxtNd ) ) if (!CanJoin(pNextFrame) || !IsOneLine(*pNextFrame))
return 0; return 0;
pNxtFrame = GetFrame( *pNxtNd ); pNextFrame = EnsureFormatted(*pNextFrame);
} }
return aFInfo.GetBigIndent( rCurrentSpacePos, pNxtFrame ); return aFInfo.GetBigIndent( rCurrentSpacePos, pNextFrame );
} }
bool SwAutoFormat::IsNoAlphaLine( const SwTextNode& rNd ) const bool SwAutoFormat::IsNoAlphaLine(const SwTextFrame & rFrame) const
{ {
const OUString& rStr = rNd.GetText(); const OUString& rStr = rFrame.GetText();
if( rStr.isEmpty() ) if( rStr.isEmpty() )
return false; return false;
// or better: determine via number of AlphaNum and !AlphaNum characters // or better: determine via number of AlphaNum and !AlphaNum characters
sal_Int32 nANChar = 0, nBlnk = 0; sal_Int32 nANChar = 0, nBlnk = 0;
CharClass& rCC = GetCharClass( rNd.GetSwAttrSet().GetLanguage().GetLanguage() ); for (TextFrameIndex n = TextFrameIndex(0),
for( sal_Int32 n = 0, nEnd = rStr.getLength(); n < nEnd; ++n ) nEnd = TextFrameIndex(rStr.getLength()); n < nEnd; ++n)
if( IsSpace( rStr[ n ] ) ) if (IsSpace(rStr[sal_Int32(n)]))
++nBlnk; ++nBlnk;
else if( rCC.isLetterNumeric( rStr, n )) else
++nANChar; {
auto const pair = rFrame.MapViewToModel(n);
CharClass& rCC = GetCharClass(pair.first->GetSwAttrSet().GetLanguage().GetLanguage());
if (rCC.isLetterNumeric(rStr, sal_Int32(n)))
++nANChar;
}
// If there are 75% of non-alphanumeric characters, then true // If there are 75% of non-alphanumeric characters, then true
sal_uLong nLen = rStr.getLength() - nBlnk; sal_uLong nLen = rStr.getLength() - nBlnk;
...@@ -513,7 +533,7 @@ bool SwAutoFormat::DoUnderline() ...@@ -513,7 +533,7 @@ bool SwAutoFormat::DoUnderline()
if( !m_aFlags.bSetBorder ) if( !m_aFlags.bSetBorder )
return false; return false;
OUString const& rText(m_pCurTextNd->GetText()); OUString const& rText(m_pCurTextFrame->GetText());
int eState = 0; int eState = 0;
sal_Int32 nCnt = 0; sal_Int32 nCnt = 0;
while (nCnt < rText.getLength()) while (nCnt < rText.getLength())
...@@ -540,8 +560,10 @@ bool SwAutoFormat::DoUnderline() ...@@ -540,8 +560,10 @@ bool SwAutoFormat::DoUnderline()
if( 2 < nCnt ) if( 2 < nCnt )
{ {
// then underline the previous paragraph if one exists // then underline the previous paragraph if one exists
DelEmptyLine( false ); DelEmptyLine( false ); // -> point will be on end of current paragraph
// WARNING: rText may be deleted now, m_pCurTextFrame may be nullptr
m_aDelPam.SetMark(); m_aDelPam.SetMark();
// apply to last node & rely on InsertItemSet to apply it to props-node
m_aDelPam.GetMark()->nContent = 0; m_aDelPam.GetMark()->nContent = 0;
editeng::SvxBorderLine aLine; editeng::SvxBorderLine aLine;
...@@ -580,7 +602,8 @@ bool SwAutoFormat::DoUnderline() ...@@ -580,7 +602,8 @@ bool SwAutoFormat::DoUnderline()
aBox.SetLine( &aLine, SvxBoxItemLine::BOTTOM ); aBox.SetLine( &aLine, SvxBoxItemLine::BOTTOM );
aBox.SetDistance(42, SvxBoxItemLine::BOTTOM ); // ~0,75 mm aBox.SetDistance(42, SvxBoxItemLine::BOTTOM ); // ~0,75 mm
aSet.Put(aBox); aSet.Put(aBox);
m_pDoc->getIDocumentContentOperations().InsertItemSet( m_aDelPam, aSet ); m_pDoc->getIDocumentContentOperations().InsertItemSet(m_aDelPam, aSet,
SetAttrMode::DEFAULT, m_pEditShell->GetLayout());
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
} }
...@@ -593,24 +616,24 @@ bool SwAutoFormat::DoTable() ...@@ -593,24 +616,24 @@ bool SwAutoFormat::DoTable()
m_pCurTextNd->FindTableNode() ) m_pCurTextNd->FindTableNode() )
return false; return false;
const OUString& rTmp = m_pCurTextNd->GetText(); const OUString& rTmp = m_pCurTextFrame->GetText();
sal_Int32 nSttPlus = GetLeadingBlanks( rTmp ); TextFrameIndex nSttPlus(GetLeadingBlanks(rTmp));
sal_Int32 nEndPlus = GetTrailingBlanks( rTmp ); TextFrameIndex nEndPlus(GetTrailingBlanks(rTmp));
sal_Unicode cChar; sal_Unicode cChar;
if( 2 > nEndPlus - nSttPlus || if (TextFrameIndex(2) > nEndPlus - nSttPlus
( '+' != ( cChar = rTmp[nSttPlus]) && '|' != cChar ) || || ('+' != (cChar = rTmp[sal_Int32(nSttPlus)]) && '|' != cChar)
( '+' != ( cChar = rTmp[nEndPlus - 1]) && '|' != cChar )) || ('+' != (cChar = rTmp[sal_Int32(nEndPlus) - 1]) && '|' != cChar))
return false; return false;
SwTextFrameInfo aInfo( m_pCurTextFrame ); SwTextFrameInfo aInfo( m_pCurTextFrame );
sal_Int32 n = nSttPlus; TextFrameIndex n = nSttPlus;
std::vector<sal_uInt16> aPosArr; std::vector<sal_uInt16> aPosArr;
while (n < rTmp.getLength()) while (n < TextFrameIndex(rTmp.getLength()))
{ {
switch (rTmp[n]) switch (rTmp[sal_Int32(n)])
{ {
case '-': case '-':
case '_': case '_':
...@@ -637,7 +660,7 @@ bool SwAutoFormat::DoTable() ...@@ -637,7 +660,7 @@ bool SwAutoFormat::DoTable()
sal_uInt16 nColCnt = aPosArr.size() - 1; sal_uInt16 nColCnt = aPosArr.size() - 1;
SwTwips nSttPos = aPosArr[ 0 ]; SwTwips nSttPos = aPosArr[ 0 ];
sal_Int16 eHori; sal_Int16 eHori;
switch( m_pCurTextNd->GetSwAttrSet().GetAdjust().GetAdjust() ) switch (m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().GetAdjust().GetAdjust())
{ {
case SvxAdjust::Center: eHori = text::HoriOrientation::CENTER; break; case SvxAdjust::Center: eHori = text::HoriOrientation::CENTER; break;
case SvxAdjust::Right: eHori = text::HoriOrientation::RIGHT; break; case SvxAdjust::Right: eHori = text::HoriOrientation::RIGHT; break;
...@@ -656,6 +679,7 @@ bool SwAutoFormat::DoTable() ...@@ -656,6 +679,7 @@ bool SwAutoFormat::DoTable()
// then create a table that matches the character // then create a table that matches the character
DelEmptyLine(); DelEmptyLine();
// WARNING: rTmp may be deleted now, m_pCurTextFrame may be nullptr
SwNodeIndex aIdx( m_aDelPam.GetPoint()->nNode ); SwNodeIndex aIdx( m_aDelPam.GetPoint()->nNode );
m_aDelPam.Move( fnMoveForward ); m_aDelPam.Move( fnMoveForward );
m_pDoc->InsertTable( SwInsertTableOptions( SwInsertTableFlags::All , 1 ), m_pDoc->InsertTable( SwInsertTableOptions( SwInsertTableFlags::All , 1 ),
...@@ -710,15 +734,17 @@ sal_Int32 SwAutoFormat::GetTrailingBlanks( const OUString& rStr ) ...@@ -710,15 +734,17 @@ sal_Int32 SwAutoFormat::GetTrailingBlanks( const OUString& rStr )
return ++n; return ++n;
} }
bool SwAutoFormat::IsFirstCharCapital( const SwTextNode& rNd ) const bool SwAutoFormat::IsFirstCharCapital(const SwTextFrame& rFrame) const
{ {
const OUString& rText = rNd.GetText(); const OUString& rText = rFrame.GetText();
for( sal_Int32 n = 0, nEnd = rText.getLength(); n < nEnd; ++n ) for (TextFrameIndex n = TextFrameIndex(0),
if (!IsSpace(rText[n])) nEnd = TextFrameIndex(rText.getLength()); n < nEnd; ++n)
if (!IsSpace(rText[sal_Int32(n)]))
{ {
CharClass& rCC = GetCharClass( rNd.GetSwAttrSet(). auto const pair = rFrame.MapViewToModel(n);
CharClass& rCC = GetCharClass( pair.first->GetSwAttrSet().
GetLanguage().GetLanguage() ); GetLanguage().GetLanguage() );
sal_Int32 nCharType = rCC.getCharacterType( rText, n ); sal_Int32 nCharType = rCC.getCharacterType(rText, sal_Int32(n));
return CharClass::isLetterType( nCharType ) && return CharClass::isLetterType( nCharType ) &&
0 != ( i18n::KCharacterType::UPPER & 0 != ( i18n::KCharacterType::UPPER &
nCharType ); nCharType );
...@@ -726,12 +752,14 @@ bool SwAutoFormat::IsFirstCharCapital( const SwTextNode& rNd ) const ...@@ -726,12 +752,14 @@ bool SwAutoFormat::IsFirstCharCapital( const SwTextNode& rNd ) const
return false; return false;
} }
sal_uInt16 SwAutoFormat::GetDigitLevel( const SwTextNode& rNd, sal_Int32& rPos, sal_uInt16
SwAutoFormat::GetDigitLevel(const SwTextFrame& rFrame, TextFrameIndex& rPos,
OUString* pPrefix, OUString* pPostfix, OUString* pNumTypes ) const OUString* pPrefix, OUString* pPostfix, OUString* pNumTypes ) const
{ {
// check for 1.) / 1. / 1.1.1 / (1). / (1) / .... // check for 1.) / 1. / 1.1.1 / (1). / (1) / ....
const OUString& rText = rNd.GetText(); const OUString& rText = rFrame.GetText();
sal_Int32 nPos = rPos; sal_Int32 nPos(rPos);
int eScan = NONE; int eScan = NONE;
sal_uInt16 nStart = 0; sal_uInt16 nStart = 0;
...@@ -740,10 +768,10 @@ sal_uInt16 SwAutoFormat::GetDigitLevel( const SwTextNode& rNd, sal_Int32& rPos, ...@@ -740,10 +768,10 @@ sal_uInt16 SwAutoFormat::GetDigitLevel( const SwTextNode& rNd, sal_Int32& rPos,
sal_uInt16 nOpeningParentheses = 0; sal_uInt16 nOpeningParentheses = 0;
sal_uInt16 nClosingParentheses = 0; sal_uInt16 nClosingParentheses = 0;
CharClass& rCC = GetCharClass( rNd.GetSwAttrSet().GetLanguage().GetLanguage() );
while (nPos < rText.getLength() && nDigitLvl < MAXLEVEL - 1) while (nPos < rText.getLength() && nDigitLvl < MAXLEVEL - 1)
{ {
auto const pair = rFrame.MapViewToModel(TextFrameIndex(nPos));
CharClass& rCC = GetCharClass(pair.first->GetSwAttrSet().GetLanguage().GetLanguage());
const sal_Unicode cCurrentChar = rText[nPos]; const sal_Unicode cCurrentChar = rText[nPos];
if( ('0' <= cCurrentChar && '9' >= cCurrentChar) || if( ('0' <= cCurrentChar && '9' >= cCurrentChar) ||
(0xff10 <= cCurrentChar && 0xff19 >= cCurrentChar) ) (0xff10 <= cCurrentChar && 0xff19 >= cCurrentChar) )
...@@ -962,7 +990,7 @@ CHECK_ROMAN_5: ...@@ -962,7 +990,7 @@ CHECK_ROMAN_5:
break; break;
++nPos; ++nPos;
} }
if( !( CHG & eScan ) || rPos == nPos || if (!( CHG & eScan ) || rPos == TextFrameIndex(nPos) ||
nPos == rText.getLength() || !IsSpace(rText[nPos]) || nPos == rText.getLength() || !IsSpace(rText[nPos]) ||
(nOpeningParentheses > nClosingParentheses)) (nOpeningParentheses > nClosingParentheses))
return USHRT_MAX; return USHRT_MAX;
...@@ -970,15 +998,15 @@ CHECK_ROMAN_5: ...@@ -970,15 +998,15 @@ CHECK_ROMAN_5:
if( (NO_DELIM & eScan) && pPrefix ) // do not forget the last one if( (NO_DELIM & eScan) && pPrefix ) // do not forget the last one
*pPrefix += "\x01" + OUString::number( nStart ); *pPrefix += "\x01" + OUString::number( nStart );
rPos = nPos; rPos = TextFrameIndex(nPos);
return nDigitLvl; // 0 .. 9 (MAXLEVEL - 1) return nDigitLvl; // 0 .. 9 (MAXLEVEL - 1)
} }
void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText ) void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText )
{ {
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx; m_aDelPam.GetPoint()->nNode = *m_pCurTextFrame->GetTextNodeForParaProps();
m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 ); m_aDelPam.GetPoint()->nContent.Assign(m_aDelPam.GetPoint()->nNode.GetNode().GetContentNode(), 0);
// keep hard tabs, alignment, language, hyphenation, DropCaps and nearly all frame attributes // keep hard tabs, alignment, language, hyphenation, DropCaps and nearly all frame attributes
SfxItemSet aSet( SfxItemSet aSet(
...@@ -989,9 +1017,9 @@ void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText ) ...@@ -989,9 +1017,9 @@ void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText )
RES_PARATR_TABSTOP, RES_PARATR_DROP, RES_PARATR_TABSTOP, RES_PARATR_DROP,
RES_BACKGROUND, RES_SHADOW>{}); RES_BACKGROUND, RES_SHADOW>{});
if( m_pCurTextNd->HasSwAttrSet() ) if (m_aDelPam.GetPoint()->nNode.GetNode().GetTextNode()->HasSwAttrSet())
{ {
aSet.Put( *m_pCurTextNd->GetpSwAttrSet() ); aSet.Put(*m_aDelPam.GetPoint()->nNode.GetNode().GetTextNode()->GetpSwAttrSet());
// take HeaderLine/TextBody only if centered or right aligned, otherwise only justification // take HeaderLine/TextBody only if centered or right aligned, otherwise only justification
SvxAdjustItem const * pAdj; SvxAdjustItem const * pAdj;
if( SfxItemState::SET == aSet.GetItemState( RES_PARATR_ADJUST, if( SfxItemState::SET == aSet.GetItemState( RES_PARATR_ADJUST,
...@@ -1008,33 +1036,29 @@ void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText ) ...@@ -1008,33 +1036,29 @@ void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText )
m_pDoc->SetTextFormatCollByAutoFormat( *m_aDelPam.GetPoint(), nId, &aSet ); m_pDoc->SetTextFormatCollByAutoFormat( *m_aDelPam.GetPoint(), nId, &aSet );
} }
bool SwAutoFormat::HasSelBlanks( SwPaM& rPam ) static bool HasSelBlanks(
SwTextFrame const*const pStartFrame, TextFrameIndex & rStartIndex,
SwTextFrame const*const pEndFrame, TextFrameIndex & rEndIndex)
{ {
// Is there a Blank at the beginning or end? if (TextFrameIndex(0) < rEndIndex
// Do not delete it, it will be inserted again. && rEndIndex < TextFrameIndex(pEndFrame->GetText().getLength())
SwPosition * pPos = rPam.End(); && ' ' == pEndFrame->GetText()[sal_Int32(rEndIndex) - 1])
sal_Int32 nBlnkPos = pPos->nContent.GetIndex();
SwTextNode* pTextNd = pPos->nNode.GetNode().GetTextNode();
if (nBlnkPos && nBlnkPos-- < pTextNd->GetText().getLength() &&
(' ' == pTextNd->GetText()[nBlnkPos]))
--pPos->nContent;
else
{ {
pPos = rPam.GetPoint() == pPos ? rPam.GetMark() : rPam.GetPoint(); --rEndIndex;
nBlnkPos = pPos->nContent.GetIndex(); return true;
pTextNd = pPos->nNode.GetNode().GetTextNode(); }
if (nBlnkPos < pTextNd->GetText().getLength() && if (rStartIndex < TextFrameIndex(pStartFrame->GetText().getLength())
(' ' == pTextNd->GetText()[nBlnkPos])) && ' ' == pStartFrame->GetText()[sal_Int32(rStartIndex)])
++pPos->nContent; {
else ++rStartIndex;
return false; return true;
} }
return true; return false;
} }
bool SwAutoFormat::HasBreakAttr( const SwTextNode& rTextNd ) bool SwAutoFormat::HasBreakAttr(const SwTextFrame& rTextFrame)
{ {
const SfxItemSet* pSet = rTextNd.GetpSwAttrSet(); const SfxItemSet *const pSet = rTextFrame.GetTextNodeFirst()->GetpSwAttrSet();
if( !pSet ) if( !pSet )
return false; return false;
...@@ -1051,9 +1075,9 @@ bool SwAutoFormat::HasBreakAttr( const SwTextNode& rTextNd ) ...@@ -1051,9 +1075,9 @@ bool SwAutoFormat::HasBreakAttr( const SwTextNode& rTextNd )
} }
/// Is there a dot at the end? /// Is there a dot at the end?
bool SwAutoFormat::IsSentenceAtEnd( const SwTextNode& rTextNd ) bool SwAutoFormat::IsSentenceAtEnd(const SwTextFrame & rTextFrame)
{ {
const OUString& rStr = rTextNd.GetText(); const OUString& rStr = rTextFrame.GetText();
sal_Int32 n = rStr.getLength(); sal_Int32 n = rStr.getLength();
if( !n ) if( !n )
return true; return true;
...@@ -1072,23 +1096,22 @@ void SwAutoFormat::DeleteLeadingTrailingBlanks(bool bStart, bool bEnd) ...@@ -1072,23 +1096,22 @@ void SwAutoFormat::DeleteLeadingTrailingBlanks(bool bStart, bool bEnd)
{ {
// delete blanks at the end of the current and at the beginning of the next one // delete blanks at the end of the current and at the beginning of the next one
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx; TextFrameIndex nPos(GetLeadingBlanks(m_pCurTextFrame->GetText()));
sal_Int32 nPos(0); if (bStart && TextFrameIndex(0) != nPos)
if( bStart && 0 != ( nPos = GetLeadingBlanks( m_pCurTextNd->GetText() )))
{ {
m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 ); *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
m_aDelPam.SetMark(); m_aDelPam.SetMark();
m_aDelPam.GetPoint()->nContent = nPos; *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
DeleteSel( m_aDelPam ); DeleteSel( m_aDelPam );
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
} }
if (bEnd && m_pCurTextNd->GetText().getLength() != nPos = TextFrameIndex(GetTrailingBlanks(m_pCurTextFrame->GetText()));
( nPos = GetTrailingBlanks( m_pCurTextNd->GetText() )) ) if (bEnd && TextFrameIndex(m_pCurTextFrame->GetText().getLength()) != nPos)
{ {
m_aDelPam.GetPoint()->nContent.Assign( *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
m_pCurTextNd, m_pCurTextNd->GetText().getLength()); TextFrameIndex(m_pCurTextFrame->GetText().getLength()));
m_aDelPam.SetMark(); m_aDelPam.SetMark();
m_aDelPam.GetPoint()->nContent = nPos; *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
DeleteSel( m_aDelPam ); DeleteSel( m_aDelPam );
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
} }
...@@ -1180,39 +1203,43 @@ void SwAutoFormat::DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect) ...@@ -1180,39 +1203,43 @@ void SwAutoFormat::DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect)
m_aNdIdx = aTmp.GetPoint()->nNode; m_aNdIdx = aTmp.GetPoint()->nNode;
m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode(); m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
m_pCurTextFrame = GetFrame(*m_pCurTextNd); // keep it up to date
} }
else else
m_pEditShell->DeleteSel( rDelPam ); m_pEditShell->DeleteSel( rDelPam );
} }
bool SwAutoFormat::DeleteJoinCurNextPara( const OUString& rNxtPara ) bool SwAutoFormat::DeleteJoinCurNextPara(SwTextFrame const*const pNextFrame,
bool const bIgnoreLeadingBlanks)
{ {
// delete blanks at the end of the current and at the beginning of the next one // delete blanks at the end of the current and at the beginning of the next one
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx; TextFrameIndex nTrailingPos(GetTrailingBlanks(m_pCurTextFrame->GetText()));
m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd,
GetTrailingBlanks( m_pCurTextNd->GetText() ) );
m_aDelPam.SetMark();
++m_aDelPam.GetPoint()->nNode; SwTextFrame const*const pEndFrame(pNextFrame ? pNextFrame : m_pCurTextFrame);
SwTextNode* pTNd = m_aDelPam.GetNode().GetTextNode(); TextFrameIndex nLeadingPos(0);
if( !pTNd ) if (pNextFrame)
{ {
// then delete only up to end of the paragraph nLeadingPos = TextFrameIndex(
--m_aDelPam.GetPoint()->nNode; bIgnoreLeadingBlanks ? 0 : GetLeadingBlanks(pNextFrame->GetText()));
m_aDelPam.GetPoint()->nContent = m_pCurTextNd->GetText().getLength();
} }
else else
m_aDelPam.GetPoint()->nContent.Assign( pTNd, {
GetLeadingBlanks( rNxtPara )); nLeadingPos = TextFrameIndex(m_pCurTextFrame->GetText().getLength());
}
// Is there a Blank at the beginning or end? // Is there a Blank at the beginning or end?
// Do not delete it, it will be inserted again. // Do not delete it, it will be inserted again.
bool bHasBlnks = HasSelBlanks( m_aDelPam ); bool bHasBlnks = HasSelBlanks(m_pCurTextFrame, nTrailingPos, pEndFrame, nLeadingPos);
*m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nTrailingPos);
m_aDelPam.SetMark();
*m_aDelPam.GetPoint() = pEndFrame->MapViewToModelPos(nLeadingPos);
if( *m_aDelPam.GetPoint() != *m_aDelPam.GetMark() ) if( *m_aDelPam.GetPoint() != *m_aDelPam.GetMark() )
DeleteSel( m_aDelPam ); DeleteSel( m_aDelPam );
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
// note: keep m_aDelPam point at insert pos. for clients
return !bHasBlnks; return !bHasBlnks;
} }
...@@ -1222,31 +1249,32 @@ void SwAutoFormat::DelEmptyLine( bool bTstNextPara ) ...@@ -1222,31 +1249,32 @@ void SwAutoFormat::DelEmptyLine( bool bTstNextPara )
SetRedlineText( STR_AUTOFMTREDL_DEL_EMPTY_PARA ); SetRedlineText( STR_AUTOFMTREDL_DEL_EMPTY_PARA );
// delete blanks in empty paragraph // delete blanks in empty paragraph
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx; *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
m_aDelPam.GetPoint()->nContent.Assign( TextFrameIndex(m_pCurTextFrame->GetText().getLength()));
m_pCurTextNd, m_pCurTextNd->GetText().getLength() );
m_aDelPam.SetMark(); m_aDelPam.SetMark();
--m_aDelPam.GetMark()->nNode; m_aDelPam.GetMark()->nNode = m_pCurTextFrame->GetTextNodeFirst()->GetIndex() - 1;
SwTextNode* pTNd = m_aDelPam.GetNode( false ).GetTextNode(); SwTextNode* pTNd = m_aDelPam.GetNode( false ).GetTextNode();
if( pTNd ) if( pTNd )
// first use the previous text node // first use the previous text node
m_aDelPam.GetMark()->nContent.Assign(pTNd, pTNd->GetText().getLength()); m_aDelPam.GetMark()->nContent.Assign(pTNd, pTNd->GetText().getLength());
else if( bTstNextPara ) else if( bTstNextPara )
{ {
// then try the next (at the beginning of a Doc, table cells, borders, ...) // then try the next (at the beginning of a Doc, table cells, frames, ...)
m_aDelPam.GetMark()->nNode += 2; m_aDelPam.GetMark()->nNode = (m_pCurTextFrame->GetMergedPara()
? m_pCurTextFrame->GetMergedPara()->pLastNode
: m_pCurTextNd
)->GetIndex() + 1;
pTNd = m_aDelPam.GetNode( false ).GetTextNode(); pTNd = m_aDelPam.GetNode( false ).GetTextNode();
if( pTNd ) if( pTNd )
{ {
m_aDelPam.GetMark()->nContent.Assign( pTNd, 0 ); m_aDelPam.GetMark()->nContent.Assign( pTNd, 0 );
m_aDelPam.GetPoint()->nContent = 0; *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
} }
} }
else else
{ {
m_aDelPam.GetMark()->nNode = m_aNdIdx; *m_aDelPam.GetMark() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
m_aDelPam.GetMark()->nContent = 0;
pTNd = m_pCurTextNd; pTNd = m_pCurTextNd;
} }
if( pTNd ) if( pTNd )
...@@ -1254,6 +1282,9 @@ void SwAutoFormat::DelEmptyLine( bool bTstNextPara ) ...@@ -1254,6 +1282,9 @@ void SwAutoFormat::DelEmptyLine( bool bTstNextPara )
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
ClearRedlineText(); ClearRedlineText();
// note: this likely has deleted m_pCurTextFrame - update it...
m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
m_pCurTextFrame = m_pCurTextNd ? GetFrame( *m_pCurTextNd ) : nullptr;
} }
void SwAutoFormat::DelMoreLinesBlanks( bool bWithLineBreaks ) void SwAutoFormat::DelMoreLinesBlanks( bool bWithLineBreaks )
...@@ -1264,38 +1295,38 @@ void SwAutoFormat::DelMoreLinesBlanks( bool bWithLineBreaks ) ...@@ -1264,38 +1295,38 @@ void SwAutoFormat::DelMoreLinesBlanks( bool bWithLineBreaks )
{ {
// delete all blanks on the left and right of the indentation // delete all blanks on the left and right of the indentation
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx;
m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 );
SwTextFrameInfo aFInfo( m_pCurTextFrame ); SwTextFrameInfo aFInfo( m_pCurTextFrame );
aFInfo.GetSpaces( m_aDelPam, !m_aFlags.bAFormatByInput || bWithLineBreaks ); std::vector<std::pair<TextFrameIndex, TextFrameIndex>> spaces;
aFInfo.GetSpaces(spaces, !m_aFlags.bAFormatByInput || bWithLineBreaks);
do { for (auto & rSpaceRange : spaces)
SwPaM* pNxt = m_aDelPam.GetNext(); {
if( pNxt->HasMark() && *pNxt->GetPoint() != *pNxt->GetMark() ) assert(rSpaceRange.first != rSpaceRange.second);
bool const bHasBlanks = HasSelBlanks(
m_pCurTextFrame, rSpaceRange.first,
m_pCurTextFrame, rSpaceRange.second);
if (rSpaceRange.first != rSpaceRange.second)
{ {
bool bHasBlnks = HasSelBlanks( *pNxt ); *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(rSpaceRange.first);
DeleteSel( *pNxt ); m_aDelPam.SetMark();
if( !bHasBlnks ) *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(rSpaceRange.second);
DeleteSel(m_aDelPam);
if (!bHasBlanks)
{ {
m_pDoc->getIDocumentContentOperations().InsertString( *pNxt, OUString(' ') ); m_pDoc->getIDocumentContentOperations().InsertString(m_aDelPam, OUString(' '));
} }
m_aDelPam.DeleteMark();
} }
}
if( pNxt == &m_aDelPam )
break;
delete pNxt;
} while( true );
m_aDelPam.DeleteMark();
} }
} }
void SwAutoFormat::JoinPrevPara() void SwAutoFormat::JoinPrevPara()
{ {
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx; m_aDelPam.GetPoint()->nNode = *m_pCurTextFrame->GetTextNodeFirst();
m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 ); m_aDelPam.GetPoint()->nContent.Assign(m_pCurTextFrame->GetTextNodeFirst(), 0);
m_aDelPam.SetMark(); m_aDelPam.SetMark();
--m_aDelPam.GetPoint()->nNode; --m_aDelPam.GetPoint()->nNode;
...@@ -1318,29 +1349,30 @@ void SwAutoFormat::BuildIndent() ...@@ -1318,29 +1349,30 @@ void SwAutoFormat::BuildIndent()
if( m_bMoreLines ) if( m_bMoreLines )
DelMoreLinesBlanks( true ); DelMoreLinesBlanks( true );
else else
bBreak = !IsFastFullLine( *m_pCurTextNd ) || bBreak = !IsFastFullLine(*m_pCurTextFrame)
IsBlanksInString( *m_pCurTextNd ) || || IsBlanksInString(*m_pCurTextFrame)
IsSentenceAtEnd( *m_pCurTextNd ); || IsSentenceAtEnd(*m_pCurTextFrame);
SetColl( RES_POOLCOLL_TEXT_IDENT ); SetColl( RES_POOLCOLL_TEXT_IDENT );
if( !bBreak ) if( !bBreak )
{ {
SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES ); SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
const SwTextNode* pNxtNd = GetNextNode(); const SwTextFrame * pNextFrame = GetNextNode();
if( pNxtNd && !m_bEnd ) if (pNextFrame && !m_bEnd)
{ {
do { do {
bBreak = !IsFastFullLine( *pNxtNd ) || bBreak = !IsFastFullLine(*pNextFrame)
IsBlanksInString( *pNxtNd ) || || IsBlanksInString(*pNextFrame)
IsSentenceAtEnd( *pNxtNd ); || IsSentenceAtEnd(*pNextFrame);
if (DeleteJoinCurNextPara(pNxtNd->GetText())) if (DeleteJoinCurNextPara(pNextFrame))
{ {
m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') ); m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
} }
if( bBreak ) if( bBreak )
break; break;
pNxtNd = GetNextNode(); pNextFrame = GetNextNode();
} while( CanJoin( pNxtNd ) && }
!CalcLevel( *pNxtNd ) ); while (CanJoin(pNextFrame)
&& !CalcLevel(*pNextFrame));
} }
} }
DeleteLeadingTrailingBlanks(); DeleteLeadingTrailingBlanks();
...@@ -1355,30 +1387,34 @@ void SwAutoFormat::BuildTextIndent() ...@@ -1355,30 +1387,34 @@ void SwAutoFormat::BuildTextIndent()
if( m_bMoreLines ) if( m_bMoreLines )
DelMoreLinesBlanks( true ); DelMoreLinesBlanks( true );
else else
bBreak = !IsFastFullLine( *m_pCurTextNd ) || bBreak = !IsFastFullLine(*m_pCurTextFrame)
IsBlanksInString( *m_pCurTextNd ) || || IsBlanksInString(*m_pCurTextFrame)
IsSentenceAtEnd( *m_pCurTextNd ); || IsSentenceAtEnd(*m_pCurTextFrame);
if( m_aFlags.bAFormatByInput ) if( m_aFlags.bAFormatByInput )
m_pCurTextNd->SetAutoFormatLvl( static_cast<sal_uInt8>(CalcLevel( *m_pCurTextNd )) ); {
const_cast<SwTextNode*>(m_pCurTextFrame->GetTextNodeForParaProps())->SetAutoFormatLvl(
static_cast<sal_uInt8>(CalcLevel(*m_pCurTextFrame)));
}
SetColl( RES_POOLCOLL_TEXT_MOVE ); SetColl( RES_POOLCOLL_TEXT_MOVE );
if( !bBreak ) if( !bBreak )
{ {
SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES ); SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
const SwTextNode* pNxtNd = GetNextNode(); const SwTextFrame * pNextFrame = GetNextNode();
while( CanJoin( pNxtNd ) && while (CanJoin(pNextFrame) &&
CalcLevel( *pNxtNd ) ) CalcLevel(*pNextFrame))
{ {
bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) || bBreak = !IsFastFullLine(*pNextFrame)
IsSentenceAtEnd( *pNxtNd ); || IsBlanksInString(*pNextFrame)
if (DeleteJoinCurNextPara(pNxtNd->GetText())) || IsSentenceAtEnd(*pNextFrame);
if (DeleteJoinCurNextPara(pNextFrame))
{ {
m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') ); m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
} }
if( bBreak ) if( bBreak )
break; break;
pNxtNd = GetNextNode(); pNextFrame = GetNextNode();
} }
} }
DeleteLeadingTrailingBlanks(); DeleteLeadingTrailingBlanks();
...@@ -1393,28 +1429,29 @@ void SwAutoFormat::BuildText() ...@@ -1393,28 +1429,29 @@ void SwAutoFormat::BuildText()
if( m_bMoreLines ) if( m_bMoreLines )
DelMoreLinesBlanks(); DelMoreLinesBlanks();
else else
bBreak = !IsFastFullLine( *m_pCurTextNd ) || bBreak = !IsFastFullLine(*m_pCurTextFrame)
IsBlanksInString( *m_pCurTextNd ) || || IsBlanksInString(*m_pCurTextFrame)
IsSentenceAtEnd( *m_pCurTextNd ); || IsSentenceAtEnd(*m_pCurTextFrame);
SetColl( RES_POOLCOLL_TEXT, true ); SetColl( RES_POOLCOLL_TEXT, true );
if( !bBreak ) if( !bBreak )
{ {
SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES ); SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
const SwTextNode* pNxtNd = GetNextNode(); const SwTextFrame * pNextFrame = GetNextNode();
while( CanJoin( pNxtNd ) && while (CanJoin(pNextFrame) &&
!CalcLevel( *pNxtNd ) ) !CalcLevel(*pNextFrame))
{ {
bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) || bBreak = !IsFastFullLine(*pNextFrame)
IsSentenceAtEnd( *pNxtNd ); || IsBlanksInString(*pNextFrame)
if (DeleteJoinCurNextPara(pNxtNd->GetText())) || IsSentenceAtEnd(*pNextFrame);
if (DeleteJoinCurNextPara(pNextFrame))
{ {
m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') ); m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
} }
if( bBreak ) if( bBreak )
break; break;
const SwTextNode* pCurrNode = pNxtNd; const SwTextFrame *const pCurrNode = pNextFrame;
pNxtNd = GetNextNode(); pNextFrame = GetNextNode();
if(!pNxtNd || pCurrNode == pNxtNd) if (!pNextFrame || pCurrNode == pNextFrame)
break; break;
} }
} }
...@@ -1432,24 +1469,24 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel ) ...@@ -1432,24 +1469,24 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
SwTwips nFrameWidth = m_pCurTextFrame->getFramePrintArea().Width(); SwTwips nFrameWidth = m_pCurTextFrame->getFramePrintArea().Width();
SwTwips nLeftTextPos; SwTwips nLeftTextPos;
{ {
sal_Int32 nPos(0); TextFrameIndex nPos(0);
while (nPos < m_pCurTextNd->GetText().getLength() && while (nPos < TextFrameIndex(m_pCurTextFrame->GetText().getLength())
IsSpace(m_pCurTextNd->GetText()[nPos])) && IsSpace(m_pCurTextFrame->GetText()[sal_Int32(nPos)]))
{ {
++nPos; ++nPos;
} }
SwTextFrameInfo aInfo( m_pCurTextFrame ); SwTextFrameInfo aInfo( m_pCurTextFrame );
nLeftTextPos = aInfo.GetCharPos(nPos); nLeftTextPos = aInfo.GetCharPos(nPos);
nLeftTextPos -= m_pCurTextNd->GetSwAttrSet().GetLRSpace().GetLeft(); nLeftTextPos -= m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().GetLRSpace().GetLeft();
} }
if( m_bMoreLines ) if( m_bMoreLines )
DelMoreLinesBlanks(); DelMoreLinesBlanks();
else else
bBreak = !IsFastFullLine( *m_pCurTextNd ) || bBreak = !IsFastFullLine(*m_pCurTextFrame)
IsBlanksInString( *m_pCurTextNd ) || || IsBlanksInString(*m_pCurTextFrame)
IsSentenceAtEnd( *m_pCurTextNd ); || IsSentenceAtEnd(*m_pCurTextFrame);
bool bRTL = m_pEditShell->IsInRightToLeftText(); bool bRTL = m_pEditShell->IsInRightToLeftText();
DeleteLeadingTrailingBlanks(); DeleteLeadingTrailingBlanks();
...@@ -1462,16 +1499,22 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel ) ...@@ -1462,16 +1499,22 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
numfunc::GetDefaultPositionAndSpaceMode() ); numfunc::GetDefaultPositionAndSpaceMode() );
const SwNumRule* pCur = nullptr; const SwNumRule* pCur = nullptr;
if( m_aFlags.bSetNumRule && nullptr != (pCur = m_pCurTextNd->GetNumRule()) ) if (m_aFlags.bSetNumRule)
aRule = *pCur; {
pCur = m_pCurTextFrame->GetTextNodeForParaProps()->GetNumRule();
if (pCur)
{
aRule = *pCur;
}
}
// replace bullet character with defined one // replace bullet character with defined one
const OUString& rStr = m_pCurTextNd->GetText(); const OUString& rStr = m_pCurTextFrame->GetText();
sal_Int32 nTextStt = 0; TextFrameIndex nTextStt(0);
const sal_Unicode* pFndBulletChr = nullptr; const sal_Unicode* pFndBulletChr = nullptr;
if (m_aFlags.bChgEnumNum && 2 < rStr.getLength()) if (m_aFlags.bChgEnumNum && 2 < rStr.getLength())
pFndBulletChr = StrChr(pBulletChar, rStr[nTextStt]); pFndBulletChr = StrChr(pBulletChar, rStr[sal_Int32(nTextStt)]);
if (nullptr != pFndBulletChr && IsSpace(rStr[nTextStt + 1])) if (nullptr != pFndBulletChr && IsSpace(rStr[sal_Int32(nTextStt) + 1]))
{ {
if( m_aFlags.bAFormatByInput ) if( m_aFlags.bAFormatByInput )
{ {
...@@ -1548,8 +1591,9 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel ) ...@@ -1548,8 +1591,9 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
// it is determined by the indentation level. // it is determined by the indentation level.
OUString aPostfix, aPrefix, aNumTypes; OUString aPostfix, aPrefix, aNumTypes;
if( USHRT_MAX != ( nDigitLevel = GetDigitLevel( *m_pCurTextNd, nTextStt, nDigitLevel = GetDigitLevel(*m_pCurTextFrame, nTextStt,
&aPrefix, &aPostfix, &aNumTypes )) ) &aPrefix, &aPostfix, &aNumTypes);
if (USHRT_MAX != nDigitLevel)
{ {
bChgEnum = true; bChgEnum = true;
...@@ -1640,37 +1684,41 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel ) ...@@ -1640,37 +1684,41 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
if ( bChgEnum || bChgBullet ) if ( bChgEnum || bChgBullet )
{ {
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx; m_aDelPam.GetPoint()->nNode = *m_pCurTextFrame->GetTextNodeForParaProps();
if( m_aFlags.bSetNumRule ) if( m_aFlags.bSetNumRule )
{ {
if( m_aFlags.bAFormatByInput ) if( m_aFlags.bAFormatByInput )
{ {
m_aDelPam.SetMark(); m_aDelPam.SetMark();
++m_aDelPam.GetMark()->nNode; SwTextFrame const*const pNextFrame = GetNextNode(false);
assert(pNextFrame);
m_aDelPam.GetMark()->nNode = *pNextFrame->GetTextNodeForParaProps();
m_aDelPam.GetNode(false).GetTextNode()->SetAttrListLevel( nLvl ); m_aDelPam.GetNode(false).GetTextNode()->SetAttrListLevel( nLvl );
} }
m_pCurTextNd->SetAttrListLevel(nLvl); const_cast<SwTextNode*>(m_pCurTextFrame->GetTextNodeForParaProps())->SetAttrListLevel(nLvl);
// start new list // start new list
m_pDoc->SetNumRule( m_aDelPam, aRule, true ); m_pDoc->SetNumRule(m_aDelPam, aRule, true, m_pEditShell->GetLayout());
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 ); *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
} }
else else
m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, {
bChgEnum ? nTextStt : 0 ); *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
bChgEnum ? nTextStt : TextFrameIndex(0));
}
m_aDelPam.SetMark(); m_aDelPam.SetMark();
if ( bChgBullet ) if ( bChgBullet )
nTextStt += 2; nTextStt += TextFrameIndex(2);
while( nTextStt < rStr.getLength() && IsSpace( rStr[ nTextStt ] )) while (nTextStt < TextFrameIndex(rStr.getLength()) && IsSpace(rStr[sal_Int32(nTextStt)]))
nTextStt++; nTextStt++;
m_aDelPam.GetPoint()->nContent = nTextStt; *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nTextStt);
DeleteSel( m_aDelPam ); DeleteSel( m_aDelPam );
if( !m_aFlags.bSetNumRule ) if( !m_aFlags.bSetNumRule )
...@@ -1681,11 +1729,12 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel ) ...@@ -1681,11 +1729,12 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, sChgStr ); m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, sChgStr );
SfxItemSet aSet( m_pDoc->GetAttrPool(), aTextNodeSetRange ); SfxItemSet aSet( m_pDoc->GetAttrPool(), aTextNodeSetRange );
*m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
assert(&m_aDelPam.GetPoint()->nNode.GetNode() == m_pCurTextFrame->GetTextNodeForParaProps());
if( bChgBullet ) if( bChgBullet )
{ {
m_aDelPam.GetPoint()->nContent = 0;
m_aDelPam.SetMark(); m_aDelPam.SetMark();
m_aDelPam.GetMark()->nContent = 1; *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(1));
SetAllScriptItem( aSet, SetAllScriptItem( aSet,
SvxFontItem( m_aFlags.aBulletFont.GetFamilyType(), SvxFontItem( m_aFlags.aBulletFont.GetFamilyType(),
m_aFlags.aBulletFont.GetFamilyName(), m_aFlags.aBulletFont.GetFamilyName(),
...@@ -1701,6 +1750,7 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel ) ...@@ -1701,6 +1750,7 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
SvxTabStopItem aTStops( RES_PARATR_TABSTOP ); SvxTabStopItem aTStops( RES_PARATR_TABSTOP );
aTStops.Insert( SvxTabStop( 0 ) ); aTStops.Insert( SvxTabStop( 0 ) );
aSet.Put( aTStops ); aSet.Put( aTStops );
assert(&m_aDelPam.GetPoint()->nNode.GetNode() == m_pCurTextFrame->GetTextNodeForParaProps());
m_pDoc->SetFormatItemByAutoFormat( m_aDelPam, aSet ); m_pDoc->SetFormatItemByAutoFormat( m_aDelPam, aSet );
} }
} }
...@@ -1711,22 +1761,23 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel ) ...@@ -1711,22 +1761,23 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
return; return;
} }
const SwTextNode* pNxtNd = GetNextNode(); const SwTextFrame * pNextFrame = GetNextNode();
while( CanJoin( pNxtNd ) && while (CanJoin(pNextFrame)
nLvl == CalcLevel( *pNxtNd ) ) && nLvl == CalcLevel(*pNextFrame))
{ {
SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES ); SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) || bBreak = !IsFastFullLine(*pNextFrame)
IsSentenceAtEnd( *pNxtNd ); || IsBlanksInString(*pNextFrame)
if (DeleteJoinCurNextPara(pNxtNd->GetText())) || IsSentenceAtEnd(*pNextFrame);
if (DeleteJoinCurNextPara(pNextFrame))
{ {
m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') ); m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
} }
if( bBreak ) if( bBreak )
break; break;
const SwTextNode* pCurrNode = pNxtNd; const SwTextFrame *const pCurrNode = pNextFrame;
pNxtNd = GetNextNode(); pNextFrame = GetNextNode();
if(!pNxtNd || pCurrNode == pNxtNd) if (!pNextFrame || pCurrNode == pNextFrame)
break; break;
} }
DeleteLeadingTrailingBlanks( false ); DeleteLeadingTrailingBlanks( false );
...@@ -1740,14 +1791,14 @@ void SwAutoFormat::BuildNegIndent( SwTwips nSpaces ) ...@@ -1740,14 +1791,14 @@ void SwAutoFormat::BuildNegIndent( SwTwips nSpaces )
// read all succeeding paragraphs that belong to this enumeration // read all succeeding paragraphs that belong to this enumeration
bool bBreak = true; bool bBreak = true;
sal_Int32 nSpacePos = 0; TextFrameIndex nSpacePos(0);
const sal_Int32 nTextPos = GetBigIndent( nSpacePos ); const sal_Int32 nTextPos = GetBigIndent( nSpacePos );
if( m_bMoreLines ) if( m_bMoreLines )
DelMoreLinesBlanks( true ); DelMoreLinesBlanks( true );
else else
bBreak = !IsFastFullLine( *m_pCurTextNd ) || bBreak = !IsFastFullLine(*m_pCurTextFrame)
( !nTextPos && IsBlanksInString( *m_pCurTextNd )) || || (!nTextPos && IsBlanksInString(*m_pCurTextFrame))
IsSentenceAtEnd( *m_pCurTextNd ); || IsSentenceAtEnd(*m_pCurTextFrame);
SetColl( static_cast<sal_uInt16>( nTextPos SetColl( static_cast<sal_uInt16>( nTextPos
? RES_POOLCOLL_CONFRONTATION ? RES_POOLCOLL_CONFRONTATION
...@@ -1755,35 +1806,34 @@ void SwAutoFormat::BuildNegIndent( SwTwips nSpaces ) ...@@ -1755,35 +1806,34 @@ void SwAutoFormat::BuildNegIndent( SwTwips nSpaces )
if( nTextPos ) if( nTextPos )
{ {
const OUString& rStr = m_pCurTextNd->GetText(); const OUString& rStr = m_pCurTextFrame->GetText();
bool bInsTab = true; bool bInsTab = true;
if ('\t' == rStr[nSpacePos+1]) // leave tab alone if ('\t' == rStr[sal_Int32(nSpacePos) + 1]) // leave tab alone
{ {
--nSpacePos; --nSpacePos;
bInsTab = false; bInsTab = false;
} }
sal_Int32 nSpaceStt = nSpacePos; TextFrameIndex nSpaceStt = nSpacePos;
while (nSpaceStt && IsSpace(rStr[--nSpaceStt])) while (nSpaceStt && IsSpace(rStr[sal_Int32(--nSpaceStt)]))
; ;
++nSpaceStt; ++nSpaceStt;
if (bInsTab && '\t' == rStr[nSpaceStt]) // leave tab alone if (bInsTab && '\t' == rStr[sal_Int32(nSpaceStt)]) // leave tab alone
{ {
++nSpaceStt; ++nSpaceStt;
bInsTab = false; bInsTab = false;
} }
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx; *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nSpacePos);
m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, nSpacePos );
// delete old Spaces, etc. // delete old Spaces, etc.
if( nSpaceStt < nSpacePos ) if( nSpaceStt < nSpacePos )
{ {
m_aDelPam.SetMark(); m_aDelPam.SetMark();
m_aDelPam.GetMark()->nContent = nSpaceStt; *m_aDelPam.GetMark() = m_pCurTextFrame->MapViewToModelPos(nSpaceStt);
DeleteSel( m_aDelPam ); DeleteSel( m_aDelPam );
if( bInsTab ) if( bInsTab )
{ {
...@@ -1796,22 +1846,22 @@ void SwAutoFormat::BuildNegIndent( SwTwips nSpaces ) ...@@ -1796,22 +1846,22 @@ void SwAutoFormat::BuildNegIndent( SwTwips nSpaces )
{ {
SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES ); SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
SwTextFrameInfo aFInfo( m_pCurTextFrame ); SwTextFrameInfo aFInfo( m_pCurTextFrame );
const SwTextNode* pNxtNd = GetNextNode(); const SwTextFrame * pNextFrame = GetNextNode();
while( CanJoin( pNxtNd ) && while (CanJoin(pNextFrame) &&
20 < std::abs( static_cast<long>(nSpaces - aFInfo.SetFrame( 20 < std::abs( static_cast<long>(nSpaces - aFInfo.SetFrame(
GetFrame( *pNxtNd ) ).GetLineStart() )) EnsureFormatted(*pNextFrame)).GetLineStart()) )
) )
{ {
bBreak = !IsFastFullLine( *pNxtNd ) || bBreak = !IsFastFullLine(*pNextFrame)
IsBlanksInString( *pNxtNd ) || || IsBlanksInString(*pNextFrame)
IsSentenceAtEnd( *pNxtNd ); || IsSentenceAtEnd(*pNextFrame);
if (DeleteJoinCurNextPara(pNxtNd->GetText())) if (DeleteJoinCurNextPara(pNextFrame))
{ {
m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') ); m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
} }
if( bBreak ) if( bBreak )
break; break;
pNxtNd = GetNextNode(); pNextFrame = GetNextNode();
} }
} }
DeleteLeadingTrailingBlanks(); DeleteLeadingTrailingBlanks();
...@@ -1831,15 +1881,16 @@ void SwAutoFormat::BuildHeadLine( sal_uInt16 nLvl ) ...@@ -1831,15 +1881,16 @@ void SwAutoFormat::BuildHeadLine( sal_uInt16 nLvl )
SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_HEADLINE1 + nLvl ), true ); SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_HEADLINE1 + nLvl ), true );
if( m_aFlags.bAFormatByInput ) if( m_aFlags.bAFormatByInput )
{ {
SwTextFormatColl& rNxtColl = m_pCurTextNd->GetTextColl()->GetNextTextFormatColl(); SwTextFormatColl& rNxtColl = m_pCurTextFrame->GetTextNodeForParaProps()->GetTextColl()->GetNextTextFormatColl();
JoinPrevPara(); JoinPrevPara();
DeleteLeadingTrailingBlanks( true, false ); DeleteLeadingTrailingBlanks( true, false );
(void)DeleteJoinCurNextPara( OUString() ); const SwTextFrame *const pNextFrame = GetNextNode(false);
(void)DeleteJoinCurNextPara(pNextFrame, true);
m_aDelPam.DeleteMark(); m_aDelPam.DeleteMark();
m_aDelPam.GetPoint()->nNode = m_aNdIdx.GetIndex() + 1; m_aDelPam.GetPoint()->nNode = *GetNextNode(false)->GetTextNodeForParaProps();
m_aDelPam.GetPoint()->nContent.Assign( m_aDelPam.GetContentNode(), 0 ); m_aDelPam.GetPoint()->nContent.Assign( m_aDelPam.GetContentNode(), 0 );
m_pDoc->SetTextFormatColl( m_aDelPam, &rNxtColl ); m_pDoc->SetTextFormatColl( m_aDelPam, &rNxtColl );
} }
...@@ -2165,7 +2216,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2165,7 +2216,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
bool bReplaceStyles = !m_aFlags.bAFormatByInput || m_aFlags.bReplaceStyles; bool bReplaceStyles = !m_aFlags.bAFormatByInput || m_aFlags.bReplaceStyles;
const SwTextNode* pNxtNd = nullptr; const SwTextFrame * pNextFrame = nullptr;
bool bNxtEmpty = false; bool bNxtEmpty = false;
bool bNxtAlpha = false; bool bNxtAlpha = false;
sal_uInt16 nNxtLevel = 0; sal_uInt16 nNxtLevel = 0;
...@@ -2175,15 +2226,18 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2175,15 +2226,18 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
if( pSttNd ) if( pSttNd )
{ {
m_aNdIdx = *pSttNd; m_aNdIdx = *pSttNd;
--m_aNdIdx; // for GoNextPara, one paragraph prior to that // for GoNextPara, one paragraph prior to that
sw::GotoPrevLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
m_aEndNdIdx = *pEndNd; m_aEndNdIdx = *pEndNd;
++m_aEndNdIdx; sw::GotoNextLayoutTextFrame(m_aEndNdIdx, m_pEditShell->GetLayout());
// check the previous TextNode // check the previous TextNode
pNxtNd = m_aNdIdx.GetNode().GetTextNode(); SwTextFrame const*const pPrevFrame = m_aNdIdx.GetNode().GetTextNode()
bEmptyLine = !pNxtNd || ? static_cast<SwTextFrame const*>(m_aNdIdx.GetNode().GetTextNode()->getLayoutFrame(m_pEditShell->GetLayout()))
IsEmptyLine( *pNxtNd ) || : nullptr;
IsNoAlphaLine( *pNxtNd ); bEmptyLine = !pPrevFrame
|| IsEmptyLine(*pPrevFrame)
|| IsNoAlphaLine(*pPrevFrame);
} }
else else
bEmptyLine = true; // at document beginning bEmptyLine = true; // at document beginning
...@@ -2254,16 +2308,19 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2254,16 +2308,19 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
break; break;
case TST_EMPTY_LINE: case TST_EMPTY_LINE:
if( IsEmptyLine( *m_pCurTextNd ) ) if (IsEmptyLine(*m_pCurTextFrame))
{ {
if( m_aFlags.bDelEmptyNode && !HasObjects( *m_pCurTextNd ) ) if (m_aFlags.bDelEmptyNode && !HasObjects(*m_pCurTextFrame))
{ {
bEmptyLine = true; bEmptyLine = true;
sal_uLong nOldCnt = m_pDoc->GetNodes().Count(); sal_uLong nOldCnt = m_pDoc->GetNodes().Count();
DelEmptyLine(); DelEmptyLine();
// Was there really a deletion of a node? // Was there really a deletion of a node?
if( nOldCnt != m_pDoc->GetNodes().Count() ) if( nOldCnt != m_pDoc->GetNodes().Count() )
--m_aNdIdx; // do not skip the next paragraph {
// do not skip the next paragraph
sw::GotoPrevLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
}
} }
eStat = READ_NEXT_PARA; eStat = READ_NEXT_PARA;
} }
...@@ -2272,7 +2329,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2272,7 +2329,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
break; break;
case TST_ALPHA_LINE: case TST_ALPHA_LINE:
if( IsNoAlphaLine( *m_pCurTextNd )) if (IsNoAlphaLine(*m_pCurTextFrame))
{ {
// recognize a table definition +---+---+ // recognize a table definition +---+---+
if( m_aFlags.bAFormatByInput && m_aFlags.bCreateTable && DoTable() ) if( m_aFlags.bAFormatByInput && m_aFlags.bCreateTable && DoTable() )
...@@ -2301,7 +2358,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2301,7 +2358,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
case GET_ALL_INFO: case GET_ALL_INFO:
{ {
if( m_pCurTextNd->GetNumRule() ) if (m_pCurTextFrame->GetTextNodeForParaProps()->GetNumRule())
{ {
// do nothing in numbering, go to next // do nothing in numbering, go to next
bEmptyLine = false; bEmptyLine = false;
...@@ -2315,7 +2372,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2315,7 +2372,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
aFInfo.SetFrame( m_pCurTextFrame ); aFInfo.SetFrame( m_pCurTextFrame );
// so far: if there were templates assigned, keep these and go to next node // so far: if there were templates assigned, keep these and go to next node
sal_uInt16 nPoolId = m_pCurTextNd->GetTextColl()->GetPoolFormatId(); sal_uInt16 nPoolId = m_pCurTextFrame->GetTextNodeForParaProps()->GetTextColl()->GetPoolFormatId();
if( IsPoolUserFormat( nPoolId ) if( IsPoolUserFormat( nPoolId )
? !m_aFlags.bChgUserColl ? !m_aFlags.bChgUserColl
: ( RES_POOLCOLL_STANDARD != nPoolId && : ( RES_POOLCOLL_STANDARD != nPoolId &&
...@@ -2333,16 +2390,16 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2333,16 +2390,16 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
{ {
short nSz; short nSz;
SvxLRSpaceItem const * pLRSpace; SvxLRSpaceItem const * pLRSpace;
if( SfxItemState::SET == m_pCurTextNd->GetSwAttrSet(). if (SfxItemState::SET == m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().
GetItemState( RES_LR_SPACE, true, GetItemState( RES_LR_SPACE, true,
reinterpret_cast<const SfxPoolItem**>(&pLRSpace) ) && reinterpret_cast<const SfxPoolItem**>(&pLRSpace) ) &&
( 0 != (nSz = pLRSpace->GetTextFirstLineOfst()) || ( 0 != (nSz = pLRSpace->GetTextFirstLineOfst()) ||
0 != pLRSpace->GetTextLeft() ) ) 0 != pLRSpace->GetTextLeft() ) )
{ {
// exception: numbering/enumeration can have an indentation // exception: numbering/enumeration can have an indentation
if( IsEnumericChar( *m_pCurTextNd )) if (IsEnumericChar(*m_pCurTextFrame))
{ {
nLevel = CalcLevel( *m_pCurTextNd, &nDigitLvl ); nLevel = CalcLevel(*m_pCurTextFrame, &nDigitLvl);
if( nLevel >= MAXLEVEL ) if( nLevel >= MAXLEVEL )
nLevel = MAXLEVEL-1; nLevel = MAXLEVEL-1;
BuildEnum( nLevel, nDigitLvl ); BuildEnum( nLevel, nDigitLvl );
...@@ -2368,18 +2425,20 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2368,18 +2425,20 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
} }
} }
nLevel = CalcLevel( *m_pCurTextNd, &nDigitLvl ); nLevel = CalcLevel( *m_pCurTextFrame, &nDigitLvl );
m_bMoreLines = !IsOneLine( *m_pCurTextNd ); m_bMoreLines = !IsOneLine(*m_pCurTextFrame);
pNxtNd = GetNextNode(); // note: every use of pNextFrame in following states, until the
if( pNxtNd ) // next READ_NEXT_PARA, relies on this update
pNextFrame = GetNextNode();
if (pNextFrame)
{ {
bNxtEmpty = IsEmptyLine( *pNxtNd ); bNxtEmpty = IsEmptyLine(*pNextFrame);
bNxtAlpha = IsNoAlphaLine( *pNxtNd ); bNxtAlpha = IsNoAlphaLine(*pNextFrame);
nNxtLevel = CalcLevel( *pNxtNd ); nNxtLevel = CalcLevel(*pNextFrame);
if( !bEmptyLine && HasBreakAttr( *m_pCurTextNd ) ) if (!bEmptyLine && HasBreakAttr(*m_pCurTextFrame))
bEmptyLine = true; bEmptyLine = true;
if( !bNxtEmpty && HasBreakAttr( *pNxtNd ) ) if (!bNxtEmpty && HasBreakAttr(*pNextFrame))
bNxtEmpty = true; bNxtEmpty = true;
} }
...@@ -2399,7 +2458,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2399,7 +2458,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
if( !bReplaceStyles ) if( !bReplaceStyles )
break; break;
const OUString sClrStr( DelLeadingBlanks(m_pCurTextNd->GetText()) ); const OUString sClrStr( DelLeadingBlanks(m_pCurTextFrame->GetText()) );
if( sClrStr.isEmpty() ) if( sClrStr.isEmpty() )
{ {
...@@ -2409,8 +2468,8 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2409,8 +2468,8 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
} }
// check if headline // check if headline
if( !bEmptyLine || !IsFirstCharCapital( *m_pCurTextNd ) || if (!bEmptyLine || !IsFirstCharCapital(*m_pCurTextFrame)
IsBlanksInString( *m_pCurTextNd ) ) || IsBlanksInString(*m_pCurTextFrame))
break; break;
bEmptyLine = false; bEmptyLine = false;
...@@ -2427,9 +2486,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2427,9 +2486,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
else if( 256 <= cLast || !strchr( ",.;", cLast ) ) else if( 256 <= cLast || !strchr( ",.;", cLast ) )
{ {
if( bNxtEmpty || bNxtAlpha if( bNxtEmpty || bNxtAlpha
|| ( pNxtNd && IsEnumericChar( *pNxtNd )) || (pNextFrame && IsEnumericChar(*pNextFrame)))
)
{ {
// one level below? // one level below?
...@@ -2465,7 +2522,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2465,7 +2522,7 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
case TST_ENUMERIC: case TST_ENUMERIC:
{ {
bEmptyLine = false; bEmptyLine = false;
if( IsEnumericChar( *m_pCurTextNd )) if (IsEnumericChar(*m_pCurTextFrame))
{ {
if( nLevel >= MAXLEVEL ) if( nLevel >= MAXLEVEL )
nLevel = MAXLEVEL-1; nLevel = MAXLEVEL-1;
...@@ -2492,9 +2549,9 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2492,9 +2549,9 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
BuildTextIndent(); BuildTextIndent();
eStat = READ_NEXT_PARA; eStat = READ_NEXT_PARA;
} }
else if( nLevel && pNxtNd && else if (nLevel && pNextFrame &&
!bNxtEmpty && !bNxtAlpha && !nNxtLevel && !bNxtEmpty && !bNxtAlpha && !nNxtLevel &&
!IsEnumericChar( *pNxtNd ) ) !IsEnumericChar(*pNextFrame))
{ {
// is an indentation // is an indentation
BuildIndent(); BuildIndent();
...@@ -2518,9 +2575,9 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2518,9 +2575,9 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
BuildText(); BuildText();
eStat = READ_NEXT_PARA; eStat = READ_NEXT_PARA;
} }
else if( !nLevel && pNxtNd && else if (!nLevel && pNextFrame &&
!bNxtEmpty && !bNxtAlpha && nNxtLevel && !bNxtEmpty && !bNxtAlpha && nNxtLevel &&
!IsEnumericChar( *pNxtNd ) ) !IsEnumericChar(*pNextFrame))
{ {
// is a negative indentation // is a negative indentation
BuildNegIndent( aFInfo.GetLineStart() ); BuildNegIndent( aFInfo.GetLineStart() );
...@@ -2563,12 +2620,12 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & ...@@ -2563,12 +2620,12 @@ SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const &
DelMoreLinesBlanks(); DelMoreLinesBlanks();
// handle hard attributes // handle hard attributes
if( m_pCurTextNd->HasSwAttrSet() ) if (m_pCurTextFrame->GetTextNodeForParaProps()->HasSwAttrSet())
{ {
short nSz; short nSz;
SvxLRSpaceItem const * pLRSpace; SvxLRSpaceItem const * pLRSpace;
if( bReplaceStyles && if( bReplaceStyles &&
SfxItemState::SET == m_pCurTextNd->GetSwAttrSet(). SfxItemState::SET == m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().
GetItemState( RES_LR_SPACE, false, GetItemState( RES_LR_SPACE, false,
reinterpret_cast<const SfxPoolItem**>(&pLRSpace) ) && reinterpret_cast<const SfxPoolItem**>(&pLRSpace) ) &&
( 0 != (nSz = pLRSpace->GetTextFirstLineOfst()) || ( 0 != (nSz = pLRSpace->GetTextFirstLineOfst()) ||
...@@ -2667,7 +2724,8 @@ void SwEditShell::AutoFormatBySplitNode() ...@@ -2667,7 +2724,8 @@ void SwEditShell::AutoFormatBySplitNode()
else else
{ {
// then go one node backwards // then go one node backwards
SwNodeIndex aNdIdx( pCursor->GetMark()->nNode, -1 ); SwNodeIndex aNdIdx(pCursor->GetMark()->nNode);
sw::GotoPrevLayoutTextFrame(aNdIdx, GetLayout());
SwTextNode* pTextNd = aNdIdx.GetNode().GetTextNode(); SwTextNode* pTextNd = aNdIdx.GetNode().GetTextNode();
if (pTextNd && !pTextNd->GetText().isEmpty()) if (pTextNd && !pTextNd->GetText().isEmpty())
{ {
......
...@@ -21,8 +21,11 @@ ...@@ -21,8 +21,11 @@
#define INCLUDED_SW_SOURCE_CORE_INC_FRMINF_HXX #define INCLUDED_SW_SOURCE_CORE_INC_FRMINF_HXX
#include <swtypes.hxx> #include <swtypes.hxx>
#include "TextFrameIndex.hxx" #include "TextFrameIndex.hxx"
#include <vector>
class SwTextFrame; class SwTextFrame;
class SwPaM; class SwPaM;
class SwTextCursor; class SwTextCursor;
...@@ -50,7 +53,8 @@ public: ...@@ -50,7 +53,8 @@ public:
SwTwips GetCharPos(TextFrameIndex nChar, bool bCenter = true) const; SwTwips GetCharPos(TextFrameIndex nChar, bool bCenter = true) const;
// collect all whitespaces at the beginning and end of a line in Pam // collect all whitespaces at the beginning and end of a line in Pam
void GetSpaces( SwPaM &rPam, bool bWithLineBreak ) const; void GetSpaces(std::vector<std::pair<TextFrameIndex, TextFrameIndex>> &,
bool bWithLineBreak) const;
// Is a bullet point/symbol/etc. at the first text position? // Is a bullet point/symbol/etc. at the first text position?
bool IsBullet(TextFrameIndex nTextPos) const; bool IsBullet(TextFrameIndex nTextPos) const;
......
...@@ -131,39 +131,31 @@ SwTwips SwTextFrameInfo::GetCharPos(TextFrameIndex const nChar, bool bCenter) co ...@@ -131,39 +131,31 @@ SwTwips SwTextFrameInfo::GetCharPos(TextFrameIndex const nChar, bool bCenter) co
return (( nNext + nStt ) / 2 ) - aRectFnSet.GetLeft(pFrame->getFrameArea()); return (( nNext + nStt ) / 2 ) - aRectFnSet.GetLeft(pFrame->getFrameArea());
} }
static SwPaM *AddPam( SwPaM *pPam, const SwTextFrame* pTextFrame, static void
AddRange(std::vector<std::pair<TextFrameIndex, TextFrameIndex>> & rRanges,
TextFrameIndex const nPos, TextFrameIndex const nLen) TextFrameIndex const nPos, TextFrameIndex const nLen)
{ {
assert(rRanges.empty() || rRanges.back().second <= nPos);
if( nLen ) if( nLen )
{ {
SwPosition const start(pTextFrame->MapViewToModelPos(nPos)); if (!rRanges.empty() && nPos == rRanges.back().second)
SwPosition const end(pTextFrame->MapViewToModelPos(nPos + nLen));
// It could be the first
if( pPam->HasMark() )
{ {
// If the new position is right after the current one, then rRanges.back().second += nLen;
// simply extend the Pam }
if (start == *pPam->GetPoint()) else
{ {
*pPam->GetPoint() = end; rRanges.emplace_back(nPos, nPos + nLen);
return pPam;
}
pPam = new SwPaM(*pPam, pPam);
} }
*pPam->GetPoint() = start;
pPam->SetMark();
*pPam->GetPoint() = end;
} }
return pPam;
} }
// Accumulates the whitespace at line start and end in the Pam // Accumulates the whitespace at line start and end in the vector
void SwTextFrameInfo::GetSpaces( SwPaM &rPam, bool bWithLineBreak ) const void SwTextFrameInfo::GetSpaces(
std::vector<std::pair<TextFrameIndex, TextFrameIndex>> & rRanges,
bool const bWithLineBreak) const
{ {
SwTextSizeInfo aInf( const_cast<SwTextFrame*>(pFrame) ); SwTextSizeInfo aInf( const_cast<SwTextFrame*>(pFrame) );
SwTextMargin aLine( const_cast<SwTextFrame*>(pFrame), &aInf ); SwTextMargin aLine( const_cast<SwTextFrame*>(pFrame), &aInf );
SwPaM *pPam = &rPam;
bool bFirstLine = true; bool bFirstLine = true;
do { do {
...@@ -173,8 +165,7 @@ void SwTextFrameInfo::GetSpaces( SwPaM &rPam, bool bWithLineBreak ) const ...@@ -173,8 +165,7 @@ void SwTextFrameInfo::GetSpaces( SwPaM &rPam, bool bWithLineBreak ) const
// Do NOT include the blanks/tabs from the first line // Do NOT include the blanks/tabs from the first line
// in the selection // in the selection
if( !bFirstLine && nPos > aLine.GetStart() ) if( !bFirstLine && nPos > aLine.GetStart() )
pPam = AddPam( pPam, pFrame, aLine.GetStart(), AddRange( rRanges, aLine.GetStart(), nPos - aLine.GetStart() );
nPos - aLine.GetStart() );
// Do NOT include the blanks/tabs from the last line // Do NOT include the blanks/tabs from the last line
// in the selection // in the selection
...@@ -187,7 +178,7 @@ void SwTextFrameInfo::GetSpaces( SwPaM &rPam, bool bWithLineBreak ) const ...@@ -187,7 +178,7 @@ void SwTextFrameInfo::GetSpaces( SwPaM &rPam, bool bWithLineBreak ) const
TextFrameIndex const nOff( !bWithLineBreak && CH_BREAK == TextFrameIndex const nOff( !bWithLineBreak && CH_BREAK ==
aLine.GetInfo().GetChar(aLine.GetEnd() - TextFrameIndex(1)) aLine.GetInfo().GetChar(aLine.GetEnd() - TextFrameIndex(1))
? 1 : 0 ); ? 1 : 0 );
pPam = AddPam( pPam, pFrame, nPos, aLine.GetEnd() - nPos - nOff ); AddRange( rRanges, nPos, aLine.GetEnd() - nPos - nOff );
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment