diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2018-11-28 15:51:02 +0100 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2018-12-01 08:44:45 +0100 |
commit | 9926ea7dd07f1f3d012ddf97941a42bb7fa5717d (patch) | |
tree | d5b15624925a913783536b3925572c741f0692a0 | |
parent | eb92dc08f2abf5ed088da0d736266f213adf00de (diff) |
sw_redlinehide_4a: SwAutoCorrDoc iterates frames, not nodes
Adapt this in a similar way, with a DeleteSel() that skips over
delete redlines.
The Replace functions fortunately only have callers that replace 1
character currently, but there is another ReplaceRange() call that
needs a litte more complicated handling.
Change-Id: Idd5c80e96c0f355d3dc965b2f70376258d23e1a3
-rw-r--r-- | sw/source/core/edit/acorrect.cxx | 173 | ||||
-rw-r--r-- | sw/source/core/edit/autofmt.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/inc/acorrect.hxx | 12 |
3 files changed, 148 insertions, 41 deletions
diff --git a/sw/source/core/edit/acorrect.cxx b/sw/source/core/edit/acorrect.cxx index a78c94942ec8..e5ca4d63c69b 100644 --- a/sw/source/core/edit/acorrect.cxx +++ b/sw/source/core/edit/acorrect.cxx @@ -27,6 +27,8 @@ #include <editsh.hxx> #include <doc.hxx> #include <pam.hxx> +#include <unocrsr.hxx> +#include <txtfrm.hxx> #include <ndtxt.hxx> #include <acorrect.hxx> #include <shellio.hxx> @@ -100,12 +102,32 @@ SwAutoCorrDoc::~SwAutoCorrDoc() void SwAutoCorrDoc::DeleteSel( SwPaM& rDelPam ) { + // this should work with plain SwPaM as well because start and end + // are always in same node, but since there is GetRanges already... + std::vector<std::shared_ptr<SwUnoCursor>> ranges; + if (sw::GetRanges(ranges, *rEditSh.GetDoc(), rDelPam)) + { + DeleteSelImpl(rDelPam); + } + else + { + for (auto const& pCursor : ranges) + { + DeleteSelImpl(*pCursor); + } + } +} + +void SwAutoCorrDoc::DeleteSelImpl(SwPaM & rDelPam) +{ SwDoc* pDoc = rEditSh.GetDoc(); if( pDoc->IsAutoFormatRedline() ) { // so that also the DelPam be moved, include it in the // Shell-Cursr-Ring !! - PaMIntoCursorShellRing aTmp( rEditSh, rCursor, rDelPam ); + // ??? is that really necessary - this should never join nodes, so Update should be enough? +// PaMIntoCursorShellRing aTmp( rEditSh, rCursor, rDelPam ); + assert(rDelPam.GetPoint()->nNode == rDelPam.GetMark()->nNode); pDoc->getIDocumentContentOperations().DeleteAndJoin( rDelPam ); } else @@ -116,8 +138,12 @@ void SwAutoCorrDoc::DeleteSel( SwPaM& rDelPam ) bool SwAutoCorrDoc::Delete( sal_Int32 nStt, sal_Int32 nEnd ) { - const SwNodeIndex& rNd = rCursor.GetPoint()->nNode; - SwPaM aSel( rNd, nStt, rNd, nEnd ); + SwTextNode const*const pTextNd = rCursor.GetNode().GetTextNode(); + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>( + pTextNd->getLayoutFrame(rEditSh.GetLayout()))); + assert(pFrame); + SwPaM aSel(pFrame->MapViewToModelPos(TextFrameIndex(nStt)), + pFrame->MapViewToModelPos(TextFrameIndex(nEnd))); DeleteSel( aSel ); if( bUndoIdInitialized ) @@ -127,7 +153,11 @@ bool SwAutoCorrDoc::Delete( sal_Int32 nStt, sal_Int32 nEnd ) bool SwAutoCorrDoc::Insert( sal_Int32 nPos, const OUString& rText ) { - SwPaM aPam( rCursor.GetPoint()->nNode.GetNode(), nPos ); + SwTextNode const*const pTextNd = rCursor.GetNode().GetTextNode(); + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>( + pTextNd->getLayoutFrame(rEditSh.GetLayout()))); + assert(pFrame); + SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(nPos))); rEditSh.GetDoc()->getIDocumentContentOperations().InsertString( aPam, rText ); if( !bUndoIdInitialized ) { @@ -148,28 +178,43 @@ bool SwAutoCorrDoc::Replace( sal_Int32 nPos, const OUString& rText ) bool SwAutoCorrDoc::ReplaceRange( sal_Int32 nPos, sal_Int32 nSourceLength, const OUString& rText ) { - SwPaM* pPam = &rCursor; - if( pPam->GetPoint()->nContent.GetIndex() != nPos ) + assert(nSourceLength == 1); // sw_redlinehide: this is currently the case, + // and ensures that the replace range cannot *contain* delete redlines, + // so we don't need something along the lines of: + // if (sw::GetRanges(ranges, *rEditSh.GetDoc(), aPam)) + // ReplaceImpl(...) + // else + // ReplaceImpl(ranges.begin()) + // for (ranges.begin() + 1; ranges.end(); ) + // DeleteImpl(*it) + + SwTextNode * const pNd = rCursor.GetNode().GetTextNode(); + if ( !pNd ) { - pPam = new SwPaM( *rCursor.GetPoint() ); - pPam->GetPoint()->nContent = nPos; + return false; } - SwTextNode * const pNd = pPam->GetNode().GetTextNode(); - if ( !pNd ) + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>( + pNd->getLayoutFrame(rEditSh.GetLayout()))); + assert(pFrame); + std::pair<SwTextNode *, sal_Int32> const pos(pFrame->MapViewToModel(TextFrameIndex(nPos))); + + SwPaM* pPam = &rCursor; + if (pPam->GetPoint()->nNode != *pos.first + || pPam->GetPoint()->nContent != pos.second) { - return false; + pPam = new SwPaM(*pos.first, pos.second); } // text attributes with dummy characters must not be replaced! bool bDoReplace = true; sal_Int32 const nLen = rText.getLength(); - for ( sal_Int32 n = 0; n < nLen && n + nPos < pNd->GetText().getLength(); ++n ) + for (sal_Int32 n = 0; n < nLen && n + nPos < pFrame->GetText().getLength(); ++n) { - sal_Unicode const Char = pNd->GetText()[n + nPos]; - if ( ( CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char ) - && pNd->GetTextAttrForCharAt( n + nPos ) ) + sal_Unicode const Char = pFrame->GetText()[n + nPos]; + if (CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char) { + assert(pFrame->MapViewToModel(TextFrameIndex(n+nPos)).first->GetTextAttrForCharAt(pFrame->MapViewToModel(TextFrameIndex(n+nPos)).second)); bDoReplace = false; break; } @@ -181,17 +226,18 @@ bool SwAutoCorrDoc::ReplaceRange( sal_Int32 nPos, sal_Int32 nSourceLength, const if( pDoc->IsAutoFormatRedline() ) { - if (nPos == pNd->GetText().getLength()) // at the End do an Insert + if (nPos == pFrame->GetText().getLength()) // at the End do an Insert { pDoc->getIDocumentContentOperations().InsertString( *pPam, rText ); } else { + assert(pos.second != pos.first->Len()); // must be _before_ char PaMIntoCursorShellRing aTmp( rEditSh, rCursor, *pPam ); pPam->SetMark(); pPam->GetPoint()->nContent = std::min<sal_Int32>( - pNd->GetText().getLength(), nPos + nSourceLength); + pos.first->GetText().getLength(), pos.second + nSourceLength); pDoc->getIDocumentContentOperations().ReplaceRange( *pPam, rText, false ); pPam->Exchange(); pPam->DeleteMark(); @@ -203,7 +249,7 @@ bool SwAutoCorrDoc::ReplaceRange( sal_Int32 nPos, sal_Int32 nSourceLength, const { pPam->SetMark(); pPam->GetPoint()->nContent = std::min<sal_Int32>( - pNd->GetText().getLength(), nPos + nSourceLength); + pos.first->GetText().getLength(), pos.second + nSourceLength); pDoc->getIDocumentContentOperations().ReplaceRange( *pPam, rText, false ); pPam->Exchange(); pPam->DeleteMark(); @@ -232,8 +278,12 @@ bool SwAutoCorrDoc::ReplaceRange( sal_Int32 nPos, sal_Int32 nSourceLength, const void SwAutoCorrDoc::SetAttr( sal_Int32 nStt, sal_Int32 nEnd, sal_uInt16 nSlotId, SfxPoolItem& rItem ) { - const SwNodeIndex& rNd = rCursor.GetPoint()->nNode; - SwPaM aPam( rNd, nStt, rNd, nEnd ); + SwTextNode const*const pTextNd = rCursor.GetNode().GetTextNode(); + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>( + pTextNd->getLayoutFrame(rEditSh.GetLayout()))); + assert(pFrame); + SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(nStt)), + pFrame->MapViewToModelPos(TextFrameIndex(nEnd))); SfxItemPool& rPool = rEditSh.GetDoc()->GetAttrPool(); sal_uInt16 nWhich = rPool.GetWhich( nSlotId, false ); @@ -253,8 +303,12 @@ void SwAutoCorrDoc::SetAttr( sal_Int32 nStt, sal_Int32 nEnd, sal_uInt16 nSlotId, bool SwAutoCorrDoc::SetINetAttr( sal_Int32 nStt, sal_Int32 nEnd, const OUString& rURL ) { - const SwNodeIndex& rNd = rCursor.GetPoint()->nNode; - SwPaM aPam( rNd, nStt, rNd, nEnd ); + SwTextNode const*const pTextNd = rCursor.GetNode().GetTextNode(); + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>( + pTextNd->getLayoutFrame(rEditSh.GetLayout()))); + assert(pFrame); + SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(nStt)), + pFrame->MapViewToModelPos(TextFrameIndex(nEnd))); SfxItemSet aSet( rEditSh.GetDoc()->GetAttrPool(), svl::Items<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT>{} ); @@ -276,18 +330,25 @@ OUString const* SwAutoCorrDoc::GetPrevPara(bool const bAtNormalPos) OUString const* pStr(nullptr); if( bAtNormalPos || !pIdx ) - pIdx.reset(new SwNodeIndex( rCursor.GetPoint()->nNode, -1 )); - else - --(*pIdx); + { + pIdx.reset(new SwNodeIndex(rCursor.GetPoint()->nNode)); + } + sw::GotoPrevLayoutTextFrame(*pIdx, rEditSh.GetLayout()); - SwTextNode* pTNd = pIdx->GetNode().GetTextNode(); - while (pTNd && !pTNd->GetText().getLength()) + SwTextFrame const* pFrame(nullptr); + for (SwTextNode * pTextNd = pIdx->GetNode().GetTextNode(); + pTextNd; pTextNd = pIdx->GetNode().GetTextNode()) { - --(*pIdx); - pTNd = pIdx->GetNode().GetTextNode(); + pFrame = static_cast<SwTextFrame const*>( + pTextNd->getLayoutFrame(rEditSh.GetLayout())); + if (pFrame && !pFrame->GetText().isEmpty()) + { + break; + } + sw::GotoPrevLayoutTextFrame(*pIdx, rEditSh.GetLayout()); } - if( pTNd && 0 == pTNd->GetAttrOutlineLevel() ) - pStr = & pTNd->GetText(); + if (pFrame && 0 == pFrame->GetTextNodeForParaProps()->GetAttrOutlineLevel()) + pStr = & pFrame->GetText(); if( bUndoIdInitialized ) bUndoIdInitialized = true; @@ -316,20 +377,24 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, eLang = GetAppLanguage(); LanguageTag aLanguageTag( eLang); + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>( + pTextNd->getLayoutFrame(rEditSh.GetLayout()))); + assert(pFrame); + //JP 22.04.99: Bug 63883 - Special treatment for dots. - bool bLastCharIsPoint = nEndPos < pTextNd->GetText().getLength() && - ('.' == pTextNd->GetText()[nEndPos]); + bool bLastCharIsPoint = nEndPos < pFrame->GetText().getLength() && + ('.' == pFrame->GetText()[nEndPos]); const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList( - pTextNd->GetText(), rSttPos, nEndPos, *this, aLanguageTag ); + pFrame->GetText(), rSttPos, nEndPos, *this, aLanguageTag); SwDoc* pDoc = rEditSh.GetDoc(); if( pFnd ) { // replace also last colon of keywords surrounded by colons (for example, ":name:") bool replaceLastChar = pFnd->GetShort()[0] == ':' && pFnd->GetShort().endsWith(":"); - const SwNodeIndex& rNd = rCursor.GetPoint()->nNode; - SwPaM aPam( rNd, rSttPos, rNd, nEndPos + (replaceLastChar ? 1 : 0) ); + SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(rSttPos)), + pFrame->MapViewToModelPos(TextFrameIndex(nEndPos + (replaceLastChar ? 1 : 0)))); if( pFnd->IsTextOnly() ) { @@ -338,7 +403,23 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, '.' != pFnd->GetLong()[ pFnd->GetLong().getLength() - 1 ] ) { // replace the selection - pDoc->getIDocumentContentOperations().ReplaceRange( aPam, pFnd->GetLong(), false); + std::vector<std::shared_ptr<SwUnoCursor>> ranges; + if (sw::GetRanges(ranges, *rEditSh.GetDoc(), aPam)) + { + pDoc->getIDocumentContentOperations().ReplaceRange(aPam, pFnd->GetLong(), false); + } + else + { + assert(!ranges.empty()); + assert(ranges.front()->GetPoint()->nNode == ranges.front()->GetMark()->nNode); + pDoc->getIDocumentContentOperations().ReplaceRange( + *ranges.front(), pFnd->GetLong(), false); + for (auto it = ranges.begin() + 1; it != ranges.end(); ++it) + { + DeleteSel(**it); + } + } + // tdf#83260 After calling sw::DocumentContentOperationsManager::ReplaceRange // pTextNd may become invalid when change tracking is on and Edit -> Track Changes -> Show == OFF. // ReplaceRange shows changes, this moves deleted nodes from special section to document. @@ -360,7 +441,8 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, if( pPara ) { OSL_ENSURE( !pIdx, "who has not deleted his Index?" ); - pIdx.reset(new SwNodeIndex( rCursor.GetPoint()->nNode, -1 )); + pIdx.reset(new SwNodeIndex( rCursor.GetPoint()->nNode )); + sw::GotoPrevLayoutTextFrame(*pIdx, rEditSh.GetLayout()); } SwDoc* pAutoDoc = aTBlks.GetDoc(); @@ -391,7 +473,7 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, if( pPara ) { - ++(*pIdx); + sw::GotoNextLayoutTextFrame(*pIdx, rEditSh.GetLayout()); pTextNd = pIdx->GetNode().GetTextNode(); } bRet = true; @@ -401,7 +483,11 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, } if( bRet && pPara && pTextNd ) - *pPara = pTextNd->GetText(); + { + SwTextFrame const*const pNewFrame(static_cast<SwTextFrame const*>( + pTextNd->getLayoutFrame(rEditSh.GetLayout()))); + *pPara = pNewFrame->GetText(); + } return bRet; } @@ -428,7 +514,12 @@ LanguageType SwAutoCorrDoc::GetLanguage( sal_Int32 nPos ) const SwTextNode* pNd = rCursor.GetPoint()->nNode.GetNode().GetTextNode(); if( pNd ) - eRet = pNd->GetLang( nPos ); + { + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>( + pNd->getLayoutFrame(rEditSh.GetLayout()))); + assert(pFrame); + eRet = pFrame->GetLangOfChar(TextFrameIndex(nPos), 0, true); + } if(LANGUAGE_SYSTEM == eRet) eRet = GetAppLanguage(); return eRet; diff --git a/sw/source/core/edit/autofmt.cxx b/sw/source/core/edit/autofmt.cxx index 3b3e3f648063..e9fa364fa267 100644 --- a/sw/source/core/edit/autofmt.cxx +++ b/sw/source/core/edit/autofmt.cxx @@ -1118,6 +1118,8 @@ void SwAutoFormat::DeleteLeadingTrailingBlanks(bool bStart, bool bEnd) } } +namespace sw { + bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges, SwDoc & rDoc, SwPaM const& rDelPam) { @@ -1163,6 +1165,8 @@ bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges, return isNoRedline; } +} // namespace sw + void SwAutoFormat::DeleteSel(SwPaM & rDelPam) { std::vector<std::shared_ptr<SwUnoCursor>> ranges; // need correcting cursor diff --git a/sw/source/core/inc/acorrect.hxx b/sw/source/core/inc/acorrect.hxx index f14edf751681..73f63c1ebac8 100644 --- a/sw/source/core/inc/acorrect.hxx +++ b/sw/source/core/inc/acorrect.hxx @@ -21,10 +21,14 @@ #define INCLUDED_SW_SOURCE_CORE_INC_ACORRECT_HXX #include <memory> +#include <vector> + #include <tools/solar.h> #include <editeng/svxacorr.hxx> #include <swundo.hxx> +class SwDoc; +class SwUnoCursor; class SwEditShell; class SwPaM; class SwNodeIndex; @@ -53,6 +57,7 @@ class SwAutoCorrDoc : public SvxAutoCorrDoc bool bUndoIdInitialized; void DeleteSel( SwPaM& rDelPam ); + void DeleteSelImpl(SwPaM & rDelPam); public: SwAutoCorrDoc( SwEditShell& rEditShell, SwPaM& rPam, sal_Unicode cIns = 0 ); @@ -111,6 +116,13 @@ public: bool CheckDelChar(const SwPosition& rPos); }; +namespace sw { + +bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges, + SwDoc & rDoc, SwPaM const& rDelPam); + +} // namespace sw + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |