summaryrefslogtreecommitdiff
path: root/sw/source/core/unocore/unotext.cxx
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2019-12-06 17:39:56 +0100
committerMichael Stahl <michael.stahl@cib.de>2019-12-07 20:37:10 +0100
commit04159aab6827e22a67a0c7bc4d68b4a999d51318 (patch)
tree28ae1058b1218838a97dd8c745f028e63b156b77 /sw/source/core/unocore/unotext.cxx
parentca16def26fa3352edbb642b918b59de1b2fa7fca (diff)
ofz#18563 sw: remove SwXFrame::m_pCopySource to fix ~SwIndexReg assert
The problem is that a text frame is inserted with a selection that partially selects a fieldmark, so the DeleteAndJoin() is split across multiple calls with a temporary cursor, and the correction of the passed in rPam that is ultimately SwXFrame::m_pCopySource is not done, so it remains on a deleted node. Replace it with a SwUnoCursor, which is automatically corrected. It turns out that this m_pCopySource member was only set via a call to SetSelection() from one place in SwXText::convertToTextFrame(), which ends up immediately calling SwXFrame::attach() anyway, which then uses m_pCopySource and resets it. This was added in deba85c5b73f36affe672567ed4a45938953f312 but it would be far simpler to just pass a local variable to SwXFrame::attachToRange(). Change-Id: I85ed128db63c13f81f215d8f50036d9d2aa6c519 Reviewed-on: https://gerrit.libreoffice.org/84661 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@cib.de>
Diffstat (limited to 'sw/source/core/unocore/unotext.cxx')
-rw-r--r--sw/source/core/unocore/unotext.cxx52
1 files changed, 29 insertions, 23 deletions
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index 64d6dc3ef6a2..c689ec89e9a9 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1511,13 +1511,20 @@ SwXText::convertToTextFrame(
throw uno::RuntimeException();
}
uno::Reference< text::XTextContent > xRet;
- SwUnoInternalPaM aStartPam(*GetDoc());
+ std::unique_ptr<SwUnoInternalPaM> pTempStartPam(new SwUnoInternalPaM(*GetDoc()));
std::unique_ptr< SwUnoInternalPaM > pEndPam(new SwUnoInternalPaM(*GetDoc()));
- if (!::sw::XTextRangeToSwPaM(aStartPam, xStart) ||
+ if (!::sw::XTextRangeToSwPaM(*pTempStartPam, xStart) ||
!::sw::XTextRangeToSwPaM(*pEndPam, xEnd))
{
throw lang::IllegalArgumentException();
}
+ auto pStartPam(GetDoc()->CreateUnoCursor(*pTempStartPam->GetPoint()));
+ if (pTempStartPam->HasMark())
+ {
+ pStartPam->SetMark();
+ *pStartPam->GetMark() = *pTempStartPam->GetMark();
+ }
+ pTempStartPam.reset();
SwXTextRange *const pStartRange =
comphelper::getUnoTunnelImplementation<SwXTextRange>(xStart);
@@ -1538,7 +1545,7 @@ SwXText::convertToTextFrame(
bool bIllegalException = false;
bool bRuntimeException = false;
OUString sMessage;
- SwStartNode* pStartStartNode = aStartPam.GetNode().StartOfSectionNode();
+ SwStartNode* pStartStartNode = pStartPam->GetNode().StartOfSectionNode();
while (pStartStartNode && pStartStartNode->IsSectionNode())
{
pStartStartNode = pStartStartNode->StartOfSectionNode();
@@ -1576,9 +1583,9 @@ SwXText::convertToTextFrame(
const SwNodeIndex aTableIdx( *pStartTableNode, -1 );
SwPosition aBefore(aTableIdx);
bParaBeforeInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aBefore );
- aStartPam.DeleteMark();
- *aStartPam.GetPoint() = aBefore;
- pStartStartNode = aStartPam.GetNode().StartOfSectionNode();
+ pStartPam->DeleteMark();
+ *pStartPam->GetPoint() = aBefore;
+ pStartStartNode = pStartPam->GetNode().StartOfSectionNode();
}
if (pEndStartNode->GetStartNodeType() == SwTableBoxStartNode)
{
@@ -1597,8 +1604,8 @@ SwXText::convertToTextFrame(
// if not - remove the additional paragraphs and throw
if (bParaBeforeInserted)
{
- SwCursor aDelete(*aStartPam.GetPoint(), nullptr);
- *aStartPam.GetPoint() = // park it because node is deleted
+ SwCursor aDelete(*pStartPam->GetPoint(), nullptr);
+ *pStartPam->GetPoint() = // park it because node is deleted
SwPosition(GetDoc()->GetNodes().GetEndOfContent());
aDelete.MovePara(GoCurrPara, fnParaStart);
aDelete.SetMark();
@@ -1619,20 +1626,20 @@ SwXText::convertToTextFrame(
}
}
- // make a selection from aStartPam to a EndPam
+ // make a selection from pStartPam to pEndPam
// If there is no content in the frame the shape is in
// it gets deleted in the DelFullPara call below,
// In this case insert a tmp text node ( we delete it later )
- if ( aStartPam.Start()->nNode == pEndPam->Start()->nNode
- && aStartPam.End()->nNode == pEndPam->End()->nNode )
+ if (pStartPam->Start()->nNode == pEndPam->Start()->nNode
+ && pStartPam->End()->nNode == pEndPam->End()->nNode)
{
- SwPosition aEnd(*aStartPam.End());
+ SwPosition aEnd(*pStartPam->End());
bParaAfterInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aEnd );
pEndPam->DeleteMark();
*pEndPam->GetPoint() = aEnd;
}
- aStartPam.SetMark();
- *aStartPam.End() = *pEndPam->End();
+ pStartPam->SetMark();
+ *pStartPam->End() = *pEndPam->End();
pEndPam.reset();
// see if there are frames already anchored to this node
@@ -1646,8 +1653,8 @@ SwXText::convertToTextFrame(
const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
if ( !isGraphicNode(pFrameFormat) &&
(RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId() || RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) &&
- aStartPam.Start()->nNode.GetIndex() <= rAnchor.GetContentAnchor()->nNode.GetIndex() &&
- aStartPam.End()->nNode.GetIndex() >= rAnchor.GetContentAnchor()->nNode.GetIndex())
+ pStartPam->Start()->nNode.GetIndex() <= rAnchor.GetContentAnchor()->nNode.GetIndex() &&
+ pStartPam->End()->nNode.GetIndex() >= rAnchor.GetContentAnchor()->nNode.GetIndex())
{
if (pFrameFormat->GetName().isEmpty())
{
@@ -1663,7 +1670,6 @@ SwXText::convertToTextFrame(
const uno::Reference<text::XTextFrame> xNewFrame(
SwXTextFrame::CreateXTextFrame(*m_pImpl->m_pDoc, nullptr));
SwXTextFrame& rNewFrame = dynamic_cast<SwXTextFrame&>(*xNewFrame);
- rNewFrame.SetSelection( aStartPam );
try
{
for (const beans::PropertyValue& rValue : rFrameProperties)
@@ -1674,19 +1680,19 @@ SwXText::convertToTextFrame(
{ // has to be in a block to remove the SwIndexes before
// DelFullPara is called
const uno::Reference< text::XTextRange> xInsertTextRange =
- new SwXTextRange(aStartPam, this);
- aStartPam.DeleteMark(); // mark position node may be deleted!
- rNewFrame.attach( xInsertTextRange );
+ new SwXTextRange(*pStartPam, this);
+ assert(rNewFrame.IsDescriptor());
+ rNewFrame.attachToRange(xInsertTextRange, pStartPam.get());
rNewFrame.setName(m_pImpl->m_pDoc->GetUniqueFrameName());
}
- SwTextNode *const pTextNode(aStartPam.GetNode().GetTextNode());
+ SwTextNode *const pTextNode(pStartPam->GetNode().GetTextNode());
assert(pTextNode);
if (!pTextNode || !pTextNode->Len()) // don't remove if it contains text!
{
{ // has to be in a block to remove the SwIndexes before
// DelFullPara is called
- SwPaM aMovePam( aStartPam.GetNode() );
+ SwPaM aMovePam( pStartPam->GetNode() );
if (aMovePam.Move( fnMoveForward, GoInContent ))
{
// move the anchor to the next paragraph
@@ -1710,7 +1716,7 @@ SwXText::convertToTextFrame(
}
}
}
- m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(aStartPam);
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pStartPam);
}
}
catch (const lang::IllegalArgumentException& rIllegal)