summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2018-11-28 15:51:02 +0100
committerMichael Stahl <Michael.Stahl@cib.de>2018-12-01 08:44:45 +0100
commit9926ea7dd07f1f3d012ddf97941a42bb7fa5717d (patch)
treed5b15624925a913783536b3925572c741f0692a0
parenteb92dc08f2abf5ed088da0d736266f213adf00de (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.cxx173
-rw-r--r--sw/source/core/edit/autofmt.cxx4
-rw-r--r--sw/source/core/inc/acorrect.hxx12
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: */