summaryrefslogtreecommitdiffstats
path: root/sw/source
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/core/crsr/crsrsh.cxx25
-rw-r--r--sw/source/core/crsr/pam.cxx5
-rw-r--r--sw/source/core/crsr/swcrsr.cxx4
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx14
-rw-r--r--sw/source/core/doc/docedt.cxx4
-rw-r--r--sw/source/core/doc/docfmt.cxx12
-rw-r--r--sw/source/core/doc/doctxm.cxx2
-rw-r--r--sw/source/core/docnode/ndsect.cxx4
-rw-r--r--sw/source/core/docnode/ndtbl.cxx43
-rw-r--r--sw/source/core/docnode/nodes.cxx58
-rw-r--r--sw/source/core/docnode/section.cxx7
-rw-r--r--sw/source/core/edit/editsh.cxx2
-rw-r--r--sw/source/core/edit/edsect.cxx154
-rw-r--r--sw/source/core/inc/frame.hxx2
-rw-r--r--sw/source/core/inc/sectfrm.hxx2
-rw-r--r--sw/source/core/inc/txtfrm.hxx2
-rw-r--r--sw/source/core/layout/calcmove.cxx13
-rw-r--r--sw/source/core/layout/findfrm.cxx8
-rw-r--r--sw/source/core/layout/flowfrm.cxx119
-rw-r--r--sw/source/core/layout/frmtool.cxx23
-rw-r--r--sw/source/core/layout/ftnfrm.cxx10
-rw-r--r--sw/source/core/layout/pagechg.cxx5
-rw-r--r--sw/source/core/layout/pagedesc.cxx74
-rw-r--r--sw/source/core/layout/sectfrm.cxx37
-rw-r--r--sw/source/core/layout/tabfrm.cxx18
-rw-r--r--sw/source/core/layout/trvlfrm.cxx25
-rw-r--r--sw/source/core/text/txtfrm.cxx19
-rw-r--r--sw/source/core/tox/tox.cxx8
-rw-r--r--sw/source/core/unocore/unocrsrhelper.cxx2
-rw-r--r--sw/source/core/unocore/unomap1.cxx1
-rw-r--r--sw/source/core/unocore/unoobj.cxx14
-rw-r--r--sw/source/core/unocore/unoportenum.cxx112
-rw-r--r--sw/source/core/unocore/unotext.cxx3
-rw-r--r--sw/source/filter/html/css1atr.cxx6
-rw-r--r--sw/source/filter/html/htmlatr.cxx409
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx40
-rw-r--r--sw/source/filter/ww8/rtfattributeoutput.cxx17
-rw-r--r--sw/source/filter/ww8/wrtw8nds.cxx8
-rw-r--r--sw/source/filter/ww8/wrtw8num.cxx9
-rw-r--r--sw/source/filter/ww8/ww8par3.cxx11
-rw-r--r--sw/source/ui/index/swuiidxmrk.cxx37
-rw-r--r--sw/source/uibase/dochdl/swdtflvr.cxx3
-rw-r--r--sw/source/uibase/docvw/AnnotationWin2.cxx2
-rw-r--r--sw/source/uibase/docvw/SidebarWinAcc.cxx10
-rw-r--r--sw/source/uibase/index/toxmgr.cxx3
-rw-r--r--sw/source/uibase/shells/textsh.cxx15
-rw-r--r--sw/source/uibase/sidebar/PageSizeControl.cxx1
-rw-r--r--sw/source/uibase/uiview/view2.cxx13
-rw-r--r--sw/source/uibase/utlui/uitool.cxx1
-rw-r--r--sw/source/uibase/wrtsh/wrtsh1.cxx5
50 files changed, 822 insertions, 599 deletions
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 173414ed4d..b7f6962982 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -775,6 +775,8 @@ static typename SwCursorShell::StartsWith StartsWith(SwStartNode const& rStart)
switch (rNode.GetNodeType())
{
case SwNodeType::Section:
+ if (rNode.GetSectionNode()->GetSection().IsHidden())
+ return SwCursorShell::StartsWith::HiddenSection;
continue;
case SwNodeType::Table:
return SwCursorShell::StartsWith::Table;
@@ -799,11 +801,16 @@ static typename SwCursorShell::StartsWith EndsWith(SwStartNode const& rStart)
switch (rNode.GetNodeType())
{
case SwNodeType::End:
- if (rNode.StartOfSectionNode()->IsTableNode())
+ if (auto pStartNode = rNode.StartOfSectionNode(); pStartNode->IsTableNode())
{
return SwCursorShell::StartsWith::Table;
}
-//TODO buggy SwUndoRedline in testTdf137503? assert(rNode.StartOfSectionNode()->IsSectionNode());
+ else if (pStartNode->IsSectionNode())
+ {
+ if (pStartNode->GetSectionNode()->GetSection().IsHidden())
+ return SwCursorShell::StartsWith::HiddenSection;
+ }
+ //TODO buggy SwUndoRedline in testTdf137503? assert(rNode.StartOfSectionNode()->IsSectionNode());
break;
case SwNodeType::Text:
if (rNode.GetTextNode()->IsHidden())
@@ -944,14 +951,14 @@ bool SwCursorShell::MovePage( SwWhichPage fnWhichPage, SwPosPage fnPosPage )
return bRet;
}
-bool SwCursorShell::isInHiddenTextFrame(SwShellCursor* pShellCursor)
+bool SwCursorShell::isInHiddenFrame(SwShellCursor* pShellCursor)
{
SwContentNode *pCNode = pShellCursor->GetPointContentNode();
std::pair<Point, bool> tmp(pShellCursor->GetPtPos(), false);
SwContentFrame *const pFrame = pCNode
? pCNode->getLayoutFrame(GetLayout(), pShellCursor->GetPoint(), &tmp)
: nullptr;
- return !pFrame || (pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsHiddenNow());
+ return !pFrame || pFrame->IsHiddenNow();
}
// sw_redlinehide: this should work for all cases: GoCurrPara, GoNextPara, GoPrevPara
@@ -992,7 +999,7 @@ bool SwCursorShell::MovePara(SwWhichPara fnWhichPara, SwMoveFnCollection const &
//which is what SwCursorShell::UpdateCursorPos will reset
//the position to if we pass it a position in an
//invisible hidden paragraph field
- while (isInHiddenTextFrame(pTmpCursor)
+ while (isInHiddenFrame(pTmpCursor)
|| !IsAtStartOrEndOfFrame(this, pTmpCursor, fnPosPara))
{
if (!pTmpCursor->MovePara(fnWhichPara, fnPosPara))
@@ -1796,7 +1803,7 @@ void SwCursorShell::UpdateCursorPos()
SwShellCursor* pShellCursor = getShellCursor( true );
Size aOldSz( GetDocSize() );
- if (isInHiddenTextFrame(pShellCursor) && !ExtendedSelectedAll())
+ if (isInHiddenFrame(pShellCursor) && !ExtendedSelectedAll())
{
SwCursorMoveState aTmpState(CursorMoveState::SetOnlyText);
aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
@@ -1805,14 +1812,14 @@ void SwCursorShell::UpdateCursorPos()
pShellCursor->DeleteMark();
// kde45196-1.html: try to get to a non-hidden paragraph, there must
// be one in the document body
- while (isInHiddenTextFrame(pShellCursor))
+ while (isInHiddenFrame(pShellCursor))
{
if (!pShellCursor->MovePara(GoNextPara, fnParaStart))
{
break;
}
}
- while (isInHiddenTextFrame(pShellCursor))
+ while (isInHiddenFrame(pShellCursor))
{
if (!pShellCursor->MovePara(GoPrevPara, fnParaStart))
{
@@ -3470,7 +3477,7 @@ bool SwCursorShell::FindValidContentNode( bool bOnlyText )
GetDoc()->GetDocShell()->IsReadOnlyUI() )
return true;
- if( m_pCurrentCursor->HasMark() )
+ if( m_pCurrentCursor->HasMark() && !mbSelectAll )
ClearMark();
// first check for frames
diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx
index 25bf8d0ef6..4f2ceb0a84 100644
--- a/sw/source/core/crsr/pam.cxx
+++ b/sw/source/core/crsr/pam.cxx
@@ -1060,7 +1060,7 @@ SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const &
(
nullptr == pFrame ||
( !bInReadOnly && pFrame->IsProtected() ) ||
- (pFrame->IsTextFrame() && static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow())
+ pFrame->IsHiddenNow()
) ||
( !bInReadOnly && pNd->FindSectionNode() &&
pNd->FindSectionNode()->GetSection().IsProtect()
@@ -1101,8 +1101,7 @@ SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const &
SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
if (nullptr == pFrame ||
( !bInReadOnly && pFrame->IsProtected() ) ||
- ( pFrame->IsTextFrame() &&
- static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()))
+ pFrame->IsHiddenNow())
{
pNd = nullptr;
continue;
diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index 8d0246bed1..5a2f9afead 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -913,7 +913,7 @@ static bool lcl_MakeSelFwrd( const SwNode& rSttNd, const SwNode& rEndNd,
rPam.SetMark();
rPam.GetPoint()->Assign(rEndNd);
- pCNd = SwNodes::GoPrevious( rPam.GetPoint() );
+ pCNd = SwNodes::GoPrevious(rPam.GetPoint(), true);
if( !pCNd )
return false;
rPam.GetPoint()->AssignEndIndex(*pCNd);
@@ -933,7 +933,7 @@ static bool lcl_MakeSelBkwrd( const SwNode& rSttNd, const SwNode& rEndNd,
if( !bFirst )
{
rPam.GetPoint()->Assign(rSttNd);
- pCNd = SwNodes::GoPrevious( rPam.GetPoint() );
+ pCNd = SwNodes::GoPrevious(rPam.GetPoint(), true);
if( !pCNd )
return false;
rPam.GetPoint()->AssignEndIndex(*pCNd);
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 09e0a1233e..57b8e58310 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3788,11 +3788,16 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
SwDoc& rDest = rInsPos.GetDoc();
SwNodeIndex aSavePos( rInsPos );
+ SwPaM aCopiedPaM(rRg.aStart, rRg.aEnd);
+ if (pCopiedPaM)
+ aCopiedPaM = pCopiedPaM->first;
+
if (rRg.aStart != rRg.aEnd)
{
bool bEndIsEqualEndPos = rInsPos == rRg.aEnd.GetNode();
--aSavePos;
SaveRedlEndPosForRestore aRedlRest( rInsPos, 0 );
+ auto savedEndContentIndex = aCopiedPaM.End()->GetContentIndex();
// insert behind the already copied start node
m_rDoc.GetNodes().CopyNodes( rRg, rInsPos, false, true );
@@ -3801,6 +3806,10 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
if (bEndIsEqualEndPos)
{
const_cast<SwNodeIndex&>(rRg.aEnd).Assign(aSavePos.GetNode(), +1);
+ // pCopiedPaM->first now spans a range from the start of the original selection
+ // to the end of newly added text, and the insertion point is in the middle of
+ // that range. Adjust the local copy to cover the original copied PaM.
+ aCopiedPaM.End()->Assign(rRg.aEnd, savedEndContentIndex);
}
}
@@ -3810,7 +3819,6 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
// sw_fieldmarkhide: also needs to be done before making frames
if (m_rDoc.getIDocumentMarkAccess()->getAllMarksCount())
{
- SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
SwPosition targetPos(aSavePos, SwNodeOffset(rRg.aStart != rRg.aEnd ? +1 : 0));
if (pCopiedPaM && rRg.aStart != pCopiedPaM->first.Start()->GetNode())
{
@@ -3823,7 +3831,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
targetPos = pCopiedPaM->second;
}
- sw::CopyBookmarks(pCopiedPaM ? pCopiedPaM->first : aRgTmp, targetPos, flags);
+ sw::CopyBookmarks(aCopiedPaM, targetPos, flags);
}
if (rRg.aStart != rRg.aEnd)
@@ -3914,7 +3922,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
{
::sw::UndoGuard const undoGuard(rDest.GetIDocumentUndoRedo());
- CopyFlyInFlyImpl(rRg, pCopiedPaM ? &pCopiedPaM->first : nullptr,
+ CopyFlyInFlyImpl(rRg, pCopiedPaM ? &aCopiedPaM : nullptr,
// see comment below regarding use of pCopiedPaM->second
(pCopiedPaM && rRg.aStart != pCopiedPaM->first.Start()->GetNode())
? pCopiedPaM->second.GetNode()
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index c78d8e18b6..2a5aad64de 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -553,7 +553,7 @@ uno::Any SwDoc::Spell( SwPaM& rPaM,
{
nCurrNd = pNd->EndOfSectionIndex();
}
- else if( !static_cast<SwTextFrame*>(pContentFrame)->IsHiddenNow() )
+ else if( !pContentFrame->IsHiddenNow() )
{
if( pPageCnt && *pPageCnt && pPageSt )
{
@@ -766,7 +766,7 @@ static bool lcl_HyphenateNode( SwNode* pNd, void* pArgs )
// sw_redlinehide: this will be called once per node for merged nodes;
// the fully deleted ones won't have frames so are skipped.
SwContentFrame* pContentFrame = pNode->getLayoutFrame( pNode->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() );
- if( pContentFrame && !static_cast<SwTextFrame*>(pContentFrame)->IsHiddenNow() )
+ if( pContentFrame && !pContentFrame->IsHiddenNow() )
{
sal_uInt16 *pPageSt = pHyphArgs->GetPageSt();
sal_uInt16 *pPageCnt = pHyphArgs->GetPageCnt();
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index d6c943dbcd..1c696bebb6 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -1553,21 +1553,21 @@ void SwDoc::CopyPageDesc( const SwPageDesc& rSrcDesc, SwPageDesc& rDstDesc,
{
if (pStashedFormatSrc->GetDoc() != this)
{
- SwFrameFormat* pNewFormat = new SwFrameFormat(GetAttrPool(), "CopyDesc", GetDfltFrameFormat());
+ SwFrameFormat newFormat(GetAttrPool(), "CopyDesc", GetDfltFrameFormat());
SfxItemSet aAttrSet(pStashedFormatSrc->GetAttrSet());
aAttrSet.ClearItem(RES_HEADER);
aAttrSet.ClearItem(RES_FOOTER);
- pNewFormat->DelDiffs( aAttrSet );
- pNewFormat->SetFormatAttr( aAttrSet );
+ newFormat.DelDiffs(aAttrSet);
+ newFormat.SetFormatAttr(aAttrSet);
if (bHeader)
- CopyHeader(*pStashedFormatSrc, *pNewFormat);
+ CopyHeader(*pStashedFormatSrc, newFormat);
else
- CopyFooter(*pStashedFormatSrc, *pNewFormat);
+ CopyFooter(*pStashedFormatSrc, newFormat);
- rDstDesc.StashFrameFormat(*pNewFormat, bHeader, bLeft, bFirst);
+ rDstDesc.StashFrameFormat(newFormat, bHeader, bLeft, bFirst);
}
else
{
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index f03687d810..d29223050b 100644
--- a/sw/source/core/doc/doctxm.cxx
+++ b/sw/source/core/doc/doctxm.cxx
@@ -1057,7 +1057,7 @@ void SwTOXBaseSection::Update(const SfxItemSet* pAttr,
SwSectionFormat* pSectFormat = rDoc.MakeSectionFormat();
rDoc.GetNodes().InsertTextSection(
*pHeadNd, *pSectFormat, headerData, nullptr, &aIdx.GetNode(), true, false);
-
+ pSectFormat->GetSection()->SetProtect(SwTOXBase::IsProtected());
if (pUndo)
{
pUndo->TitleSectionInserted(*pSectFormat);
diff --git a/sw/source/core/docnode/ndsect.cxx b/sw/source/core/docnode/ndsect.cxx
index cf96e1d509..1da9ecb43e 100644
--- a/sw/source/core/docnode/ndsect.cxx
+++ b/sw/source/core/docnode/ndsect.cxx
@@ -1022,9 +1022,9 @@ SwSectionNode::~SwSectionNode()
}
}
-SwFrame *SwSectionNode::MakeFrame( SwFrame *pSib )
+SwFrame* SwSectionNode::MakeFrame(SwFrame* pSib, bool bHidden)
{
- m_pSection->m_Data.SetHiddenFlag(false);
+ m_pSection->m_Data.SetHiddenFlag(bHidden);
return new SwSectionFrame( *m_pSection, pSib );
}
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index a7a2bee478..f3b3a07d63 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -888,6 +888,34 @@ const SwTable* SwDoc::TextToTable( const SwInsertTableOptions& rInsTableOpts,
return &rNdTable;
}
+static void lcl_RemoveBreaksTable(SwTableNode & rNode, SwTableFormat *const pTableFormat)
+{
+ // delete old layout frames, new ones need to be created...
+ rNode.DelFrames(nullptr);
+
+ // remove PageBreaks/PageDesc/ColBreak
+ SwFrameFormat & rFormat(*rNode.GetTable().GetFrameFormat());
+
+ if (const SvxFormatBreakItem* pItem = rFormat.GetItemIfSet(RES_BREAK, false))
+ {
+ if (pTableFormat)
+ {
+ pTableFormat->SetFormatAttr(*pItem);
+ }
+ rFormat.ResetFormatAttr(RES_BREAK);
+ }
+
+ SwFormatPageDesc const*const pPageDescItem(rFormat.GetItemIfSet(RES_PAGEDESC, false));
+ if (pPageDescItem && pPageDescItem->GetPageDesc())
+ {
+ if (pTableFormat)
+ {
+ pTableFormat->SetFormatAttr(*pPageDescItem);
+ }
+ rFormat.ResetFormatAttr(RES_PAGEDESC);
+ }
+}
+
static void lcl_RemoveBreaks(SwContentNode & rNode, SwTableFormat *const pTableFormat)
{
// delete old layout frames, new ones need to be created...
@@ -1385,10 +1413,19 @@ SwTableNode* SwNodes::TextToTable( const SwNodes::TableRanges_t & rTableNodes,
// delete frames of all contained content nodes
for( nLines = 0; aNodeIndex <= rTableNodes.rbegin()->rbegin()->aEnd; ++aNodeIndex,++nLines )
{
- SwNode& rNode = aNodeIndex.GetNode();
- if( rNode.IsContentNode() )
+ SwNode* pNode(&aNodeIndex.GetNode());
+ while (pNode->IsSectionNode()) // could be ToX field in table
+ {
+ pNode = pNode->GetNodes()[pNode->GetIndex()+1];
+ }
+ if (pNode->IsTableNode())
+ {
+ lcl_RemoveBreaksTable(static_cast<SwTableNode&>(*pNode),
+ (0 == nLines) ? pTableFormat : nullptr);
+ }
+ else if (pNode->IsContentNode())
{
- lcl_RemoveBreaks(static_cast<SwContentNode&>(rNode),
+ lcl_RemoveBreaks(static_cast<SwContentNode&>(*pNode),
(0 == nLines) ? pTableFormat : nullptr);
}
}
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index c6ecb9ccf9..3506dff230 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -1336,34 +1336,68 @@ SwContentNode* SwNodes::GoNext(SwPosition *pIdx) const
return static_cast<SwContentNode*>(pNd);
}
-SwContentNode* SwNodes::GoPrevious(SwNodeIndex *pIdx)
+SwNodeOffset SwNodes::StartOfGlobalSection(const SwNode& node) const
+{
+ const SwNodeOffset pos = node.GetIndex();
+ if (GetEndOfExtras().GetIndex() < pos)
+ // Regular ContentSection
+ return GetEndOfExtras().GetIndex() + SwNodeOffset(1);
+ if (GetEndOfAutotext().GetIndex() < pos)
+ // Redlines
+ return GetEndOfAutotext().GetIndex() + SwNodeOffset(1);
+ if (GetEndOfInserts().GetIndex() < pos)
+ {
+ // Flys/Headers/Footers
+ if (auto* p = node.FindFlyStartNode())
+ return p->GetIndex();
+ if (auto* p = node.FindHeaderStartNode())
+ return p->GetIndex();
+ if (auto* p = node.FindFooterStartNode())
+ return p->GetIndex();
+ return GetEndOfInserts().GetIndex() + SwNodeOffset(1);
+ }
+ if (GetEndOfPostIts().GetIndex() < pos)
+ {
+ // Footnotes
+ if (auto* p = node.FindFootnoteStartNode())
+ return p->GetIndex();
+ return GetEndOfPostIts().GetIndex() + SwNodeOffset(1);
+ }
+ return SwNodeOffset(0);
+}
+
+SwContentNode* SwNodes::GoPrevious(SwNodeIndex* pIdx, bool canCrossBoundary)
{
if( !pIdx->GetIndex() )
return nullptr;
SwNodeIndex aTmp( *pIdx, -1 );
+ SwNodeOffset aGlobalStart(
+ canCrossBoundary ? SwNodeOffset(0) : aTmp.GetNodes().StartOfGlobalSection(pIdx->GetNode()));
SwNode* pNd = nullptr;
- while( aTmp.GetIndex() && !( pNd = &aTmp.GetNode())->IsContentNode() )
+ while (aTmp > aGlobalStart && !(pNd = &aTmp.GetNode())->IsContentNode())
--aTmp;
- if( !aTmp.GetIndex() )
+ if (aTmp <= aGlobalStart)
pNd = nullptr;
else
(*pIdx) = aTmp;
return static_cast<SwContentNode*>(pNd);
}
-SwContentNode* SwNodes::GoPrevious(SwPosition *pIdx)
+SwContentNode* SwNodes::GoPrevious(SwPosition* pIdx, bool canCrossBoundary)
{
if( !pIdx->GetNodeIndex() )
return nullptr;
SwNodeIndex aTmp( pIdx->GetNode(), -1 );
+ SwNodeOffset aGlobalStart(
+ canCrossBoundary ? SwNodeOffset(0) : aTmp.GetNodes().StartOfGlobalSection(pIdx->GetNode()));
SwNode* pNd = nullptr;
- while( aTmp.GetIndex() && !( pNd = &aTmp.GetNode())->IsContentNode() )
+ while( aTmp > aGlobalStart && !( pNd = &aTmp.GetNode())->IsContentNode() )
--aTmp;
- if( !aTmp.GetIndex() )
+ if (aTmp <= aGlobalStart)
pNd = nullptr;
else
pIdx->Assign(aTmp);
@@ -1963,7 +1997,7 @@ SwContentNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
if (SwNodeType::Section == pNd->GetNodeType())
{
const SwSection& rSect = static_cast<const SwSectionNode*>(pNd)->GetSection();
- if( (bSkipHidden && rSect.IsHiddenFlag()) ||
+ if( (bSkipHidden && rSect.CalcHiddenFlag()) ||
(bSkipProtect && rSect.IsProtectFlag()) )
// than skip the section
aTmp = *pNd->EndOfSectionNode();
@@ -1974,7 +2008,7 @@ SwContentNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
{
const SwSection& rSect = static_cast<SwSectionNode*>(pNd->
m_pStartOfSection)->GetSection();
- if( (bSkipHidden && rSect.IsHiddenFlag()) ||
+ if( (bSkipHidden && rSect.CalcHiddenFlag()) ||
(bSkipProtect && rSect.IsProtectFlag()) )
// than skip the section
aTmp = *pNd->EndOfSectionNode();
@@ -1985,7 +2019,7 @@ SwContentNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
const SwSectionNode* pSectNd;
if( ( bSkipHidden || bSkipProtect ) &&
nullptr != (pSectNd = pNd->FindSectionNode() ) &&
- ( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) ||
+ ( ( bSkipHidden && pSectNd->GetSection().CalcHiddenFlag() ) ||
( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) )
{
aTmp = *pSectNd->EndOfSectionNode();
@@ -2072,8 +2106,9 @@ SwContentNode* SwNodes::GoPrevSection( SwNodeIndex * pIdx,
{
bool bFirst = true;
SwNodeIndex aTmp( *pIdx );
+ SwNodeOffset aGlobalStart(aTmp.GetNodes().StartOfGlobalSection(pIdx->GetNode()));
const SwNode* pNd;
- while( aTmp > SwNodeOffset(0) )
+ while (aTmp > aGlobalStart)
{
pNd = & aTmp.GetNode();
if (SwNodeType::End == pNd->GetNodeType())
@@ -2129,8 +2164,9 @@ SwContentNode* SwNodes::GoPrevSection( SwPosition * pIdx,
{
bool bFirst = true;
SwNodeIndex aTmp( pIdx->GetNode() );
+ SwNodeOffset aGlobalStart(aTmp.GetNodes().StartOfGlobalSection(pIdx->GetNode()));
const SwNode* pNd;
- while( aTmp > SwNodeOffset(0) )
+ while (aTmp > aGlobalStart)
{
pNd = & aTmp.GetNode();
if (SwNodeType::End == pNd->GetNodeType())
diff --git a/sw/source/core/docnode/section.cxx b/sw/source/core/docnode/section.cxx
index 12d9e281c2..53418541eb 100644
--- a/sw/source/core/docnode/section.cxx
+++ b/sw/source/core/docnode/section.cxx
@@ -299,14 +299,11 @@ void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, bool const bCondition)
// Tell all Children that they are hidden
const sw::SectionHidden aHint;
pFormat->CallSwClientNotify(aHint);
-
- // Delete all Frames
- pFormat->DelFrames();
}
}
else if (m_Data.IsHiddenFlag()) // show Nodes again
{
- // Show all Frames (Child Sections are accounted for by MakeFrames)
+ // Show all Frames
// Only if the Parent Section is not restricting us!
SwSection* pParentSect = pFormat->GetParentSection();
if( !pParentSect || !pParentSect->IsHiddenFlag() )
@@ -314,8 +311,6 @@ void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, bool const bCondition)
// Tell all Children that the Parent is not hidden anymore
const sw::SectionHidden aHint(false);
pFormat->CallSwClientNotify(aHint);
-
- pFormat->MakeFrames();
}
}
}
diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx
index 333eecd352..0400dc8871 100644
--- a/sw/source/core/edit/editsh.cxx
+++ b/sw/source/core/edit/editsh.cxx
@@ -796,7 +796,7 @@ void SwEditShell::SetNumberingRestart()
if( nullptr != pContentFrame )
{
// skip hidden frames - ignore protection!
- if( !static_cast<SwTextFrame*>(pContentFrame)->IsHiddenNow() )
+ if( !pContentFrame->IsHiddenNow() )
{
// if the node is numbered and the starting value of the numbering equals the
// start value of the numbering rule then set this value as hard starting value
diff --git a/sw/source/core/edit/edsect.cxx b/sw/source/core/edit/edsect.cxx
index a7e652aea9..070a37a90d 100644
--- a/sw/source/core/edit/edsect.cxx
+++ b/sw/source/core/edit/edsect.cxx
@@ -308,89 +308,121 @@ static const SwNode* lcl_SpecialInsertNode(const SwPosition* pCurrentPos)
// pInnermostNode contains the section/table before/after which we should
// insert our empty paragraph, or it will be NULL if none is found.
const SwNode* pInnermostNode = nullptr;
+ const SwSection* pSection = nullptr;
{
const SwNode* pTableNode = rCurrentNode.FindTableNode();
const SwNode* pSectionNode = rCurrentNode.FindSectionNode();
// find the table/section which is close
if( pTableNode == nullptr )
+ {
+ if( pSectionNode == nullptr )
+ return nullptr;
+
pInnermostNode = pSectionNode;
+ pSection = &static_cast<const SwSectionNode*>(pSectionNode)->GetSection();
+ }
else if ( pSectionNode == nullptr )
pInnermostNode = pTableNode;
else
{
// compare and choose the larger one
- pInnermostNode =
- ( pSectionNode->GetIndex() > pTableNode->GetIndex() )
- ? pSectionNode : pTableNode;
+ if (pSectionNode->GetIndex() > pTableNode->GetIndex())
+ {
+ pInnermostNode = pSectionNode;
+ pSection = &static_cast<const SwSectionNode*>(pSectionNode)->GetSection();
+ }
+ else
+ pInnermostNode = pTableNode;
}
}
-
- // The previous version had a check to skip empty read-only sections. Those
- // shouldn't occur, so we only need to check whether our pInnermostNode is
- // inside a protected area.
-
- // Now, pInnermostNode is NULL or the innermost section or table node.
- if( (pInnermostNode != nullptr) && !pInnermostNode->IsProtect() )
+ if(pInnermostNode != nullptr)
{
- OSL_ENSURE( pInnermostNode->IsTableNode() ||
- pInnermostNode->IsSectionNode(), "wrong node found" );
- OSL_ENSURE( ( pInnermostNode->GetIndex() <= rCurrentNode.GetIndex() )&&
- ( pInnermostNode->EndOfSectionNode()->GetIndex() >=
- rCurrentNode.GetIndex() ), "wrong node found" );
-
- // we now need to find the possible start/end positions
-
- // we found a start if
- // - we're at or just before a start node
- // - there are only start nodes between the current and pInnermostNode
- SwNodeIndex aBegin( pCurrentPos->GetNode() );
- if( rCurrentNode.IsContentNode() &&
- (pCurrentPos->GetContentIndex() == 0))
- --aBegin;
- while( (aBegin != pInnermostNode->GetIndex()) &&
- aBegin.GetNode().IsStartNode() )
- --aBegin;
- bool bStart = ( aBegin == pInnermostNode->GetIndex() );
-
- // we found an end if
- // - we're at or just before an end node
- // - there are only end nodes between the current node and
- // pInnermostNode's end node or
- // - there are only end nodes between the last table cell merged with
- // the current cell and pInnermostNode's end node
- SwNodeIndex aEnd( pCurrentPos->GetNode() );
- if( rCurrentNode.IsContentNode() &&
- ( pCurrentPos->GetContentIndex() ==
- rCurrentNode.GetContentNode()->Len() ) )
+ bool bIsProtected = pInnermostNode->IsProtect();
+
+ //special case - ToxSection
+ // - in this case the inner section could be tox header
+ // section but the new node should be before the content section
+ // protection of the tox should not prevent the insertion
+ // only protection outside needs to be checked
+ if( pSection &&
+ (SectionType::ToxHeader == pSection->GetType() ||
+ SectionType::ToxContent == pSection->GetType()))
{
- ++aEnd;
+ if (SectionType::ToxHeader == pSection->GetType())
+ {
+ if (const SwSection* pSectionParent = pSection->GetParent())
+ pInnermostNode = pSectionParent->GetFormat()->GetSectionNode();
+ }
+ bIsProtected = static_cast<const SwSectionNode*>(pInnermostNode)->IsInProtectSect();
+ }
- // tdf#156492 handle cells merged vertically in the bottom right corner
- if ( pInnermostNode->IsTableNode() )
+ // The previous version had a check to skip empty read-only sections. Those
+ // shouldn't occur, so we only need to check whether our pInnermostNode is
+ // inside a protected area.
+
+ // Now, pInnermostNode is NULL or the innermost section or table node.
+ if(!bIsProtected)
+ {
+ OSL_ENSURE( pInnermostNode->IsTableNode() ||
+ pInnermostNode->IsSectionNode(), "wrong node found" );
+ OSL_ENSURE( ( pInnermostNode->GetIndex() <= rCurrentNode.GetIndex() )&&
+ ( pInnermostNode->EndOfSectionNode()->GetIndex() >=
+ rCurrentNode.GetIndex() ), "wrong node found" );
+
+ // we now need to find the possible start/end positions
+
+ // we found a start if
+ // - we're at or just before a start node
+ // - there are only start nodes between the current and pInnermostNode
+ SwNodeIndex aBegin( pCurrentPos->GetNode() );
+ if( rCurrentNode.IsContentNode() &&
+ (pCurrentPos->GetContentIndex() == 0))
+ --aBegin;
+ while( (aBegin != pInnermostNode->GetIndex()) &&
+ aBegin.GetNode().IsStartNode() )
+ --aBegin;
+ bool bStart = ( aBegin == pInnermostNode->GetIndex() );
+
+ // we found an end if
+ // - we're at or just before an end node
+ // - there are only end nodes between the current node and
+ // pInnermostNode's end node or
+ // - there are only end nodes between the last table cell merged with
+ // the current cell and pInnermostNode's end node
+ SwNodeIndex aEnd( pCurrentPos->GetNode() );
+ if( rCurrentNode.IsContentNode() &&
+ ( pCurrentPos->GetContentIndex() ==
+ rCurrentNode.GetContentNode()->Len() ) )
{
- const SwNode* pTableBoxStartNode = pCurrentPos->GetNode().FindTableBoxStartNode();
- const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
- if ( pTableBox && pTableBox->getRowSpan() > 1 )
+ ++aEnd;
+
+ // tdf#156492 handle cells merged vertically in the bottom right corner
+ if ( pInnermostNode->IsTableNode() )
{
- const SwTableNode* pTableNd = pInnermostNode->FindTableNode();
- pTableBox = & pTableBox->FindEndOfRowSpan( pTableNd->GetTable(),
- pTableBox->getRowSpan() );
- pTableBoxStartNode = pTableBox->GetSttNd();
- aEnd = pTableBoxStartNode->GetIndex() + 2;
+ const SwNode* pTableBoxStartNode = pCurrentPos->GetNode().FindTableBoxStartNode();
+ const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
+ if ( pTableBox && pTableBox->getRowSpan() > 1 )
+ {
+ const SwTableNode* pTableNd = pInnermostNode->FindTableNode();
+ pTableBox = & pTableBox->FindEndOfRowSpan( pTableNd->GetTable(),
+ pTableBox->getRowSpan() );
+ pTableBoxStartNode = pTableBox->GetSttNd();
+ aEnd = pTableBoxStartNode->GetIndex() + 2;
+ }
}
}
+ while( (aEnd != pInnermostNode->EndOfSectionNode()->GetIndex()) &&
+ aEnd.GetNode().IsEndNode() )
+ ++aEnd;
+ bool bEnd = ( aEnd == pInnermostNode->EndOfSectionNode()->GetIndex() );
+
+ // evaluate result: if both start + end, end is preferred
+ if( bEnd )
+ pReturn = pInnermostNode->EndOfSectionNode();
+ else if ( bStart )
+ pReturn = pInnermostNode;
}
- while( (aEnd != pInnermostNode->EndOfSectionNode()->GetIndex()) &&
- aEnd.GetNode().IsEndNode() )
- ++aEnd;
- bool bEnd = ( aEnd == pInnermostNode->EndOfSectionNode()->GetIndex() );
-
- // evaluate result: if both start + end, end is preferred
- if( bEnd )
- pReturn = pInnermostNode->EndOfSectionNode();
- else if ( bStart )
- pReturn = pInnermostNode;
}
OSL_ENSURE( ( pReturn == nullptr ) || pReturn->IsStartNode() ||
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index d57654f6a9..604488a18c 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -891,6 +891,8 @@ public:
// Fly in ... and footnotes
bool IsProtected() const;
+ virtual bool IsHiddenNow() const;
+
bool IsColLocked() const { return mbColLocked; }
virtual bool IsDeleteForbidden() const { return mnForbidDelete > 0; }
diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
index c07d78b12b..69158b3358 100644
--- a/sw/source/core/inc/sectfrm.hxx
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -88,6 +88,8 @@ public:
virtual void Cut() override;
virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) override;
+ virtual bool IsHiddenNow() const override;
+
inline const SwSectionFrame *GetFollow() const;
inline SwSectionFrame *GetFollow();
SwSectionFrame* FindMaster() const;
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index e60dbd20fb..df11ca589b 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -559,7 +559,7 @@ public:
#endif
/// Hidden
- bool IsHiddenNow() const; // bHidden && pOut == pPrt
+ virtual bool IsHiddenNow() const override; // bHidden && pOut == pPrt
void HideHidden(); // Remove appendage if Hidden
void HideFootnotes(TextFrameIndex nStart, TextFrameIndex nEnd);
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx
index c2bbdd8904..e13fdf0121 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -177,7 +177,7 @@ bool SwContentFrame::ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool & )
if ( nMoveAnyway < 3 )
{
- if ( nSpace )
+ if (nSpace || IsHiddenNow())
{
// Do not notify footnotes which are stuck to the paragraph:
// This would require extremely confusing code, taking into
@@ -209,7 +209,7 @@ bool SwContentFrame::ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool & )
}
// Check for space left in new upper
- return nSpace != 0;
+ return nSpace != 0 || IsHiddenNow();
}
}
return false;
@@ -532,7 +532,7 @@ static SwFrame* lcl_NotHiddenPrev( SwFrame* pFrame )
do
{
pRet = lcl_Prev( pRet );
- } while ( pRet && pRet->IsTextFrame() && static_cast<SwTextFrame*>(pRet)->IsHiddenNow() );
+ } while ( pRet && pRet->IsHiddenNow() );
return pRet;
}
@@ -1083,9 +1083,8 @@ void SwContentFrame::MakePrtArea( const SwBorderAttrs &rAttrs )
setFramePrintAreaValid(true);
SwRectFnSet aRectFnSet(this);
- const bool bTextFrame = IsTextFrame();
SwTwips nUpper = 0;
- if ( bTextFrame && static_cast<SwTextFrame*>(this)->IsHiddenNow() )
+ if (IsTextFrame() && IsHiddenNow())
{
if ( static_cast<SwTextFrame*>(this)->HasFollow() )
static_cast<SwTextFrame*>(this)->JoinFrame();
@@ -1715,7 +1714,7 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
const bool bMoveFwdInvalid = nullptr != GetIndNext();
const bool bNxtNew =
( 0 == aRectFnSet.GetHeight(pNxt->getFramePrintArea()) ) &&
- (!pNxt->IsTextFrame() ||!static_cast<SwTextFrame*>(pNxt)->IsHiddenNow());
+ !pNxt->IsHiddenNow();
pNxt->Calc(getRootFrame()->GetCurrShell()->GetOut());
@@ -2217,7 +2216,7 @@ bool SwContentFrame::WouldFit_( SwTwips nSpace,
pTmpPrev = nullptr;
else
{
- if( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsHiddenNow() )
+ if (pFrame->IsHiddenNow())
pTmpPrev = lcl_NotHiddenPrev( pFrame );
else
pTmpPrev = pFrame;
diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx
index 5331baacd9..0dd64c6aec 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -994,7 +994,7 @@ SwFrame *SwFrame::FindNext_()
(!bFootnote || pSct->IsInFootnote() ) )
return pSct;
}
- return pRet;
+ return pRet == this ? nullptr : pRet;
}
// #i27138# - add parameter <_bInSameFootnote>
@@ -1380,11 +1380,7 @@ void SwFrame::InvalidateNextPrtArea()
SwFrame* pNextFrame = FindNext();
// skip empty section frames and hidden text frames
{
- while ( pNextFrame &&
- ( ( pNextFrame->IsSctFrame() &&
- !static_cast<SwSectionFrame*>(pNextFrame)->GetSection() ) ||
- ( pNextFrame->IsTextFrame() &&
- static_cast<SwTextFrame*>(pNextFrame)->IsHiddenNow() ) ) )
+ while (pNextFrame && pNextFrame->IsHiddenNow())
{
pNextFrame = pNextFrame->FindNext();
}
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index da509e2a6b..88158161c5 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -1271,8 +1271,7 @@ bool SwFlowFrame::IsPageBreak( bool bAct ) const
// Determine predecessor
const SwFrame *pPrev = m_rThis.FindPrev();
- while ( pPrev && ( !pPrev->IsInDocBody() ||
- ( pPrev->IsTextFrame() && static_cast<const SwTextFrame*>(pPrev)->IsHiddenNow() ) ) )
+ while (pPrev && (!pPrev->IsInDocBody() || pPrev->IsHiddenNow()))
pPrev = pPrev->FindPrev();
if ( pPrev )
@@ -1333,7 +1332,7 @@ bool SwFlowFrame::IsColBreak( bool bAct ) const
// Determine predecessor
const SwFrame *pPrev = m_rThis.FindPrev();
while( pPrev && ( ( !pPrev->IsInDocBody() && !m_rThis.IsInFly() && !m_rThis.FindFooterOrHeader() ) ||
- ( pPrev->IsTextFrame() && static_cast<const SwTextFrame*>(pPrev)->IsHiddenNow() ) ) )
+ pPrev->IsHiddenNow() ) )
pPrev = pPrev->FindPrev();
if ( pPrev )
@@ -1364,6 +1363,14 @@ bool SwFlowFrame::IsColBreak( bool bAct ) const
return false;
}
+// Skip hidden paragraphs and empty sections on the same level
+static const SwFrame* skipHiddenSiblingFrames_(const SwFrame* pFrame)
+{
+ while (pFrame && pFrame->IsHiddenNow())
+ pFrame = pFrame->GetPrev();
+ return pFrame;
+}
+
bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
{
if( m_rThis.IsInSct() )
@@ -1379,7 +1386,7 @@ bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
return !pTmp->GetPrev() || IsPageBreak(true);
if( pTmp->IsColumnFrame() && pTmp->GetPrev() )
return IsColBreak( true );
- if( pTmp->IsSctFrame() && ( !bSct || pTmp->GetPrev() ) )
+ if (pTmp->IsSctFrame() && (!bSct || skipHiddenSiblingFrames_(pTmp->GetPrev())))
return false;
pTmp = pTmp->GetUpper();
}
@@ -1401,6 +1408,31 @@ bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
return pTmp && !pTmp->GetPrev();
}
+// Skip hidden paragraphs and empty sections
+static const SwFrame* skipHiddenFrames_(const SwFrame* pFrame)
+{
+ do
+ {
+ pFrame = skipHiddenSiblingFrames_(pFrame);
+ if (!pFrame || !pFrame->IsSctFrame())
+ return pFrame;
+ // Special case: found previous frame is a section
+ // Search for the last content in the section
+ auto pSectFrame = static_cast<const SwSectionFrame*>(pFrame);
+ pFrame = pSectFrame->FindLastContent();
+ // If the last content is in a table _inside_ the section,
+ // take the table herself.
+ // Correction: Check directly, if table is inside table, instead of indirectly
+ // by checking, if section isn't inside a table
+ if (pFrame && pFrame->IsInTab())
+ {
+ const SwTabFrame* pTableFrame = pFrame->FindTabFrame();
+ if (pSectFrame->IsAnLower(pTableFrame))
+ return pTableFrame;
+ }
+ } while (true);
+}
+
/** helper method to determine previous frame for calculation of the
upper space
@@ -1408,73 +1440,21 @@ bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
*/
const SwFrame* SwFlowFrame::GetPrevFrameForUpperSpaceCalc_( const SwFrame* _pProposedPrevFrame ) const
{
- const SwFrame* pPrevFrame = _pProposedPrevFrame
- ? _pProposedPrevFrame
- : m_rThis.GetPrev();
-
- // Skip hidden paragraphs and empty sections
- while ( pPrevFrame &&
- ( ( pPrevFrame->IsTextFrame() &&
- static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ||
- ( pPrevFrame->IsSctFrame() &&
- !static_cast<const SwSectionFrame*>(pPrevFrame)->GetSection() ) ) )
- {
- pPrevFrame = pPrevFrame->GetPrev();
- }
+ const SwFrame* pPrevFrame
+ = skipHiddenFrames_(_pProposedPrevFrame ? _pProposedPrevFrame : m_rThis.GetPrev());
+ if (pPrevFrame || !m_rThis.IsInFootnote()
+ || !(m_rThis.IsSctFrame() || !m_rThis.IsInSct() || !m_rThis.FindSctFrame()->IsInFootnote()))
+ return pPrevFrame;
// Special case: no direct previous frame is found but frame is in footnote
// Search for a previous frame in previous footnote,
// if frame isn't in a section, which is also in the footnote
- if ( !pPrevFrame && m_rThis.IsInFootnote() &&
- ( m_rThis.IsSctFrame() ||
- !m_rThis.IsInSct() || !m_rThis.FindSctFrame()->IsInFootnote() ) )
- {
- const SwFootnoteFrame* pPrevFootnoteFrame =
- static_cast<const SwFootnoteFrame*>(m_rThis.FindFootnoteFrame()->GetPrev());
- if ( pPrevFootnoteFrame )
- {
- pPrevFrame = pPrevFootnoteFrame->GetLastLower();
-
- // Skip hidden paragraphs and empty sections
- while ( pPrevFrame &&
- ( ( pPrevFrame->IsTextFrame() &&
- static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ||
- ( pPrevFrame->IsSctFrame() &&
- !static_cast<const SwSectionFrame*>(pPrevFrame)->GetSection() ) ) )
- {
- pPrevFrame = pPrevFrame->GetPrev();
- }
- }
- }
- // Special case: found previous frame is a section
- // Search for the last content in the section
- if( pPrevFrame && pPrevFrame->IsSctFrame() )
- {
- const SwSectionFrame* pPrevSectFrame =
- static_cast<const SwSectionFrame*>(pPrevFrame);
- pPrevFrame = pPrevSectFrame->FindLastContent();
- // If the last content is in a table _inside_ the section,
- // take the table herself.
- // Correction: Check directly, if table is inside table, instead of indirectly
- // by checking, if section isn't inside a table
- if ( pPrevFrame && pPrevFrame->IsInTab() )
- {
- const SwTabFrame* pTableFrame = pPrevFrame->FindTabFrame();
- if ( pPrevSectFrame->IsAnLower( pTableFrame ) )
- {
- pPrevFrame = pTableFrame;
- }
- }
- // Correction: skip hidden text frames
- while ( pPrevFrame &&
- pPrevFrame->IsTextFrame() &&
- static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() )
- {
- pPrevFrame = pPrevFrame->GetPrev();
- }
- }
+ const SwFootnoteFrame* pPrevFootnoteFrame =
+ static_cast<const SwFootnoteFrame*>(m_rThis.FindFootnoteFrame()->GetPrev());
+ if ( pPrevFootnoteFrame )
+ return skipHiddenFrames_(pPrevFootnoteFrame->GetLastLower());
- return pPrevFrame;
+ return nullptr;
}
// This should be renamed to something like lcl_UseULSpacing
@@ -1912,6 +1892,8 @@ SwTwips SwFlowFrame::CalcAddLowerSpaceAsLastInTableCell(
/// Moves the Frame forward if it seems necessary regarding the current conditions and attributes.
bool SwFlowFrame::CheckMoveFwd( bool& rbMakePage, bool bKeep, bool bIgnoreMyOwnKeepValue )
{
+ if (m_rThis.IsHiddenNow())
+ return false;
const SwFrame* pNxt = m_rThis.GetIndNext();
if ( bKeep && //!bMovedBwd &&
@@ -2299,7 +2281,8 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat )
)
pNewUpper = m_rThis.GetLeaf( MAKEPAGE_FTN, false );
}
- else if ( IsPageBreak( true ) ) // Do we have to respect a PageBreak?
+ // Do we have to respect a PageBreak?
+ else if (IsPageBreak(true) && (!m_rThis.IsInSct() || !m_rThis.FindSctFrame()->IsHiddenNow()))
{
// If the previous page doesn't have a Frame in the body,
// flowing back makes sense despite the PageBreak (otherwise,
@@ -2366,7 +2349,7 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat )
}
}
}
- else if ( IsColBreak( true ) )
+ else if (IsColBreak(true))
{
// If the previous column doesn't contain a ContentFrame, flowing back
// makes sense despite the ColumnBreak, as otherwise we'd get
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index eeab5c60c1..baf632d6eb 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -844,11 +844,7 @@ void SwContentNotify::ImplDestroy()
SwFrame* pPrevFrame = pCnt->FindPrev();
// skip empty section frames and hidden text frames
{
- while ( pPrevFrame &&
- ( ( pPrevFrame->IsSctFrame() &&
- !static_cast<SwSectionFrame*>(pPrevFrame)->GetSection() ) ||
- ( pPrevFrame->IsTextFrame() &&
- static_cast<SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ) )
+ while (pPrevFrame && pPrevFrame->IsHiddenNow())
{
pPrevFrame = pPrevFrame->FindPrev();
}
@@ -1608,7 +1604,7 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
pFrame = pNode->IsTextNode()
? sw::MakeTextFrame(*pNode->GetTextNode(), pLay, eMode)
: pNode->MakeFrame(pLay);
- if( pPageMaker )
+ if (pPageMaker && !pLay->IsHiddenNow())
pPageMaker->CheckInsert( nIndex );
pFrame->InsertBehind( pLay, pPrv );
@@ -1766,15 +1762,11 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
continue; // skip it
}
SwSectionNode *pNode = static_cast<SwSectionNode*>(pNd);
- if( pNode->GetSection().CalcHiddenFlag() )
- // is hidden, skip the area
- nIndex = pNode->EndOfSectionIndex();
- else
{
if (pActualSection)
pActualSection->SetLastPos(pPrv);
- pFrame = pNode->MakeFrame( pLay );
+ pFrame = pNode->MakeFrame(pLay, pNode->GetSection().CalcHiddenFlag());
pActualSection.reset( new SwActualSection( pActualSection.release(),
static_cast<SwSectionFrame*>(pFrame), pNode ) );
if ( pActualSection->GetUpper() )
@@ -1945,7 +1937,8 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
}
else
{
- pFrame = pActualSection->GetSectionNode()->MakeFrame( pLay );
+ pFrame = pActualSection->GetSectionNode()->MakeFrame(
+ pLay, pActualSection->GetSectionNode()->GetSection().IsHiddenFlag());
pFrame->InsertBehind( pLay, pPrv );
static_cast<SwSectionFrame*>(pFrame)->Init();
@@ -2523,8 +2516,7 @@ void SwBorderAttrs::CalcJoinedWithPrev( const SwFrame& _rFrame,
// one as previous frame.
const SwFrame* pPrevFrame = _pPrevFrame ? _pPrevFrame : _rFrame.GetPrev();
// OD 2004-02-13 #i25029# - skip hidden text frames.
- while ( pPrevFrame && pPrevFrame->IsTextFrame() &&
- static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() )
+ while (pPrevFrame && pPrevFrame->IsHiddenNow())
{
pPrevFrame = pPrevFrame->GetPrev();
}
@@ -2555,8 +2547,7 @@ void SwBorderAttrs::CalcJoinedWithNext( const SwFrame& _rFrame )
// corresponding attribute set is set at current text frame.
// OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
const SwFrame* pNextFrame = _rFrame.GetNext();
- while ( pNextFrame && pNextFrame->IsTextFrame() &&
- static_cast<const SwTextFrame*>(pNextFrame)->IsHiddenNow() )
+ while (pNextFrame && pNextFrame->IsHiddenNow())
{
pNextFrame = pNextFrame->GetNext();
}
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index 70453c5727..f4e6072498 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -2965,13 +2965,9 @@ SwContentFrame* SwFootnoteFrame::FindLastContent()
while ( pTmpLastLower && pTmpLastLower->GetNext() )
{
pTmpLastLower = pTmpLastLower->GetNext();
- if ( ( pTmpLastLower->IsTextFrame() &&
- !static_cast<SwTextFrame*>(pTmpLastLower)->IsHiddenNow() ) ||
- ( pTmpLastLower->IsSctFrame() &&
- static_cast<SwSectionFrame*>(pTmpLastLower)->GetSection() &&
- static_cast<SwSectionFrame*>(pTmpLastLower)->ContainsContent() ) ||
- ( pTmpLastLower->IsTabFrame() &&
- static_cast<SwTabFrame*>(pTmpLastLower)->ContainsContent() ) )
+ if (!pTmpLastLower->IsHiddenNow()
+ && (!pTmpLastLower->IsLayoutFrame()
+ || static_cast<SwLayoutFrame*>(pTmpLastLower)->ContainsContent()))
{
pLastLowerOfFootnote = pTmpLastLower;
}
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index bf4bcc45ea..f8c029ea12 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -789,7 +789,10 @@ SwPageDesc *SwPageFrame::FindPageDesc()
return pRet;
}
- SwFrame *pFlow = FindFirstBodyContent();
+ SwContentFrame* pFirstContent = FindFirstBodyContent();
+ while (pFirstContent && pFirstContent->IsHiddenNow())
+ pFirstContent = pFirstContent->GetNextContentFrame();
+ SwFrame* pFlow = pFirstContent;
if ( pFlow && pFlow->IsInTab() )
pFlow = pFlow->FindTabFrame();
diff --git a/sw/source/core/layout/pagedesc.cxx b/sw/source/core/layout/pagedesc.cxx
index 2b78823327..f9679bb2a8 100644
--- a/sw/source/core/layout/pagedesc.cxx
+++ b/sw/source/core/layout/pagedesc.cxx
@@ -83,13 +83,13 @@ SwPageDesc::SwPageDesc( const SwPageDesc &rCpy )
, m_FootnoteInfo( rCpy.GetFootnoteInfo() )
, m_pdList( nullptr )
{
- m_aStashedHeader.m_pStashedFirst = rCpy.m_aStashedHeader.m_pStashedFirst;
- m_aStashedHeader.m_pStashedLeft = rCpy.m_aStashedHeader.m_pStashedLeft;
- m_aStashedHeader.m_pStashedFirstLeft = rCpy.m_aStashedHeader.m_pStashedFirstLeft;
+ m_aStashedHeader.m_oStashedFirst = rCpy.m_aStashedHeader.m_oStashedFirst;
+ m_aStashedHeader.m_oStashedLeft = rCpy.m_aStashedHeader.m_oStashedLeft;
+ m_aStashedHeader.m_oStashedFirstLeft = rCpy.m_aStashedHeader.m_oStashedFirstLeft;
- m_aStashedFooter.m_pStashedFirst = rCpy.m_aStashedFooter.m_pStashedFirst;
- m_aStashedFooter.m_pStashedLeft = rCpy.m_aStashedFooter.m_pStashedLeft;
- m_aStashedFooter.m_pStashedFirstLeft = rCpy.m_aStashedFooter.m_pStashedFirstLeft;
+ m_aStashedFooter.m_oStashedFirst = rCpy.m_aStashedFooter.m_oStashedFirst;
+ m_aStashedFooter.m_oStashedLeft = rCpy.m_aStashedFooter.m_oStashedLeft;
+ m_aStashedFooter.m_oStashedFirstLeft = rCpy.m_aStashedFooter.m_oStashedFirstLeft;
if (rCpy.m_pTextFormatColl && rCpy.m_aDepends.IsListeningTo(rCpy.m_pTextFormatColl))
{
@@ -110,13 +110,13 @@ SwPageDesc & SwPageDesc::operator = (const SwPageDesc & rSrc)
m_FirstMaster = rSrc.m_FirstMaster;
m_FirstLeft = rSrc.m_FirstLeft;
- m_aStashedHeader.m_pStashedFirst = rSrc.m_aStashedHeader.m_pStashedFirst;
- m_aStashedHeader.m_pStashedLeft = rSrc.m_aStashedHeader.m_pStashedLeft;
- m_aStashedHeader.m_pStashedFirstLeft = rSrc.m_aStashedHeader.m_pStashedFirstLeft;
+ m_aStashedHeader.m_oStashedFirst = rSrc.m_aStashedHeader.m_oStashedFirst;
+ m_aStashedHeader.m_oStashedLeft = rSrc.m_aStashedHeader.m_oStashedLeft;
+ m_aStashedHeader.m_oStashedFirstLeft = rSrc.m_aStashedHeader.m_oStashedFirstLeft;
- m_aStashedFooter.m_pStashedFirst = rSrc.m_aStashedFooter.m_pStashedFirst;
- m_aStashedFooter.m_pStashedLeft = rSrc.m_aStashedFooter.m_pStashedLeft;
- m_aStashedFooter.m_pStashedFirstLeft = rSrc.m_aStashedFooter.m_pStashedFirstLeft;
+ m_aStashedFooter.m_oStashedFirst = rSrc.m_aStashedFooter.m_oStashedFirst;
+ m_aStashedFooter.m_oStashedLeft = rSrc.m_aStashedFooter.m_oStashedLeft;
+ m_aStashedFooter.m_oStashedFirstLeft = rSrc.m_aStashedFooter.m_oStashedFirstLeft;
m_aDepends.EndListeningAll();
if (rSrc.m_pTextFormatColl && rSrc.m_aDepends.IsListeningTo(rSrc.m_pTextFormatColl))
@@ -416,30 +416,30 @@ void SwPageDesc::ChgFirstShare( bool bNew )
void SwPageDesc::StashFrameFormat(const SwFrameFormat& rFormat, bool bHeader, bool bLeft, bool bFirst)
{
assert(rFormat.GetRegisteredIn());
- std::shared_ptr<SwFrameFormat>* pFormat = nullptr;
+ std::optional<SwFrameFormat>* pFormat = nullptr;
if (bHeader)
{
if (bLeft && !bFirst)
- pFormat = &m_aStashedHeader.m_pStashedLeft;
+ pFormat = &m_aStashedHeader.m_oStashedLeft;
else if (!bLeft && bFirst)
- pFormat = &m_aStashedHeader.m_pStashedFirst;
+ pFormat = &m_aStashedHeader.m_oStashedFirst;
else if (bLeft && bFirst)
- pFormat = &m_aStashedHeader.m_pStashedFirstLeft;
+ pFormat = &m_aStashedHeader.m_oStashedFirstLeft;
}
else
{
if (bLeft && !bFirst)
- pFormat = &m_aStashedFooter.m_pStashedLeft;
+ pFormat = &m_aStashedFooter.m_oStashedLeft;
else if (!bLeft && bFirst)
- pFormat = &m_aStashedFooter.m_pStashedFirst;
+ pFormat = &m_aStashedFooter.m_oStashedFirst;
else if (bLeft && bFirst)
- pFormat = &m_aStashedFooter.m_pStashedFirstLeft;
+ pFormat = &m_aStashedFooter.m_oStashedFirstLeft;
}
if (pFormat)
{
- *pFormat = std::make_shared<SwFrameFormat>(rFormat);
+ pFormat->emplace(rFormat);
}
else
{
@@ -451,24 +451,24 @@ void SwPageDesc::StashFrameFormat(const SwFrameFormat& rFormat, bool bHeader, bo
const SwFrameFormat* SwPageDesc::GetStashedFrameFormat(bool bHeader, bool bLeft, bool bFirst) const
{
- std::shared_ptr<SwFrameFormat>* pFormat = nullptr;
+ std::optional<SwFrameFormat>* pFormat = nullptr;
if (bLeft && !bFirst)
{
- pFormat = bHeader ? &m_aStashedHeader.m_pStashedLeft : &m_aStashedFooter.m_pStashedLeft;
+ pFormat = bHeader ? &m_aStashedHeader.m_oStashedLeft : &m_aStashedFooter.m_oStashedLeft;
}
else if (!bLeft && bFirst)
{
- pFormat = bHeader ? &m_aStashedHeader.m_pStashedFirst : &m_aStashedFooter.m_pStashedFirst;
+ pFormat = bHeader ? &m_aStashedHeader.m_oStashedFirst : &m_aStashedFooter.m_oStashedFirst;
}
else if (bLeft && bFirst)
{
- pFormat = bHeader ? &m_aStashedHeader.m_pStashedFirstLeft : &m_aStashedFooter.m_pStashedFirstLeft;
+ pFormat = bHeader ? &m_aStashedHeader.m_oStashedFirstLeft : &m_aStashedFooter.m_oStashedFirstLeft;
}
if (pFormat)
{
- return pFormat->get();
+ return pFormat->has_value() ? &**pFormat : nullptr;
}
else
{
@@ -483,15 +483,15 @@ bool SwPageDesc::HasStashedFormat(bool bHeader, bool bLeft, bool bFirst) const
{
if (bLeft && !bFirst)
{
- return m_aStashedHeader.m_pStashedLeft != nullptr;
+ return m_aStashedHeader.m_oStashedLeft.has_value();
}
else if (!bLeft && bFirst)
{
- return m_aStashedHeader.m_pStashedFirst != nullptr;
+ return m_aStashedHeader.m_oStashedFirst.has_value();
}
else if (bLeft && bFirst)
{
- return m_aStashedHeader.m_pStashedFirstLeft != nullptr;
+ return m_aStashedHeader.m_oStashedFirstLeft.has_value();
}
else
{
@@ -503,15 +503,15 @@ bool SwPageDesc::HasStashedFormat(bool bHeader, bool bLeft, bool bFirst) const
{
if (bLeft && !bFirst)
{
- return m_aStashedFooter.m_pStashedLeft != nullptr;
+ return m_aStashedFooter.m_oStashedLeft.has_value();
}
else if (!bLeft && bFirst)
{
- return m_aStashedFooter.m_pStashedFirst != nullptr;
+ return m_aStashedFooter.m_oStashedFirst.has_value();
}
else if (bLeft && bFirst)
{
- return m_aStashedFooter.m_pStashedFirstLeft != nullptr;
+ return m_aStashedFooter.m_oStashedFirstLeft.has_value();
}
else
{
@@ -527,15 +527,15 @@ void SwPageDesc::RemoveStashedFormat(bool bHeader, bool bLeft, bool bFirst)
{
if (bLeft && !bFirst)
{
- m_aStashedHeader.m_pStashedLeft.reset();
+ m_aStashedHeader.m_oStashedLeft.reset();
}
else if (!bLeft && bFirst)
{
- m_aStashedHeader.m_pStashedFirst.reset();
+ m_aStashedHeader.m_oStashedFirst.reset();
}
else if (bLeft && bFirst)
{
- m_aStashedHeader.m_pStashedFirstLeft.reset();
+ m_aStashedHeader.m_oStashedFirstLeft.reset();
}
else
{
@@ -546,15 +546,15 @@ void SwPageDesc::RemoveStashedFormat(bool bHeader, bool bLeft, bool bFirst)
{
if (bLeft && !bFirst)
{
- m_aStashedFooter.m_pStashedLeft.reset();
+ m_aStashedFooter.m_oStashedLeft.reset();
}
else if (!bLeft && bFirst)
{
- m_aStashedFooter.m_pStashedFirst.reset();
+ m_aStashedFooter.m_oStashedFirst.reset();
}
else if (bLeft && bFirst)
{
- m_aStashedFooter.m_pStashedFirstLeft.reset();
+ m_aStashedFooter.m_oStashedFirstLeft.reset();
}
else
{
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index a1fd849ec4..3967a1f564 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -189,6 +189,13 @@ SwSectionFrame::~SwSectionFrame()
{
}
+//virtual
+bool SwSectionFrame::IsHiddenNow() const
+{
+ const auto* pSection = GetSection();
+ return !pSection || pSection->CalcHiddenFlag();
+}
+
void SwSectionFrame::DelEmpty( bool bRemove )
{
if( IsColLocked() )
@@ -1371,6 +1378,20 @@ void SwSectionFrame::Format( vcl::RenderContext* pRenderContext, const SwBorderA
SwRectFnSet aRectFnSet(this);
+ if (GetSection()->CalcHiddenFlag())
+ {
+ {
+ SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
+ aRectFnSet.SetHeight(aFrm, 0);
+ }
+ {
+ SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
+ aRectFnSet.SetHeight(aPrt, 0);
+ }
+ setFrameAreaSizeValid(true);
+ setFramePrintAreaValid(true);
+ }
+
if ( !isFramePrintAreaValid() )
{
PROTOCOL( this, PROT::PrintArea, DbgAction::NONE, nullptr )
@@ -2182,6 +2203,11 @@ bool SwSectionFrame::Growable() const
SwTwips SwSectionFrame::Grow_( SwTwips nDist, bool bTst )
{
+ if (GetSection()->CalcHiddenFlag())
+ {
+ return 0;
+ }
+
if ( !IsColLocked() && !HasFixSize() )
{
SwRectFnSet aRectFnSet(this);
@@ -2646,6 +2672,17 @@ void SwSectionFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
return;
SwSectionFrame::MoveContentAndDelete(this, pHint->IsSaveContent());
}
+ else if (rHint.GetId() == SfxHintId::SwSectionHidden)
+ {
+ InvalidateAll();
+ InvalidateObjs(false);
+
+ for (SwFrame* pLowerFrame = Lower(); pLowerFrame; pLowerFrame = pLowerFrame->GetNext())
+ {
+ pLowerFrame->InvalidateAll();
+ pLowerFrame->InvalidateObjs(false);
+ }
+ }
else
SwFrame::SwClientNotify(rMod, rHint);
}
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index f757824561..c4a742c037 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -667,7 +667,7 @@ static bool lcl_RecalcSplitLine( SwRowFrame& rLastLine, SwRowFrame& rFollowLine,
{
SwContentFrame const*const pAnchor = pFootnote->GetRef();
SwTabFrame const* pTab = pAnchor->FindTabFrame();
- if (pTab == &rTab)
+ if (pTab)
{
while (pTab->GetUpper()->IsInTab())
{
@@ -1454,6 +1454,8 @@ namespace
auto IsAllHiddenSection(SwSectionFrame const& rSection) -> bool
{
+ if (rSection.IsHiddenNow())
+ return true;
for (SwFrame const* pFrame = rSection.Lower(); pFrame; pFrame = pFrame->GetNext())
{
if (pFrame->IsColumnFrame())
@@ -1474,7 +1476,7 @@ namespace
}
else if (pFrame->IsTextFrame())
{
- if (!static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow())
+ if (!pFrame->IsHiddenNow())
{
return false;
}
@@ -1509,7 +1511,7 @@ namespace
}
else if (pFrame->IsTextFrame())
{
- if (!static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow())
+ if (!pFrame->IsHiddenNow())
{
return false;
}
@@ -3371,7 +3373,15 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
}
bool bFlyHoriOrientLeft = text::HoriOrientation::LEFT == rHori.GetHoriOrient();
- if (bSplitFly && !bFlyHoriOrientLeft)
+
+ bool bToplevelSplitFly = false;
+ if (bSplitFly)
+ {
+ // Floating table wrapped by table: avoid this in the nested case.
+ bToplevelSplitFly = !pFly->GetAnchorFrame()->IsInTab();
+ }
+
+ if (bToplevelSplitFly && !bFlyHoriOrientLeft)
{
// Only shift to the right if we don't have enough space on the left.
SwTwips nTabWidth = getFramePrintArea().Width();
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index a8445e90dd..89a5f03302 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -52,6 +52,7 @@
#include <ndtxt.hxx>
#include <undobj.hxx>
#include <flyfrms.hxx>
+#include <sectfrm.hxx>
#include <swselectionlist.hxx>
#include <comphelper/lok.hxx>
@@ -828,8 +829,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
//If I'm in the DocumentBody, I want to stay there.
if ( pStart->IsInDocBody() )
{
- while ( pCnt && (!pCnt->IsInDocBody() ||
- (pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow())))
+ while (pCnt && (!pCnt->IsInDocBody() || pCnt->IsHiddenNow()))
{
pCnt = (*fnNxtPrv)( pCnt );
pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
@@ -840,8 +840,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
//case of necessity.
else if ( pStart->IsInFootnote() )
{
- while ( pCnt && (!pCnt->IsInFootnote() ||
- (pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow())))
+ while (pCnt && (!pCnt->IsInFootnote() || pCnt->IsHiddenNow()))
{
pCnt = (*fnNxtPrv)( pCnt );
pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
@@ -851,7 +850,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
//In Flys we can go ahead blindly as long as we find a Content.
else if ( pStart->IsInFly() )
{
- if ( pCnt && pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow() )
+ if (pCnt && pCnt->IsHiddenNow())
{
pCnt = (*fnNxtPrv)( pCnt );
pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
@@ -875,7 +874,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
}
if ( !bSame )
pCnt = nullptr;
- else if (pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow()) // i73332
+ else if (pCnt->IsHiddenNow()) // i73332
{
pCnt = (*fnNxtPrv)( pCnt );
pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
@@ -958,8 +957,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
}
}
- } while ( !bEnd ||
- (pCnt && pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow()));
+ } while (!bEnd || (pCnt && pCnt->IsHiddenNow()));
if (pCnt == nullptr)
{
@@ -1246,7 +1244,7 @@ const SwContentFrame *SwLayoutFrame::GetContentPos( Point& rPoint,
if ( pComp != pContent )
continue;
- if ( !pContent->IsTextFrame() || !static_cast<const SwTextFrame*>(pContent)->IsHiddenNow() )
+ if (!pContent->IsHiddenNow())
{
SwRect aContentFrame( pContent->UnionFrame() );
if ( aContentFrame.Contains( rPoint ) )
@@ -1727,6 +1725,15 @@ bool SwFrame::IsProtected() const
return false;
}
+// virtual
+bool SwFrame::IsHiddenNow() const
+{
+ if (const auto* pSectFrame = FindSctFrame())
+ return pSectFrame->IsHiddenNow();
+
+ return false;
+}
+
/** @return the physical page number */
sal_uInt16 SwFrame::GetPhyPageNum() const
{
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 302302a9a2..52a51ff1a5 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -1485,6 +1485,9 @@ bool SwTextFrame::IsHiddenNow() const
return true;
}
+ if (SwContentFrame::IsHiddenNow())
+ return true;
+
bool bHiddenCharsHidePara(false);
bool bHiddenParaField(false);
if (m_pMergedPara)
@@ -1554,22 +1557,14 @@ bool SwTextFrame::IsHiddenNow() const
// be visible - check this for the 1st body paragraph
if (IsInDocBody() && FindPrevCnt() == nullptr)
{
- bool isAllHidden(true);
for (SwContentFrame const* pNext = FindNextCnt(true);
pNext != nullptr; pNext = pNext->FindNextCnt(true))
{
- if (!pNext->IsTextFrame()
- || !static_cast<SwTextFrame const*>(pNext)->IsHiddenNow())
- {
- isAllHidden = false;
- break;
- }
- }
- if (isAllHidden)
- {
- SAL_INFO("sw.core", "unhiding one body paragraph");
- return false;
+ if (!pNext->IsHiddenNow())
+ return true;
}
+ SAL_INFO("sw.core", "unhiding one body paragraph");
+ return false;
}
return true;
}
diff --git a/sw/source/core/tox/tox.cxx b/sw/source/core/tox/tox.cxx
index 04f43e5d41..b29bafde11 100644
--- a/sw/source/core/tox/tox.cxx
+++ b/sw/source/core/tox/tox.cxx
@@ -148,7 +148,13 @@ void SwTOXMark::RegisterToTOXType(SwTOXType& rType)
bool SwTOXMark::operator==( const SfxPoolItem& rAttr ) const
{
assert(SfxPoolItem::operator==(rAttr));
- return m_pType == static_cast<const SwTOXMark&>(rAttr).m_pType;
+ // tdf#158783 this item was never 'pooled', so operator== was not really
+ // ever used. We discussed to implement it (there is quite some
+ // content), but we came to the point that it's only safe to say
+ // instances are equal when same instance -> fallback to ptr compare.
+ // NOTE: Do *not* use areSfxPoolItemPtrsEqual here, with DBG_UTIL
+ // active the contol/test code there would again call operator==
+ return this == &rAttr;
}
SwTOXMark* SwTOXMark::Clone( SfxItemPool* ) const
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index 70a724814c..30f6d6e619 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -225,7 +225,7 @@ void GetSelectableFromAny(uno::Reference<uno::XInterface> const& xIfc,
return;
}
- uno::Reference<text::XTextRange> const xTextRange(xTunnel, UNO_QUERY);
+ uno::Reference<text::XTextRange> const xTextRange(xIfc, UNO_QUERY);
if (xTextRange.is())
{
SwUnoInternalPaM aPam(rTargetDoc);
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index 12db464a87..f9e16b1f42 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -307,6 +307,7 @@ std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetAutoCharS
{ UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_TOP_COLOR },
{ UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_BOTTOM_COLOR },
{ UNO_NAME_CHAR_SHADOW_FORMAT, RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_CHAR_STYLE_NAME, RES_TXTATR_CHARFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0 },
};
return aAutoCharStyleMap;
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
index b2f83fee30..49562c1d02 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -539,11 +539,6 @@ SwUnoCursorHelper::SetCursorPropertyValue(
rMap.getByName(prop.Name);
if (!pEntry)
{
- if (prop.Name == "CharStyleName")
- {
- lcl_setCharStyle(rPam.GetDoc(), prop.Value, items);
- continue;
- }
throw beans::UnknownPropertyException(
"Unknown property: " + prop.Name);
}
@@ -552,7 +547,14 @@ SwUnoCursorHelper::SetCursorPropertyValue(
throw beans::PropertyVetoException(
"Property is read-only: " + prop.Name);
}
- rPropSet.setPropertyValue(*pEntry, prop.Value, items);
+ if (prop.Name == "CharStyleName")
+ {
+ lcl_setCharStyle(rPam.GetDoc(), prop.Value, items);
+ }
+ else
+ {
+ rPropSet.setPropertyValue(*pEntry, prop.Value, items);
+ }
}
IStyleAccess& rStyleAccess = rPam.GetDoc().GetIStyleAccess();
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 186b5c5b23..494cec7468 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -84,7 +84,17 @@ static void lcl_CreatePortions(
namespace
{
enum class BkmType {
- Start, End, StartEnd
+ // The order is important: BookmarkCompareStruct::operator () depends on it.
+ // When different bookmarks' starts/ends appear at one position, by default (when there's no
+ // frames at the position - see lcl_ExportBookmark), first previous bookmarks close, then
+ // collapsed ones appear, then new bookmarks open.
+ End, StartEnd, Start
+ };
+
+ enum class ExportBookmarkPass
+ {
+ before_frames,
+ after_frames,
};
struct SwXBookmarkPortion_Impl
@@ -124,7 +134,8 @@ namespace
// start of the 2nd bookmark BEFORE the end of the first bookmark
// See bug #i58438# for more details. The below code is correct and
// fixes both #i58438 and #i16896#
- return r1->aPosition < r2->aPosition;
+ return std::make_pair(r1->aPosition, r1->nBkmType)
+ < std::make_pair(r2->aPosition, r2->nBkmType);
}
};
typedef std::multiset < SwXBookmarkPortion_ImplSharedPtr, BookmarkCompareStruct > SwXBookmarkPortion_ImplList;
@@ -132,13 +143,15 @@ namespace
/// Inserts pBkmk to rBkmArr in case it starts or ends at rOwnNode
void lcl_FillBookmark(sw::mark::IMark* const pBkmk, const SwNode& rOwnNode, SwDoc& rDoc, SwXBookmarkPortion_ImplList& rBkmArr)
{
- bool const hasOther = pBkmk->IsExpanded();
+ bool const isExpanded = pBkmk->IsExpanded();
const SwPosition& rStartPos = pBkmk->GetMarkStart();
const SwPosition& rEndPos = pBkmk->GetMarkEnd();
+ // A bookmark where the text was deleted becomes collapsed
+ bool const hasOther = isExpanded && rStartPos != rEndPos;
bool const bStartPosInNode = rStartPos.GetNode() == rOwnNode;
bool const bEndPosInNode = rEndPos.GetNode() == rOwnNode;
sw::mark::CrossRefBookmark* const pCrossRefMark
- = !hasOther && (bStartPosInNode || bEndPosInNode)
+ = !isExpanded && bStartPosInNode
? dynamic_cast<sw::mark::CrossRefBookmark*>(pBkmk)
: nullptr;
@@ -560,15 +573,23 @@ lcl_CreateContentControlPortion(const css::uno::Reference<SwXText>& xParent,
* Exports all bookmarks from rBkmArr into rPortions that have the same start
* or end position as nIndex.
*
- * @param rBkmArr the array of bookmarks. If bOnlyFrameStarts is true, then
- * this is only read, otherwise consumed entries are removed.
+ * @param rBkmArr the array of bookmarks.
*
* @param rFramePositions the list of positions where there is an at-char /
* anchored frame.
+ * Collapsed (BkmType::StartEnd) bookmarks, as well as bookmarks that start/end
+ * at the frame anchor position, are considered as wrapping the frames, if any
+ * (i.e., starts are output before the frames; ends are output after frames).
+ * When there's no frame here, bookmarks are expected to not overlap (#i58438):
+ * first, non-collapsed bookmarks' ends are output; then collapsed bookmarks;
+ * then non-collapsed bookmarks' starts.
*
- * @param bOnlyFrameStarts If true: export only the start of the bookmarks
- * which cover an at-char anchored frame. If false: export the end of the same
- * bookmarks and everything else.
+ * @param stage Case before_frames: if there is a frame at this index, output
+ * starts of both collapsed and non-collapsed bookmarks (remove non-collapsed
+ * starts from rBkmArr, convert collapsed ones to ends); if there's no frame,
+ * doesn't output anything.
+ * Case after_frames: outputs (and removes from rBkmArr) everything (left) at
+ * this index, in the order of occurrence in rBkmArr (see #i58438).
*/
static void lcl_ExportBookmark(
TextRangeList_t & rPortions,
@@ -577,54 +598,56 @@ static void lcl_ExportBookmark(
SwXBookmarkPortion_ImplList& rBkmArr,
const sal_Int32 nIndex,
const o3tl::sorted_vector<sal_Int32>& rFramePositions,
- bool bOnlyFrameStarts)
+ ExportBookmarkPass stage)
{
for ( SwXBookmarkPortion_ImplList::iterator aIter = rBkmArr.begin(), aEnd = rBkmArr.end(); aIter != aEnd; )
{
const SwXBookmarkPortion_ImplSharedPtr& pPtr = *aIter;
if ( nIndex > pPtr->getIndex() )
{
- if (bOnlyFrameStarts)
- ++aIter;
- else
- aIter = rBkmArr.erase(aIter);
+ assert(!"Some bookmarks were not consumed earlier");
continue;
}
if ( nIndex < pPtr->getIndex() )
break;
- if ((BkmType::Start == pPtr->nBkmType && bOnlyFrameStarts) ||
- (BkmType::StartEnd == pPtr->nBkmType))
+ if (stage == ExportBookmarkPass::before_frames)
{
- bool bFrameStart = rFramePositions.find(nIndex) != rFramePositions.end();
- bool bEnd = pPtr->nBkmType == BkmType::StartEnd && bFrameStart && !bOnlyFrameStarts;
- if (pPtr->nBkmType == BkmType::Start || bFrameStart || !bOnlyFrameStarts)
+ if (rFramePositions.find(nIndex) == rFramePositions.end()) // No frames at this index
+ break; // Do nothing; everything will be output at after_frames pass
+
+ if (pPtr->nBkmType == BkmType::End)
{
- // At this we create a text portion, due to one of these
- // reasons:
- // - this is the real start of a non-collapsed bookmark
- // - this is the real position of a collapsed bookmark
- // - this is the start or end (depending on bOnlyFrameStarts)
- // of a collapsed bookmark at the same position as an at-char
- // anchored frame
- rtl::Reference<SwXTextPortion> pPortion =
- new SwXTextPortion(pUnoCursor, xParent, bEnd ? PORTION_BOOKMARK_END : PORTION_BOOKMARK_START);
- rPortions.emplace_back(pPortion);
- pPortion->SetBookmark(pPtr->xBookmark);
- pPortion->SetCollapsed( BkmType::StartEnd == pPtr->nBkmType && !bFrameStart );
+ ++aIter;
+ continue; // Only consider BkmType::Start and BkmType::StartEnd in this pass
}
}
- else if (BkmType::End == pPtr->nBkmType && !bOnlyFrameStarts)
- {
- rtl::Reference<SwXTextPortion> pPortion =
- new SwXTextPortion(pUnoCursor, xParent, PORTION_BOOKMARK_END);
- rPortions.emplace_back(pPortion);
- pPortion->SetBookmark(pPtr->xBookmark);
- }
+
+ // At this we create a text portion, due to one of these
+ // reasons:
+ // - this is the real start of a non-collapsed bookmark
+ // - this is the real end of a non-collapsed bookmark
+ // - this is the real position of a collapsed bookmark
+ // - this is the start or end of a collapsed bookmark at the same position as an at-char
+ // anchored frame
+ const SwTextPortionType portionType
+ = pPtr->nBkmType == BkmType::End ? PORTION_BOOKMARK_END : PORTION_BOOKMARK_START;
+ const bool collapsed
+ = pPtr->nBkmType == BkmType::StartEnd && stage == ExportBookmarkPass::after_frames;
+
+ rtl::Reference<SwXTextPortion> pPortion = new SwXTextPortion(pUnoCursor, xParent, portionType);
+ rPortions.emplace_back(pPortion);
+ pPortion->SetBookmark(pPtr->xBookmark);
+ pPortion->SetCollapsed(collapsed);
// next bookmark
- if (bOnlyFrameStarts)
+ if (pPtr->nBkmType == BkmType::StartEnd && stage == ExportBookmarkPass::before_frames)
+ {
+ // This is a collapsed bookmark around a frame, and its start portion was just emitted;
+ // turn it into an end bookmark to process after_frames
+ pPtr->nBkmType = BkmType::End;
++aIter;
+ }
else
aIter = rBkmArr.erase(aIter);
}
@@ -1168,13 +1191,12 @@ static void lcl_ExportBkmAndRedline(
SwSoftPageBreakList& rBreakArr,
const sal_Int32 nIndex,
const o3tl::sorted_vector<sal_Int32>& rFramePositions,
- bool bOnlyFrameBookmarkStarts)
+ ExportBookmarkPass stage)
{
if (!rBkmArr.empty())
- lcl_ExportBookmark(rPortions, xParent, pUnoCursor, rBkmArr, nIndex, rFramePositions,
- bOnlyFrameBookmarkStarts);
+ lcl_ExportBookmark(rPortions, xParent, pUnoCursor, rBkmArr, nIndex, rFramePositions, stage);
- if (bOnlyFrameBookmarkStarts)
+ if (stage == ExportBookmarkPass::before_frames)
// Only exporting the start of some collapsed bookmarks: no export of
// other arrays.
return;
@@ -1401,7 +1423,7 @@ static void lcl_CreatePortions(
// Then export start of collapsed bookmarks which "cover" at-char
// anchored frames.
lcl_ExportBkmAndRedline( *PortionStack.top().first, i_xParentText,
- pUnoCursor, Bookmarks, Redlines, SoftPageBreaks, nCurrentIndex, aFramePositions, /*bOnlyFrameBookmarkStarts=*/true );
+ pUnoCursor, Bookmarks, Redlines, SoftPageBreaks, nCurrentIndex, aFramePositions, ExportBookmarkPass::before_frames );
lcl_ExportAnnotationStarts(
*PortionStack.top().first,
@@ -1419,7 +1441,7 @@ static void lcl_CreatePortions(
// Export ends of the previously started collapsed bookmarks + all
// other bookmarks, redlines, etc.
lcl_ExportBkmAndRedline( *PortionStack.top().first, i_xParentText,
- pUnoCursor, Bookmarks, Redlines, SoftPageBreaks, nCurrentIndex, aFramePositions, /*bOnlyFrameBookmarkStarts=*/false );
+ pUnoCursor, Bookmarks, Redlines, SoftPageBreaks, nCurrentIndex, aFramePositions, ExportBookmarkPass::after_frames );
lcl_ExportAnnotationStarts(
*PortionStack.top().first,
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index f959d6a610..93603d6d40 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1634,6 +1634,9 @@ SwXText::convertToTextFrame(
// see testFlyInFly for why this checks only the edges of the selection,
// and testFloatingTablesAnchor for why it excludes pre/post table
// added nodes
+ // TODO: isGraphicNode here looks dubious; see also tdf#47036 fix;
+ // this needs more investigation when exactly Word considers something
+ // anchored in text frame vs. anchored in body.
if (!isGraphicNode(pFrameFormat)
&& (IsAtParaMatch(*oAnchorCheckPam, rAnchor)
|| (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()
diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx
index 30ba8d3c0a..2587edfaf2 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -3301,14 +3301,16 @@ SwHTMLWriter& OutCSS1_SvxBox( SwHTMLWriter& rWrt, const SfxPoolItem& rHt )
if( rHt.Which() == RES_CHRATR_BOX )
{
+ constexpr std::string_view inline_block("inline-block");
if( rWrt.m_bTagOn )
{
// Inline-block to make the line height changing correspond to the character border
- rWrt.OutCSS1_PropertyAscii(sCSS1_P_display, "inline-block");
+ rWrt.OutCSS1_PropertyAscii(sCSS1_P_display, inline_block);
}
else
{
- HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span), false );
+ if (!IgnorePropertyForReqIF(rWrt.mbReqIF, sCSS1_P_display, inline_block))
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span), false );
return rWrt;
}
}
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index 9f67d1ee03..c880082018 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -1058,7 +1058,7 @@ public:
HTMLStartEndPos( const SfxPoolItem& rItem, sal_Int32 nStt, sal_Int32 nE );
- const SfxPoolItem* GetItem() const { return m_pItem.get(); }
+ const SfxPoolItem& GetItem() const { return *m_pItem; }
void SetStart(sal_Int32 nStt) { m_nStart = nStt; }
sal_Int32 GetStart() const { return m_nStart; }
@@ -1075,7 +1075,7 @@ HTMLStartEndPos::HTMLStartEndPos(const SfxPoolItem& rItem, sal_Int32 nStt, sal_I
, m_pItem(rItem.Clone())
{}
-typedef std::vector<HTMLStartEndPos *> HTMLStartEndPositions;
+typedef std::map<sal_Int32, std::vector<HTMLStartEndPos*>> HTMLStartEndPositions;
namespace {
@@ -1091,8 +1091,8 @@ enum HTMLOnOffState { HTML_NOT_SUPPORTED, // unsupported Attribute
class HTMLEndPosLst
{
- HTMLStartEndPositions m_aStartLst; // list, sorted for start positions
- HTMLStartEndPositions m_aEndLst; // list, sorted for end positions
+ HTMLStartEndPositions m_aStartLst; // list, each position's elements sorted by appearance order
+ HTMLStartEndPositions m_aEndLst; // list, no sort of elements in position
std::deque<sal_Int32> m_aScriptChgLst; // positions where script changes
// 0 is not contained in this list,
// but the text length
@@ -1110,8 +1110,7 @@ class HTMLEndPosLst
// Insert/remove a SttEndPos in/from the Start and End lists.
// The end position is known.
- void InsertItem_( HTMLStartEndPos *pPos, HTMLStartEndPositions::size_type nEndPos );
- void RemoveItem_( HTMLStartEndPositions::size_type nEndPos );
+ void InsertItem_(HTMLStartEndPos* pPos);
// determine the 'type' of the attribute
HTMLOnOffState GetHTMLItemState( const SfxPoolItem& rItem );
@@ -1125,8 +1124,7 @@ class HTMLEndPosLst
sal_Int32 nEndPos );
// adapt the end of a split item
- void FixSplittedItem( HTMLStartEndPos *pPos, sal_Int32 nNewEnd,
- HTMLStartEndPositions::size_type nStartPos );
+ void FixSplittedItem(HTMLStartEndPos* pPos, sal_Int32 nNewEnd);
// insert an attribute in the lists and, if necessary, split it
void InsertItem( const SfxPoolItem& rItem, sal_Int32 nStart,
@@ -1144,6 +1142,8 @@ class HTMLEndPosLst
const SwHTMLFormatInfo *GetFormatInfo( const SwFormat& rFormat,
SwHTMLFormatInfos& rFormatInfos );
+ void OutEndAttrs(SwHTMLWriter& rWrt, std::vector<HTMLStartEndPos*>& posItems);
+
public:
HTMLEndPosLst( SwDoc *pDoc, SwDoc* pTemplate, std::optional<Color> xDfltColor,
@@ -1169,36 +1169,46 @@ public:
bool IsHTMLMode(sal_uLong nMode) const { return (m_nHTMLMode & nMode) != 0; }
};
-}
-
-void HTMLEndPosLst::InsertItem_( HTMLStartEndPos *pPos, HTMLStartEndPositions::size_type nEndPos )
+struct SortEnds
{
- // Insert the attribute in the Start list behind all attributes that
- // were started before, or at the same position.
- sal_Int32 nStart = pPos->GetStart();
- HTMLStartEndPositions::size_type i {0};
+ HTMLStartEndPositions& m_startList;
+ SortEnds(HTMLStartEndPositions& startList) : m_startList(startList) {}
+ bool operator()(const HTMLStartEndPos* p1, const HTMLStartEndPos* p2)
+ {
+ // if p1 start after p2, then it ends before
+ if (p1->GetStart() > p2->GetStart())
+ return true;
+ if (p1->GetStart() < p2->GetStart())
+ return false;
+ for (const auto p : m_startList[p1->GetStart()])
+ {
+ if (p == p1)
+ return false;
+ if (p == p2)
+ return true;
+ }
+ assert(!"Neither p1 nor p2 found in their start list");
+ return false;
+ }
+};
- while (i < m_aStartLst.size() && m_aStartLst[i]->GetStart() <= nStart)
- ++i;
- m_aStartLst.insert(m_aStartLst.begin() + i, pPos);
+#ifndef NDEBUG
+bool IsEmpty(const HTMLStartEndPositions& l)
+{
+ return std::find_if(l.begin(), l.end(), [](auto& i) { return !i.second.empty(); }) == l.end();
+}
+#endif
- // the position in the End list was supplied
- m_aEndLst.insert(m_aEndLst.begin() + nEndPos, pPos);
}
-void HTMLEndPosLst::RemoveItem_( HTMLStartEndPositions::size_type nEndPos )
+void HTMLEndPosLst::InsertItem_(HTMLStartEndPos* pPos)
{
- HTMLStartEndPos* pPos = m_aEndLst[nEndPos];
+ // Character border attribute must be the first which is written out because of border merge.
+ auto& posItems1 = m_aStartLst[pPos->GetStart()];
+ auto it = pPos->GetItem().Which() == RES_CHRATR_BOX ? posItems1.begin() : posItems1.end();
+ posItems1.insert(it, pPos);
- // now, we are looking for it in the Start list
- HTMLStartEndPositions::iterator it = std::find(m_aStartLst.begin(), m_aStartLst.end(), pPos);
- OSL_ENSURE(it != m_aStartLst.end(), "Item not found in Start List!");
- if (it != m_aStartLst.end())
- m_aStartLst.erase(it);
-
- m_aEndLst.erase(m_aEndLst.begin() + nEndPos);
-
- delete pPos;
+ m_aEndLst[pPos->GetEnd()].push_back(pPos);
}
HTMLOnOffState HTMLEndPosLst::GetHTMLItemState( const SfxPoolItem& rItem )
@@ -1352,23 +1362,25 @@ HTMLOnOffState HTMLEndPosLst::GetHTMLItemState( const SfxPoolItem& rItem )
bool HTMLEndPosLst::ExistsOnTagItem( sal_uInt16 nWhich, sal_Int32 nPos )
{
- for (auto pTest : m_aStartLst)
+ for (const auto& [startPos, items] : m_aStartLst)
{
- if( pTest->GetStart() > nPos )
+ if (startPos > nPos)
{
// this attribute, and all attributes that follow, start later
break;
}
- else if( pTest->GetEnd() > nPos )
+
+ for (const auto* pTest : items)
{
- // the attribute starts before, or at, the current position and
- // ends after it
- const SfxPoolItem *pItem = pTest->GetItem();
- if( pItem->Which() == nWhich &&
- HTML_ON_VALUE == GetHTMLItemState(*pItem) )
+ if (pTest->GetEnd() > nPos)
{
- // an OnTag attribute was found
- return true;
+ // the attribute starts before, or at, the current position and ends after it
+ const SfxPoolItem& rItem = pTest->GetItem();
+ if (rItem.Which() == nWhich && HTML_ON_VALUE == GetHTMLItemState(rItem))
+ {
+ // an OnTag attribute was found
+ return true;
+ }
}
}
}
@@ -1386,24 +1398,17 @@ bool HTMLEndPosLst::ExistsOffTagItem( sal_uInt16 nWhich, sal_Int32 nStartPos,
return false;
}
- for (auto pTest : m_aStartLst)
+ for (const auto* pTest : m_aStartLst[nStartPos])
{
- if( pTest->GetStart() > nStartPos )
- {
- // this attribute, and all attributes that follow, start later
- break;
- }
- else if( pTest->GetStart()==nStartPos &&
- pTest->GetEnd()==nEndPos )
+ if (pTest->GetEnd() == nEndPos)
{
- // the attribute starts before or at the current position and
- // ends after it
- const SfxPoolItem *pItem = pTest->GetItem();
- sal_uInt16 nTstWhich = pItem->Which();
+ // the attribute starts before or at the current position and ends after it
+ const SfxPoolItem& rItem = pTest->GetItem();
+ sal_uInt16 nTstWhich = rItem.Which();
if( (nTstWhich == RES_CHRATR_CROSSEDOUT ||
nTstWhich == RES_CHRATR_UNDERLINE ||
nTstWhich == RES_CHRATR_BLINK) &&
- HTML_OFF_VALUE == GetHTMLItemState(*pItem) )
+ HTML_OFF_VALUE == GetHTMLItemState(rItem) )
{
// an OffTag attribute was found that is exported the same
// way as the current item
@@ -1415,55 +1420,51 @@ bool HTMLEndPosLst::ExistsOffTagItem( sal_uInt16 nWhich, sal_Int32 nStartPos,
return false;
}
-void HTMLEndPosLst::FixSplittedItem( HTMLStartEndPos *pPos, sal_Int32 nNewEnd,
- HTMLStartEndPositions::size_type nStartPos )
+void HTMLEndPosLst::FixSplittedItem(HTMLStartEndPos* pPos, sal_Int32 nNewEnd)
{
+ // remove the item from the End list
+ std::erase(m_aEndLst[pPos->GetEnd()], pPos);
// fix the end position accordingly
pPos->SetEnd( nNewEnd );
-
- // remove the item from the End list
- HTMLStartEndPositions::iterator it = std::find(m_aEndLst.begin(), m_aEndLst.end(), pPos);
- OSL_ENSURE(it != m_aEndLst.end(), "Item not found in End List!");
- if (it != m_aEndLst.end())
- m_aEndLst.erase(it);
-
- // from now on, it is closed as the last one at the corresponding position
- HTMLStartEndPositions::size_type nEndPos {0};
- while (nEndPos < m_aEndLst.size() && m_aEndLst[nEndPos]->GetEnd() <= nNewEnd)
- ++nEndPos;
- m_aEndLst.insert(m_aEndLst.begin() + nEndPos, pPos);
+ // from now on, it is closed at the corresponding position
+ m_aEndLst[nNewEnd].push_back(pPos);
// now, adjust the attributes that got started afterwards
- for (HTMLStartEndPositions::size_type i = nStartPos + 1; i < m_aStartLst.size(); ++i)
+ const sal_Int32 nPos = pPos->GetStart();
+ for (const auto& [startPos, items] : m_aStartLst)
{
- HTMLStartEndPos* pTest = m_aStartLst[i];
- sal_Int32 nTestEnd = pTest->GetEnd();
- if( pTest->GetStart() >= nNewEnd )
- {
- // the Test attribute and all the following ones start, after the
- // split attribute ends
+ if (startPos < nPos)
+ continue;
+
+ if (startPos >= nNewEnd)
break;
+
+ auto it = items.begin();
+ if (startPos == nPos)
+ {
+ it = std::find(items.begin(), items.end(), pPos);
+ if (it != items.end())
+ ++it;
}
- else if( nTestEnd > nNewEnd )
+ for (; it != items.end(); ++it)
{
+ HTMLStartEndPos* pTest = *it;
+ const sal_Int32 nTestEnd = pTest->GetEnd();
+ if (nTestEnd <= nNewEnd)
+ continue;
+
// the Test attribute starts before the split attribute
// ends, and ends afterwards, i.e., it must be split, as well
+ // remove the attribute from the End list
+ std::erase(m_aEndLst[pTest->GetEnd()], pTest);
// set the new end
pTest->SetEnd( nNewEnd );
-
- // remove the attribute from the End list
- it = std::find(m_aEndLst.begin(), m_aEndLst.end(), pTest);
- OSL_ENSURE(it != m_aEndLst.end(), "Item not found in End List!");
- if (it != m_aEndLst.end())
- m_aEndLst.erase(it);
-
- // it now ends as the first attribute in the respective position.
- // We already know this position in the End list.
- m_aEndLst.insert(m_aEndLst.begin() + nEndPos, pTest);
+ // it now ends in the respective position.
+ m_aEndLst[nNewEnd].push_back(pTest);
// insert the 'rest' of the attribute
- InsertItem( *pTest->GetItem(), nNewEnd, nTestEnd );
+ InsertItem( pTest->GetItem(), nNewEnd, nTestEnd );
}
}
}
@@ -1471,36 +1472,38 @@ void HTMLEndPosLst::FixSplittedItem( HTMLStartEndPos *pPos, sal_Int32 nNewEnd,
void HTMLEndPosLst::InsertItem( const SfxPoolItem& rItem, sal_Int32 nStart,
sal_Int32 nEnd )
{
- HTMLStartEndPositions::size_type i;
- for (i = 0; i < m_aEndLst.size(); i++)
+ assert(nStart < nEnd);
+
+ for (auto& [endPos, items] : m_aEndLst)
{
- HTMLStartEndPos* pTest = m_aEndLst[i];
- sal_Int32 nTestEnd = pTest->GetEnd();
- if( nTestEnd <= nStart )
+ if (endPos <= nStart)
{
// the Test attribute ends, before the new one starts
continue;
}
- else if( nTestEnd < nEnd )
+ if (endPos >= nEnd)
+ {
+ // the Test attribute (and all that follow) ends, before the new
+ // one ends
+ break;
+ }
+
+ std::sort(items.begin(), items.end(), SortEnds(m_aStartLst));
+
+ for (HTMLStartEndPos* pTest : items)
{
if( pTest->GetStart() < nStart )
{
// the Test attribute ends, before the new one ends. Thus, the
// new attribute must be split.
- InsertItem_( new HTMLStartEndPos( rItem, nStart, nTestEnd ), i );
- nStart = nTestEnd;
+ InsertItem_(new HTMLStartEndPos(rItem, nStart, endPos));
+ nStart = endPos;
}
}
- else
- {
- // the Test attribute (and all that follow) ends, before the new
- // one ends
- break;
- }
}
// one attribute must still be inserted
- InsertItem_( new HTMLStartEndPos( rItem, nStart, nEnd ), i );
+ InsertItem_(new HTMLStartEndPos(rItem, nStart, nEnd));
}
void HTMLEndPosLst::SplitItem( const SfxPoolItem& rItem, sal_Int32 nStart,
@@ -1511,59 +1514,47 @@ void HTMLEndPosLst::SplitItem( const SfxPoolItem& rItem, sal_Int32 nStart,
// first, we must search for the old items by using the start list and
// determine the new item range
- for (HTMLStartEndPositions::size_type i = 0; i < m_aStartLst.size(); ++i)
+ for (auto& [nTestStart, items] : m_aStartLst)
{
- HTMLStartEndPos* pTest = m_aStartLst[i];
- sal_Int32 nTestStart = pTest->GetStart();
- sal_Int32 nTestEnd = pTest->GetEnd();
-
if( nTestStart >= nEnd )
{
// this attribute, and all that follow, start later
break;
}
- else if( nTestEnd > nStart )
+
+ for (auto it = items.begin(); it != items.end();)
{
+ HTMLStartEndPos* pTest = *it;
+ sal_Int32 nTestEnd = pTest->GetEnd();
+ if (nTestEnd <= nStart)
+ continue;
+
// the Test attribute ends in the range that must be deleted
- const SfxPoolItem *pItem = pTest->GetItem();
+ const SfxPoolItem& rTestItem = pTest->GetItem();
// only the corresponding OnTag attributes have to be considered
- if( pItem->Which() == nWhich &&
- HTML_ON_VALUE == GetHTMLItemState( *pItem ) )
+ if (rTestItem.Which() == nWhich && HTML_ON_VALUE == GetHTMLItemState(rTestItem))
{
- bool bDelete = true;
+ // if necessary, insert the second part of the split
+ // attribute
+ if (nTestEnd > nEnd)
+ InsertItem(pTest->GetItem(), nEnd, nTestEnd);
- if( nTestStart < nStart )
- {
- // the start of the new attribute corresponds to the new
- // end of the attribute
- FixSplittedItem( pTest, nStart, i );
- bDelete = false;
- }
- else
+ if (nTestStart >= nStart)
{
// the Test item only starts after the new end of the
// attribute. Therefore, it can be completely erased.
- m_aStartLst.erase(m_aStartLst.begin() + i);
- i--;
-
- HTMLStartEndPositions::iterator it
- = std::find(m_aEndLst.begin(), m_aEndLst.end(), pTest);
- OSL_ENSURE(it != m_aEndLst.end(), "Item not found in End List!");
- if (it != m_aEndLst.end())
- m_aEndLst.erase(it);
- }
-
- // if necessary, insert the second part of the split
- // attribute
- if( nTestEnd > nEnd )
- {
- InsertItem( *pTest->GetItem(), nEnd, nTestEnd );
+ it = items.erase(it);
+ std::erase(m_aEndLst[pTest->GetEnd()], pTest);
+ delete pTest;
+ continue;
}
- if( bDelete )
- delete pTest;
+ // the start of the new attribute corresponds to the new
+ // end of the attribute
+ FixSplittedItem(pTest, nStart);
}
+ ++it;
}
}
}
@@ -1611,8 +1602,8 @@ HTMLEndPosLst::HTMLEndPosLst(SwDoc* pD, SwDoc* pTempl, std::optional<Color> xDfl
HTMLEndPosLst::~HTMLEndPosLst()
{
- OSL_ENSURE(m_aStartLst.empty(), "Start List not empty in destructor");
- OSL_ENSURE(m_aEndLst.empty(), "End List not empty in destructor");
+ assert(IsEmpty(m_aStartLst) && "Start List not empty in destructor");
+ assert(IsEmpty(m_aEndLst) && "End List not empty in destructor");
}
void HTMLEndPosLst::InsertNoScript( const SfxPoolItem& rItem,
@@ -1900,53 +1891,25 @@ void HTMLEndPosLst::OutStartAttrs( SwHTMLWriter& rWrt, sal_Int32 nPos )
{
rWrt.m_bTagOn = true;
- // Character border attribute must be the first which is written out
- // because of border merge.
- HTMLStartEndPositions::size_type nCharBoxIndex = 0;
- while (nCharBoxIndex < m_aStartLst.size()
- && m_aStartLst[nCharBoxIndex]->GetItem()->Which() != RES_CHRATR_BOX)
- {
- ++nCharBoxIndex;
- }
-
+ auto it = m_aStartLst.find(nPos);
+ if (it == m_aStartLst.end())
+ return;
// the attributes of the start list are sorted in ascending order
- for (HTMLStartEndPositions::size_type i = 0; i < m_aStartLst.size(); ++i)
+ for (HTMLStartEndPos* pPos : it->second)
{
- HTMLStartEndPos *pPos = nullptr;
- if (nCharBoxIndex < m_aStartLst.size())
- {
- if( i == 0 )
- pPos = m_aStartLst[nCharBoxIndex];
- else if( i == nCharBoxIndex )
- pPos = m_aStartLst[0];
- else
- pPos = m_aStartLst[i];
- }
- else
- pPos = m_aStartLst[i];
-
- sal_Int32 nStart = pPos->GetStart();
- if( nStart > nPos )
- {
- // this attribute, and all that follow, will be opened later on
- break;
- }
- else if( nStart == nPos )
+ // output the attribute
+ sal_uInt16 nCSS1Script = rWrt.m_nCSS1Script;
+ sal_uInt16 nWhich = pPos->GetItem().Which();
+ if( RES_TXTATR_CHARFMT == nWhich ||
+ RES_TXTATR_INETFMT == nWhich ||
+ RES_PARATR_DROP == nWhich )
{
- // output the attribute
- sal_uInt16 nCSS1Script = rWrt.m_nCSS1Script;
- sal_uInt16 nWhich = pPos->GetItem()->Which();
- if( RES_TXTATR_CHARFMT == nWhich ||
- RES_TXTATR_INETFMT == nWhich ||
- RES_PARATR_DROP == nWhich )
- {
- rWrt.m_nCSS1Script = GetScriptAtPos( nPos, nCSS1Script );
- }
- HTMLOutFuncs::FlushToAscii( rWrt.Strm() ); // was one time only - do we still need it?
- Out( aHTMLAttrFnTab, *pPos->GetItem(), rWrt );
- rWrt.maStartedAttributes[pPos->GetItem()->Which()]++;
- rWrt.m_nCSS1Script = nCSS1Script;
+ rWrt.m_nCSS1Script = GetScriptAtPos( nPos, nCSS1Script );
}
+ HTMLOutFuncs::FlushToAscii( rWrt.Strm() ); // was one time only - do we still need it?
+ Out( aHTMLAttrFnTab, pPos->GetItem(), rWrt );
+ rWrt.maStartedAttributes[pPos->GetItem().Which()]++;
+ rWrt.m_nCSS1Script = nCSS1Script;
}
}
@@ -1954,59 +1917,55 @@ void HTMLEndPosLst::OutEndAttrs( SwHTMLWriter& rWrt, sal_Int32 nPos )
{
rWrt.m_bTagOn = false;
- // the attributes in the End list are sorted in ascending order
- HTMLStartEndPositions::size_type i {0};
- while (i < m_aEndLst.size())
+ if (nPos == SAL_MAX_INT32)
+ {
+ for (auto& element : m_aEndLst)
+ OutEndAttrs(rWrt, element.second);
+ }
+ else
{
- HTMLStartEndPos* pPos = m_aEndLst[i];
- sal_Int32 nEnd = pPos->GetEnd();
+ auto it = m_aEndLst.find(nPos);
+ if (it != m_aEndLst.end())
+ OutEndAttrs(rWrt, it->second);
+ }
+}
- if( SAL_MAX_INT32 == nPos || nEnd == nPos )
+void HTMLEndPosLst::OutEndAttrs(SwHTMLWriter& rWrt, std::vector<HTMLStartEndPos*>& posItems)
+{
+ std::sort(posItems.begin(), posItems.end(), SortEnds(m_aStartLst));
+ for (auto it = posItems.begin(); it != posItems.end(); it = posItems.erase(it))
+ {
+ HTMLStartEndPos* pPos = *it;
+ HTMLOutFuncs::FlushToAscii( rWrt.Strm() ); // was one time only - do we still need it?
+ // Skip closing span if next character span has the same border (border merge)
+ bool bSkipOut = false;
+ if( pPos->GetItem().Which() == RES_CHRATR_BOX )
{
- HTMLOutFuncs::FlushToAscii( rWrt.Strm() ); // was one time only - do we still need it?
- // Skip closing span if next character span has the same border (border merge)
- bool bSkipOut = false;
- if( pPos->GetItem()->Which() == RES_CHRATR_BOX )
+ auto& startPosItems = m_aStartLst[pPos->GetEnd()];
+ for (auto it2 = startPosItems.begin(); it2 != startPosItems.end(); ++it2)
{
- HTMLStartEndPositions::iterator it
- = std::find(m_aStartLst.begin(), m_aStartLst.end(), pPos);
- OSL_ENSURE(it != m_aStartLst.end(), "Item not found in Start List!");
- if (it != m_aStartLst.end())
- ++it;
- while (it != m_aStartLst.end())
+ HTMLStartEndPos* pEndPos = *it2;
+ if( pEndPos->GetItem().Which() == RES_CHRATR_BOX &&
+ static_cast<const SvxBoxItem&>(pEndPos->GetItem()) ==
+ static_cast<const SvxBoxItem&>(pPos->GetItem()) )
{
- HTMLStartEndPos *pEndPos = *it;
- if( pEndPos->GetItem()->Which() == RES_CHRATR_BOX &&
- *static_cast<const SvxBoxItem*>(pEndPos->GetItem()) ==
- *static_cast<const SvxBoxItem*>(pPos->GetItem()) )
- {
- pEndPos->SetStart(pPos->GetStart());
- bSkipOut = true;
- break;
- }
- ++it;
+ startPosItems.erase(it2);
+ pEndPos->SetStart(pPos->GetStart());
+ auto& oldStartPosItems = m_aStartLst[pEndPos->GetStart()];
+ oldStartPosItems.insert(oldStartPosItems.begin(), pEndPos);
+ bSkipOut = true;
+ break;
}
}
- if( !bSkipOut )
- {
- Out( aHTMLAttrFnTab, *pPos->GetItem(), rWrt );
- rWrt.maStartedAttributes[pPos->GetItem()->Which()]--;
- }
- RemoveItem_( i );
- }
- else if( nEnd > nPos )
- {
- // this attribute, and all that follow, are closed later on
- break;
}
- else
+ if( !bSkipOut )
{
- // The attribute is closed before the current position. This
- // is not allowed, but we can handle it anyway.
- OSL_ENSURE( nEnd >= nPos,
- "The attribute should've been closed a long time ago" );
- i++;
+ Out( aHTMLAttrFnTab, pPos->GetItem(), rWrt );
+ rWrt.maStartedAttributes[pPos->GetItem().Which()]--;
}
+
+ std::erase(m_aStartLst[pPos->GetStart()], pPos);
+ delete pPos;
}
}
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index d84549d430..28da6d2883 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -161,6 +161,8 @@
#include <frozen/bits/defines.h>
#include <frozen/bits/elsa_std.h>
#include <frozen/unordered_map.h>
+#include <IDocumentDeviceAccess.hxx>
+#include <sfx2/printer.hxx>
using ::editeng::SvxBorderLine;
@@ -1965,7 +1967,22 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, sal_In
}
// if there is some redlining in the document, output it
- StartRedline( m_pRedlineData, bLastRun );
+ bool bSkipRedline = false;
+ if (nLen == 1)
+ {
+ // Don't redline content-controls--Word doesn't do them.
+ SwTextAttr* pAttr
+ = pNode->GetTextAttrAt(nPos, RES_TXTATR_CONTENTCONTROL, sw::GetTextAttrMode::Default);
+ if (pAttr && pAttr->GetStart() == nPos)
+ {
+ bSkipRedline = true;
+ }
+ }
+
+ if (!bSkipRedline)
+ {
+ StartRedline(m_pRedlineData, bLastRun);
+ }
// XML_r node should be surrounded with bookmark-begin and bookmark-end nodes if it has bookmarks.
// The same is applied for permission ranges.
@@ -2042,6 +2059,13 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, sal_In
// append the actual run end
m_pSerializer->endElementNS( XML_w, XML_r );
+ // if there is some redlining in the document, output it
+ // (except in the case of fields with multiple runs)
+ if (!bSkipRedline)
+ {
+ EndRedline(m_pRedlineData, bLastRun);
+ }
+
if (nLen != -1)
{
sal_Int32 nEnd = nPos + nLen;
@@ -2052,10 +2076,6 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, sal_In
}
}
- // if there is some redlining in the document, output it
- // (except in the case of fields with multiple runs)
- EndRedline( m_pRedlineData, bLastRun );
-
// enclose in a sdt block, if necessary: if one is already started, then don't do it for now
// (so on export sdt blocks are never nested ATM)
if ( !m_bAnchorLinkedToNode && !m_aRunSdt.m_bStartedSdt)
@@ -9118,9 +9138,15 @@ void DocxAttributeOutput::FormatFrameSize( const SwFormatFrameSize& rSize )
}
}
-void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
+void DocxAttributeOutput::FormatPaperBin(const SvxPaperBinItem& rPaperBin)
{
- SAL_INFO("sw.ww8", "TODO DocxAttributeOutput::FormatPaperBin()" );
+ sal_Int8 nPaperBin = rPaperBin.GetValue();
+ rtl::Reference<FastAttributeList> attrList = FastSerializerHelper::createAttrList( );
+ SfxPrinter* pPrinter = m_rExport.m_rDoc.getIDocumentDeviceAccess().getPrinter(true);
+ sal_Int16 nPaperSource = pPrinter->GetSourceIndexByPaperBin(nPaperBin);
+ attrList->add( FSNS( XML_w, XML_first ), OString::number(nPaperSource) );
+ attrList->add( FSNS( XML_w, XML_other ), OString::number(nPaperSource) );
+ m_pSerializer->singleElementNS( XML_w, XML_paperSrc, attrList );
}
void DocxAttributeOutput::FormatFirstLineIndent(SvxFirstLineIndentItem const& rFirstLine)
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 2d68556e8a..7dcda8f73f 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -94,6 +94,8 @@
#include <formatflysplit.hxx>
#include <fmtwrapinfluenceonobjpos.hxx>
#include "rtfexport.hxx"
+#include <IDocumentDeviceAccess.hxx>
+#include <sfx2/printer.hxx>
using namespace ::com::sun::star;
using namespace sw::util;
@@ -3324,9 +3326,14 @@ void RtfAttributeOutput::FormatFrameSize(const SwFormatFrameSize& rSize)
}
}
-void RtfAttributeOutput::FormatPaperBin(const SvxPaperBinItem& /*rItem*/)
+void RtfAttributeOutput::FormatPaperBin(const SvxPaperBinItem& rItem)
{
- SAL_INFO("sw.rtf", "TODO: " << __func__);
+ SfxPrinter* pPrinter = m_rExport.m_rDoc.getIDocumentDeviceAccess().getPrinter(true);
+ sal_Int16 nPaperSource = pPrinter->GetSourceIndexByPaperBin(rItem.GetValue());
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_BINFSXN);
+ m_aSectionBreaks.append(static_cast<sal_Int32>(nPaperSource));
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_BINSXN);
+ m_aSectionBreaks.append(static_cast<sal_Int32>(nPaperSource));
}
void RtfAttributeOutput::FormatFirstLineIndent(SvxFirstLineIndentItem const& rFirstLine)
@@ -3747,6 +3754,12 @@ void RtfAttributeOutput::FormatFillGradient(const XFillGradientItem& rFillGradie
const Color aEndColor(rColorStops.back().getStopColor());
m_aFlyProperties.push_back(std::make_pair<OString, OString>(
"fillBackColor"_ostr, OString::number(wwUtility::RGBToBGR(aEndColor))));
+
+ if (rGradient.GetGradientStyle() == awt::GradientStyle_AXIAL)
+ {
+ m_aFlyProperties.push_back(
+ std::make_pair<OString, OString>("fillFocus"_ostr, OString::number(50)));
+ }
}
else
{
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 39e2f88523..68437c9529 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2478,6 +2478,14 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
bool bStartedPostponedRunProperties = false;
OUString aSavedSnippet ;
+ // Don't redline content-controls--Word doesn't do them.
+ SwTextAttr* pAttr = rNode.GetTextAttrAt(nCurrentPos, RES_TXTATR_CONTENTCONTROL,
+ sw::GetTextAttrMode::Default);
+ if (pAttr && pAttr->GetStart() == nCurrentPos)
+ {
+ pRedlineData = nullptr;
+ }
+
sal_Int32 nNextAttr = GetNextPos( &aAttrIter, rNode, nCurrentPos );
// Skip un-exportable attributes.
diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index 8d59434db6..681961a377 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -279,7 +279,7 @@ void WW8AttributeOutput::NumberingLevel( sal_uInt8 /*nLevel*/,
sal_Int16 nListTabPos,
const OUString &rNumberingString,
const SvxBrushItem* pBrush, //For i120928,to transfer graphic of bullet
- bool /*isLegal*/
+ bool isLegal
)
{
// Start value
@@ -303,6 +303,13 @@ void WW8AttributeOutput::NumberingLevel( sal_uInt8 /*nLevel*/,
nAlign = 0;
break;
}
+
+ if (isLegal)
+ {
+ // 3rd bit.
+ nAlign |= 0x04;
+ }
+
m_rWW8Export.m_pTableStrm->WriteUChar( nAlign );
// Write the rgbxchNums[9], positions of placeholders for paragraph
diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index d0a294b144..41b203f924 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -368,6 +368,8 @@ struct WW8LVL // only THE entries, WE need!
short nDxaLeft1; // first line indent
sal_uInt8 nNFC; // number format code
+ /// Legal numbering: whether this level overrides the nfc of all inherited level numbers.
+ bool fLegal;
// Offset of fieldcodes in Num-X-String
sal_uInt8 aOfsNumsXCH[WW8ListManager::nMaxLevel];
sal_uInt8 nLenGrpprlChpx; // length, in bytes, of the LVL's grpprlChpx
@@ -662,7 +664,15 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet
m_rSt.ReadUChar( aLVL.nNFC );
m_rSt.ReadUChar( aBits1 );
if( ERRCODE_NONE != m_rSt.GetError() ) return false;
+ // 1st..2nd bits.
aLVL.nAlign = (aBits1 & 0x03);
+
+ if (aBits1 & 0x04)
+ {
+ // 3rd bit.
+ aLVL.fLegal = true;
+ }
+
if( aBits1 & 0x10 ) aLVL.bV6Prev = true;
if( aBits1 & 0x20 ) aLVL.bV6PrSp = true;
if( aBits1 & 0x40 ) aLVL.bV6 = true;
@@ -898,6 +908,7 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet
if( bSetStartNo && 0 <= aLVL.nStartAt)
rNumFormat.SetStart(o3tl::narrowing<sal_uInt16>(aLVL.nStartAt));
rNumFormat.SetNumberingType( nType );
+ rNumFormat.SetIsLegal(aLVL.fLegal);
rNumFormat.SetNumAdjust( eAdj );
if( style::NumberingType::CHAR_SPECIAL == nType )
diff --git a/sw/source/ui/index/swuiidxmrk.cxx b/sw/source/ui/index/swuiidxmrk.cxx
index 39443f7e7b..8a6f74b86e 100644
--- a/sw/source/ui/index/swuiidxmrk.cxx
+++ b/sw/source/ui/index/swuiidxmrk.cxx
@@ -287,19 +287,20 @@ void SwIndexMarkPane::InitControls()
bool bShow = false;
pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_PRV );
- if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ // tdf#158783 ptr compare OK for SwTOXMark (more below)
+ if (!areSfxPoolItemPtrsEqual( pMoveMark, pMark ))
{
m_pSh->GotoTOXMark( *pMoveMark, TOX_NXT );
bShow = true;
}
- m_xPrevBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark));
+ m_xPrevBT->set_sensitive(!areSfxPoolItemPtrsEqual(pMoveMark, pMark));
pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_NXT );
- if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ if (!areSfxPoolItemPtrsEqual( pMoveMark, pMark ))
{
m_pSh->GotoTOXMark( *pMoveMark, TOX_PRV );
bShow = true;
}
- m_xNextBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark));
+ m_xNextBT->set_sensitive(!areSfxPoolItemPtrsEqual(pMoveMark, pMark));
if( bShow )
{
m_xPrevBT->show();
@@ -308,19 +309,19 @@ void SwIndexMarkPane::InitControls()
}
pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_PRV );
- if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ if (!areSfxPoolItemPtrsEqual( pMoveMark, pMark ))
{
m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_NXT );
bShow = true;
}
- m_xPrevSameBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark));
+ m_xPrevSameBT->set_sensitive(!areSfxPoolItemPtrsEqual(pMoveMark, pMark));
pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_NXT );
- if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ if (!areSfxPoolItemPtrsEqual( pMoveMark, pMark ))
{
m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_PRV );
bShow = true;
}
- m_xNextSameBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark));
+ m_xNextSameBT->set_sensitive(!areSfxPoolItemPtrsEqual(pMoveMark, pMark));
if( bShow )
{
m_xNextSameBT->show();
@@ -894,25 +895,26 @@ void SwIndexMarkPane::UpdateDialog()
if( m_xPrevBT->get_visible() )
{
const SwTOXMark* pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_PRV );
- if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ // tdf#158783 ptr compare OK for SwTOXMark (more below)
+ if (!areSfxPoolItemPtrsEqual( pMoveMark, pMark ))
m_pSh->GotoTOXMark( *pMoveMark, TOX_NXT );
- m_xPrevBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) );
+ m_xPrevBT->set_sensitive( !areSfxPoolItemPtrsEqual(pMoveMark, pMark) );
pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_NXT );
- if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ if (!areSfxPoolItemPtrsEqual( pMoveMark, pMark ))
m_pSh->GotoTOXMark( *pMoveMark, TOX_PRV );
- m_xNextBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) );
+ m_xNextBT->set_sensitive( !areSfxPoolItemPtrsEqual(pMoveMark, pMark) );
}
if (m_xPrevSameBT->get_visible())
{
const SwTOXMark* pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_PRV );
- if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ if (!areSfxPoolItemPtrsEqual( pMoveMark, pMark ))
m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_NXT );
- m_xPrevSameBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) );
+ m_xPrevSameBT->set_sensitive( !areSfxPoolItemPtrsEqual(pMoveMark, pMark) );
pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_NXT );
- if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ if (!areSfxPoolItemPtrsEqual( pMoveMark, pMark ))
m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_PRV );
- m_xNextSameBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) );
+ m_xNextSameBT->set_sensitive( !areSfxPoolItemPtrsEqual(pMoveMark, pMark) );
}
const bool bEnable = !m_pSh->HasReadonlySel();
@@ -1013,7 +1015,8 @@ void SwIndexMarkPane::ReInitDlg(SwWrtShell& rWrtShell, SwTOXMark const * pCurTOX
if(pCurTOXMark)
{
for(sal_uInt16 i = 0; i < m_pTOXMgr->GetTOXMarkCount(); i++)
- if (SfxPoolItem::areSame(m_pTOXMgr->GetTOXMark(i), pCurTOXMark))
+ // tdf#158783 ptr compare OK for SwTOXMark (more below)
+ if (areSfxPoolItemPtrsEqual(m_pTOXMgr->GetTOXMark(i), pCurTOXMark))
{
m_pTOXMgr->SetCurTOXMark(i);
break;
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index cb96c08527..ea419d2326 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -382,7 +382,8 @@ const Graphic* SwTransferable::FindOLEReplacementGraphic() const
void SwTransferable::RemoveDDELinkFormat(vcl::Window& rWin)
{
RemoveFormat( SotClipboardFormatId::LINK );
- CopyToClipboard(&rWin);
+ if (rWin.GetClipboard()->getContents().get() == this)
+ CopyToClipboard(&rWin);
}
void SwTransferable::DisconnectDDE()
diff --git a/sw/source/uibase/docvw/AnnotationWin2.cxx b/sw/source/uibase/docvw/AnnotationWin2.cxx
index a1780f9132..6b8895f1d9 100644
--- a/sw/source/uibase/docvw/AnnotationWin2.cxx
+++ b/sw/source/uibase/docvw/AnnotationWin2.cxx
@@ -504,7 +504,7 @@ void SwAnnotationWin::SetMenuButtonColors()
const tools::Long nBorderDistanceBottom = ((aSymbolRect.GetHeight() * 150) + 500) / 1000;
aSymbolRect.AdjustBottom( -nBorderDistanceBottom );
DecorationView aDecoView(xVirDev.get());
- aDecoView.DrawSymbol(aSymbolRect, SymbolType::SPIN_DOWN, GetTextColor(),
+ aDecoView.DrawSymbol(aSymbolRect, SymbolType::SPIN_DOWN, COL_BLACK,
DrawSymbolFlags::NONE);
mxMenuButton->set_image(xVirDev);
mxMenuButton->set_size_request(aSize.Width() + 4, aSize.Height() + 4);
diff --git a/sw/source/uibase/docvw/SidebarWinAcc.cxx b/sw/source/uibase/docvw/SidebarWinAcc.cxx
index f489bc140b..3b2b4c758e 100644
--- a/sw/source/uibase/docvw/SidebarWinAcc.cxx
+++ b/sw/source/uibase/docvw/SidebarWinAcc.cxx
@@ -23,9 +23,9 @@
#include <viewsh.hxx>
#include <accmap.hxx>
#include <toolkit/awt/vclxaccessiblecomponent.hxx>
+#include <vcl/svapp.hxx>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
-#include <mutex>
namespace sw::sidebarwindows {
@@ -47,7 +47,7 @@ class SidebarWinAccessibleContext : public VCLXAccessibleComponent
void ChangeAnchor( const SwFrame* pAnchorFrame )
{
- std::scoped_lock aGuard(maMutex);
+ SolarMutexGuard aGuard;
mpAnchorFrame = pAnchorFrame;
}
@@ -55,7 +55,7 @@ class SidebarWinAccessibleContext : public VCLXAccessibleComponent
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
getAccessibleParent() override
{
- std::scoped_lock aGuard(maMutex);
+ SolarMutexGuard aGuard;
css::uno::Reference< css::accessibility::XAccessible > xAccParent;
@@ -70,7 +70,7 @@ class SidebarWinAccessibleContext : public VCLXAccessibleComponent
virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override
{
- std::scoped_lock aGuard(maMutex);
+ SolarMutexGuard aGuard;
sal_Int64 nIndex( -1 );
@@ -87,8 +87,6 @@ class SidebarWinAccessibleContext : public VCLXAccessibleComponent
private:
SwViewShell& mrViewShell;
const SwFrame* mpAnchorFrame;
-
- std::mutex maMutex;
};
}
diff --git a/sw/source/uibase/index/toxmgr.cxx b/sw/source/uibase/index/toxmgr.cxx
index 8b8ff6dbd8..c7cd813eb4 100644
--- a/sw/source/uibase/index/toxmgr.cxx
+++ b/sw/source/uibase/index/toxmgr.cxx
@@ -47,7 +47,8 @@ void SwTOXMgr::DeleteTOXMark()
if( m_pCurTOXMark )
{
pNext = const_cast<SwTOXMark*>(&m_pSh->GotoTOXMark( *m_pCurTOXMark, TOX_NXT ));
- if (SfxPoolItem::areSame( pNext, m_pCurTOXMark ))
+ // tdf#158783 ptr compare OK for SwTOXMark (more below)
+ if (areSfxPoolItemPtrsEqual( pNext, m_pCurTOXMark ))
pNext = nullptr;
m_pSh->DeleteTOXMark( m_pCurTOXMark );
diff --git a/sw/source/uibase/shells/textsh.cxx b/sw/source/uibase/shells/textsh.cxx
index 0924935b3d..97de985401 100644
--- a/sw/source/uibase/shells/textsh.cxx
+++ b/sw/source/uibase/shells/textsh.cxx
@@ -877,7 +877,20 @@ void SwTextShell::ExecTransliteration( SfxRequest const & rReq )
void SwTextShell::ExecRotateTransliteration( SfxRequest const & rReq )
{
if( rReq.GetSlot() == SID_TRANSLITERATE_ROTATE_CASE )
- GetShell().TransliterateText( m_aRotateCase.getNextMode() );
+ {
+ SwWrtShell& rSh = GetShell();
+ if (rSh.HasSelection())
+ {
+ rSh.TransliterateText(m_aRotateCase.getNextMode());
+ }
+ else
+ {
+ rSh.Push(); // save cur cursor
+ if ((rSh.IsEndWrd() || rSh.IsStartWord() || rSh.IsInWord()) && rSh.SelWrd())
+ rSh.TransliterateText(m_aRotateCase.getNextMode());
+ rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ }
+ }
}
SwTextShell::SwTextShell(SwView &_rView) :
diff --git a/sw/source/uibase/sidebar/PageSizeControl.cxx b/sw/source/uibase/sidebar/PageSizeControl.cxx
index 4ea5995c09..a2dbe406f3 100644
--- a/sw/source/uibase/sidebar/PageSizeControl.cxx
+++ b/sw/source/uibase/sidebar/PageSizeControl.cxx
@@ -168,7 +168,6 @@ PageSizeControl::PageSizeControl(PageSizePopup* pControl, weld::Widget* pParent)
}
mxSizeValueSet->SetNoSelection();
mxSizeValueSet->SetSelectHdl( LINK(this, PageSizeControl, ImplSizeHdl ) );
- mxSizeValueSet->SetOptimalDrawingAreaHeight();
mxSizeValueSet->Show();
mxSizeValueSet->Resize();
diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx
index cc6faf78a3..f7a10a49f7 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -286,14 +286,21 @@ OUString SwView::GetPageStr(sal_uInt16 nPhyNum, sal_uInt16 nVirtNum, const OUStr
? SwResId(STR_PAGE_COUNT_PRINTED)
: (extra.isEmpty() ? SwResId(STR_PAGE_COUNT) : SwResId(STR_PAGE_COUNT_CUSTOM)));
aStr = aStr.replaceFirst("%1", OUString::number(nPhyNum));
- aStr = aStr.replaceFirst("%2", OUString::number(nPageCount));
if (nPageCount != nPrintedPageCount)
{
+ aStr = aStr.replaceFirst("%2", OUString::number(nPageCount));
aStr = aStr.replaceFirst("%3", OUString::number(nPrintedPhyNum));
aStr = aStr.replaceFirst("%4", OUString::number(nPrintedPageCount));
}
- else
- aStr = aStr.replaceFirst("%3", extra);
+ else {
+ if (extra.isEmpty())
+ aStr = aStr.replaceFirst("%2", OUString::number(nPageCount));
+ else
+ {
+ aStr = aStr.replaceFirst("%2", extra);
+ aStr = aStr.replaceFirst("%3", OUString::number(nPageCount));
+ }
+ }
return aStr;
}
diff --git a/sw/source/uibase/utlui/uitool.cxx b/sw/source/uibase/utlui/uitool.cxx
index fd50bf6678..dfaffe3480 100644
--- a/sw/source/uibase/utlui/uitool.cxx
+++ b/sw/source/uibase/utlui/uitool.cxx
@@ -392,6 +392,7 @@ void ItemSetToPageDesc( const SfxItemSet& rSet, SwPageDesc& rPageDesc )
if(rMaster.GetFooter().IsActive())
{
rMaster.SetFormatAttr(SwFormatFooter(false));
+ // why reset this? but not doing it causes testTdf112694 to fail
rPageDesc.ChgFooterShare(false);
}
}
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 4b2402fc93..0054eca4cb 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -115,6 +115,7 @@
#include <frmtool.hxx>
#include <viewopt.hxx>
+#include <IDocumentRedlineAccess.hxx>
#include <IDocumentUndoRedo.hxx>
#include <UndoInsert.hxx>
#include <UndoCore.hxx>
@@ -1177,8 +1178,12 @@ void SwWrtShell::InsertContentControl(SwContentControlType eType)
Left(SwCursorSkipMode::Chars, /*bSelect=*/true, aPlaceholder.getLength(),
/*bBasicCall=*/false);
}
+
+ const RedlineFlags oldRedlineFlags = getIDocumentRedlineAccess().GetRedlineFlags();
+ getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::Ignore);
SwFormatContentControl aContentControl(pContentControl, RES_TXTATR_CONTENTCONTROL);
SetAttrItem(aContentControl);
+ getIDocumentRedlineAccess().SetRedlineFlags(oldRedlineFlags);
}
// Insert footnote