ofz#18534 sw: WW8 import: avoid creating redlines that overlap...
...with fieldmarks, as the editing operations already do.
This was triggering ~SwIndexReg assert when creating this redline:
$4 = " \b\nfür \a\003 \b\nKlasse \a\003 \b\t\tSchuljahr \a\003 \b\t\a\003 \b. Halbjahr\nLeistungsbeurteilung lt. Konferenzbeschluss vom "
Change-Id: I904be93e044c4b98bb8c806357ed061692303c7a
Reviewed-on: https://gerrit.libreoffice.org/85149
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sw/qa/core/data/ww8/pass/ofz18534-1.doc b/sw/qa/core/data/ww8/pass/ofz18534-1.doc
new file mode 100644
index 0000000..6b50fdd
--- /dev/null
+++ b/sw/qa/core/data/ww8/pass/ofz18534-1.doc
Binary files differ
diff --git a/sw/source/filter/basflt/fltshell.cxx b/sw/source/filter/basflt/fltshell.cxx
index 359ab56..a9727bd 100644
--- a/sw/source/filter/basflt/fltshell.cxx
+++ b/sw/source/filter/basflt/fltshell.cxx
@@ -66,6 +66,7 @@
#include <swtable.hxx>
#include <tox.hxx>
#include <expfld.hxx>
#include <bookmrk.hxx>
#include <section.hxx>
#include <tblsel.hxx>
#include <pagedesc.hxx>
@@ -131,7 +132,7 @@ void SwFltStackEntry::SetEndPos(const SwPosition& rEndPos)
m_aPtPos.SetPos(rEndPos);
}
bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck,
bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, RegionMode const eCheck,
const SwFltPosition &rMkPos, const SwFltPosition &rPtPos, bool bIsParaEnd,
sal_uInt16 nWhich)
{
@@ -180,16 +181,22 @@ bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck,
OSL_ENSURE( CheckNodesRange( rRegion.Start()->nNode,
rRegion.End()->nNode, true ),
"attribute or similar crosses section-boundaries" );
if( bCheck )
return CheckNodesRange( rRegion.Start()->nNode,
rRegion.End()->nNode, true );
else
return true;
bool bRet = true;
if (eCheck & RegionMode::CheckNodes)
{
bRet &= CheckNodesRange(rRegion.Start()->nNode,
rRegion.End()->nNode, true);
}
if (eCheck & RegionMode::CheckFieldmark)
{
bRet &= !sw::mark::IsFieldmarkOverlap(rRegion);
}
return bRet;
}
bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck) const
bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, RegionMode eCheck) const
{
return MakeRegion(pDoc, rRegion, bCheck, m_aMkPos, m_aPtPos, bIsParaEnd,
return MakeRegion(pDoc, rRegion, eCheck, m_aMkPos, m_aPtPos, bIsParaEnd,
pAttr->Which());
}
@@ -489,7 +496,7 @@ static bool MakePoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
static bool MakeBookRegionOrPoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
SwPaM& rRegion )
{
if (rEntry.MakeRegion(pDoc, rRegion, true/*bCheck*/ ))
if (rEntry.MakeRegion(pDoc, rRegion, SwFltStackEntry::RegionMode::CheckNodes))
{
if (rRegion.GetPoint()->nNode.GetNode().FindTableBoxStartNode()
!= rRegion.GetMark()->nNode.GetNode().FindTableBoxStartNode())
@@ -591,7 +598,7 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
SwNumRule* pNumRule = pDoc->FindNumRulePtr( rNumNm );
if( pNumRule )
{
if( rEntry.MakeRegion(pDoc, aRegion, true))
if (rEntry.MakeRegion(pDoc, aRegion, SwFltStackEntry::RegionMode::CheckNodes))
{
SwNodeIndex aTmpStart( aRegion.Start()->nNode );
SwNodeIndex aTmpEnd( aTmpStart );
@@ -757,7 +764,8 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
break;
case RES_FLTR_REDLINE:
{
if (rEntry.MakeRegion(pDoc, aRegion, true))
if (rEntry.MakeRegion(pDoc, aRegion,
SwFltStackEntry::RegionMode::CheckNodes|SwFltStackEntry::RegionMode::CheckFieldmark))
{
pDoc->getIDocumentRedlineAccess().SetRedlineFlags( RedlineFlags::On
| RedlineFlags::ShowInsert
@@ -791,7 +799,7 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
{
rEntry.SetIsParaEnd( IsParaEndInCPs(nStart,nEnd,bHasSdOD) );
}
if (rEntry.MakeRegion(pDoc, aRegion, false))
if (rEntry.MakeRegion(pDoc, aRegion, SwFltStackEntry::RegionMode::NoCheck))
{
if (rEntry.IsParaEnd())
{
diff --git a/sw/source/filter/inc/fltshell.hxx b/sw/source/filter/inc/fltshell.hxx
index 3bff180..e0b41c9 100644
--- a/sw/source/filter/inc/fltshell.hxx
+++ b/sw/source/filter/inc/fltshell.hxx
@@ -100,10 +100,11 @@ public:
SW_DLLPUBLIC SwFltStackEntry(const SwPosition & rStartPos, std::unique_ptr<SfxPoolItem> pHt );
SW_DLLPUBLIC ~SwFltStackEntry();
enum class RegionMode { NoCheck = 0, CheckNodes = 1<<0, CheckFieldmark = 1<<1 };
SW_DLLPUBLIC void SetEndPos( const SwPosition & rEndPos);
SW_DLLPUBLIC bool MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck) const;
SW_DLLPUBLIC bool MakeRegion(SwDoc* pDoc, SwPaM& rRegion, RegionMode eCheck) const;
SW_DLLPUBLIC static bool MakeRegion(SwDoc* pDoc, SwPaM& rRegion,
bool bCheck, const SwFltPosition &rMkPos, const SwFltPosition &rPtPos, bool bIsParaEnd=false,
RegionMode eCheck, const SwFltPosition &rMkPos, const SwFltPosition &rPtPos, bool bIsParaEnd=false,
sal_uInt16 nWhich=0);
void SetStartCP(sal_Int32 nCP) {mnStartCP = nCP;}
@@ -114,6 +115,8 @@ public:
void SetIsParaEnd(bool bArg){ bIsParaEnd = bArg;}
};
template<> struct o3tl::typed_flags<SwFltStackEntry::RegionMode>: o3tl::is_typed_flags<SwFltStackEntry::RegionMode, 0x03> {};
class SW_DLLPUBLIC SwFltControlStack
{
private:
diff --git a/sw/source/filter/ww8/writerhelper.cxx b/sw/source/filter/ww8/writerhelper.cxx
index 512812f..8628816 100644
--- a/sw/source/filter/ww8/writerhelper.cxx
+++ b/sw/source/filter/ww8/writerhelper.cxx
@@ -782,8 +782,8 @@ namespace sw
void SetInDocAndDelete::operator()(std::unique_ptr<SwFltStackEntry>& pEntry)
{
SwPaM aRegion(pEntry->m_aMkPos.m_nNode);
if (
pEntry->MakeRegion(&mrDoc, aRegion, true) &&
if (pEntry->MakeRegion(&mrDoc, aRegion,
SwFltStackEntry::RegionMode::CheckNodes|SwFltStackEntry::RegionMode::CheckFieldmark) &&
(*aRegion.GetPoint() != *aRegion.GetMark())
)
{
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 2af0bee..3c39619 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -1386,7 +1386,7 @@ void SwWW8FltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
paragraph indent to be relative to the new paragraph indent
*/
SwPaM aRegion(rTmpPos);
if (rEntry.MakeRegion(pDoc, aRegion, false))
if (rEntry.MakeRegion(pDoc, aRegion, SwFltStackEntry::RegionMode::NoCheck))
{
SvxLRSpaceItem aNewLR( *static_cast<SvxLRSpaceItem*>(rEntry.pAttr.get()) );
sal_uLong nStart = aRegion.Start()->nNode.GetIndex();
@@ -1452,7 +1452,7 @@ void SwWW8FltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
case RES_TXTATR_INETFMT:
{
SwPaM aRegion(rTmpPos);
if (rEntry.MakeRegion(pDoc, aRegion, false))
if (rEntry.MakeRegion(pDoc, aRegion, SwFltStackEntry::RegionMode::NoCheck))
{
SwFrameFormat *pFrame;
// If we have just one single inline graphic then
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index f16ca75..8ccbca6 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -3424,10 +3424,8 @@ bool SwWW8ImplReader::ConvertSubToGraphicPlacement()
SwFltPosition aPtPos(*m_pPaM->GetPoint());
SwFrameFormat *pFlyFormat = nullptr;
if (
SwFltStackEntry::MakeRegion(&m_rDoc,aRegion,false,aMkPos,aPtPos) &&
nullptr != (pFlyFormat = ContainsSingleInlineGraphic(aRegion))
)
if (SwFltStackEntry::MakeRegion(&m_rDoc, aRegion, SwFltStackEntry::RegionMode::NoCheck, aMkPos, aPtPos)
&& nullptr != (pFlyFormat = ContainsSingleInlineGraphic(aRegion)))
{
m_xCtrlStck->DeleteAndDestroy(nPos);
pFlyFormat->SetFormatAttr(SwFormatVertOrient(0, text::VertOrientation::CHAR_CENTER, text::RelOrientation::CHAR));