[Libreoffice-commits] core.git: Branch 'libreoffice-6-4' - 2 commits - sw/inc sw/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Sat Dec 7 21:35:29 UTC 2019
sw/inc/unoframe.hxx | 5 -
sw/source/core/doc/DocumentContentOperationsManager.cxx | 31 +++++++--
sw/source/core/unocore/unoframe.cxx | 18 +----
sw/source/core/unocore/unotext.cxx | 52 ++++++++--------
4 files changed, 60 insertions(+), 46 deletions(-)
New commits:
commit 2d5b0b03f77bc43c8c6ac0b46e8f2e20c32dd3f2
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Dec 6 17:39:56 2019 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 7 22:35:06 2019 +0100
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 at cib.de>
(cherry picked from commit 04159aab6827e22a67a0c7bc4d68b4a999d51318)
Reviewed-on: https://gerrit.libreoffice.org/84693
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sw/inc/unoframe.hxx b/sw/inc/unoframe.hxx
index 074f7b814535..6fcce7a82032 100644
--- a/sw/inc/unoframe.hxx
+++ b/sw/inc/unoframe.hxx
@@ -71,8 +71,6 @@ private:
bool bIsDescriptor;
OUString m_sName;
- std::unique_ptr<SwPaM> m_pCopySource;
-
sal_Int64 m_nDrawAspect;
sal_Int64 m_nVisibleAreaWidth;
sal_Int64 m_nVisibleAreaHeight;
@@ -148,7 +146,8 @@ public:
/// @throws css::lang::IllegalArgumentException
/// @throws css::uno::RuntimeException
- void attachToRange(const css::uno::Reference< css::text::XTextRange > & xTextRange);
+ void attachToRange(css::uno::Reference<css::text::XTextRange> const& xTextRange,
+ SwPaM const* pCopySource = nullptr);
const SwFrameFormat* GetFrameFormat() const
{ return m_pFrameFormat; }
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
index 294db651c919..69171335a842 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -1267,7 +1267,6 @@ SwXFrame::SwXFrame(SwFrameFormat& rFrameFormat, FlyCntType eSet, const ::SfxItem
SwXFrame::~SwXFrame()
{
SolarMutexGuard aGuard;
- m_pCopySource.reset();
m_pProps.reset();
EndListeningAll();
}
@@ -1356,13 +1355,6 @@ uno::Reference< beans::XPropertySetInfo > SwXFrame::getPropertySetInfo()
return xRef;
}
-void SwXFrame::SetSelection(SwPaM& rCopySource)
-{
- m_pCopySource.reset(new SwPaM(*rCopySource.Start()));
- m_pCopySource->SetMark();
- *m_pCopySource->GetMark() = *rCopySource.End();
-}
-
SdrObject *SwXFrame::GetOrCreateSdrObject(SwFlyFrameFormat &rFormat)
{
SdrObject* pObject = rFormat.FindSdrObject();
@@ -2668,7 +2660,8 @@ void SwXFrame::ResetDescriptor()
m_pProps.reset();
}
-void SwXFrame::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
+void SwXFrame::attachToRange(uno::Reference<text::XTextRange> const& xTextRange,
+ SwPaM const*const pCopySource)
{
SolarMutexGuard aGuard;
if(!IsDescriptor())
@@ -2760,7 +2753,7 @@ void SwXFrame::attachToRange(const uno::Reference< text::XTextRange > & xTextRan
if( eType == FLYCNTTYPE_FRM)
{
UnoActionContext aCont(pDoc);
- if(m_pCopySource)
+ if (pCopySource)
{
std::unique_ptr<SwFormatAnchor> pAnchorItem;
// the frame is inserted bound to page
@@ -2773,18 +2766,17 @@ void SwXFrame::attachToRange(const uno::Reference< text::XTextRange > & xTextRan
aPam.DeleteMark(); // mark position node will be deleted!
aIntPam.DeleteMark(); // mark position node will be deleted!
- pFormat = pDoc->MakeFlyAndMove( *m_pCopySource, aFrameSet,
+ pFormat = pDoc->MakeFlyAndMove( *pCopySource, aFrameSet,
nullptr,
pParentFrameFormat );
if(pAnchorItem && pFormat)
{
pFormat->DelFrames();
- pAnchorItem->SetAnchor( m_pCopySource->Start() );
+ pAnchorItem->SetAnchor( pCopySource->Start() );
SfxItemSet aAnchorSet( pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>{} );
aAnchorSet.Put( *pAnchorItem );
pDoc->SetFlyFrameAttr( *pFormat, aAnchorSet );
}
- m_pCopySource.reset();
}
else
{
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index d49b07e35cb9..c9bd3aca8310 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1517,13 +1517,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);
@@ -1544,7 +1551,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();
@@ -1582,9 +1589,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)
{
@@ -1603,8 +1610,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();
@@ -1625,20 +1632,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
@@ -1652,8 +1659,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())
{
@@ -1669,7 +1676,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)
@@ -1680,19 +1686,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
@@ -1716,7 +1722,7 @@ SwXText::convertToTextFrame(
}
}
}
- m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(aStartPam);
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pStartPam);
}
}
catch (const lang::IllegalArgumentException& rIllegal)
commit dba967656d5176f582f3102da129977ac5a0684d
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Dec 6 17:44:26 2019 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 7 22:34:52 2019 +0100
ofz#18563 sw: fix 2 problems with field marks
* sw::CalcBreaks had a thinko in that a separator that had a start but
no matching end wasn't reported
* DocumentContentOperationsManager::DelFullPara() may apparently be
called with a rPam having just one position, in which case expanding
it doesn't work.
Change-Id: I6503498dd38d188799385aa706ffe7dfccfdba08
Reviewed-on: https://gerrit.libreoffice.org/84662
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit 522ed1b685f5b7eb52efb9d874dfacc02bf82139)
Reviewed-on: https://gerrit.libreoffice.org/84692
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 4b9ee39a1ed4..7f03a5c96b6e 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -81,6 +81,8 @@
#include <com/sun/star/i18n/WordType.hpp>
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
+
+#include <tuple>
#include <memory>
@@ -494,7 +496,7 @@ namespace sw
SwNodes const& rNodes(rPam.GetPoint()->nNode.GetNodes());
IDocumentMarkAccess const& rIDMA(*rPam.GetDoc()->getIDocumentMarkAccess());
- std::stack<sw::mark::IFieldmark const*> startedFields;
+ std::stack<std::tuple<sw::mark::IFieldmark const*, bool, sal_uLong, sal_Int32>> startedFields;
for (sal_uLong n = nStartNode; n <= nEndNode; ++n)
{
@@ -534,7 +536,7 @@ namespace sw
case CH_TXT_ATR_FIELDSTART:
{
auto const pFieldMark(rIDMA.getFieldmarkAt(SwPosition(rTextNode, i)));
- startedFields.push(pFieldMark);
+ startedFields.emplace(pFieldMark, false, 0, 0);
break;
}
case CH_TXT_ATR_FIELDSEP:
@@ -545,7 +547,10 @@ namespace sw
}
else
{ // no way to find the field via MarkManager...
- assert(startedFields.top()->IsCoveringPosition(SwPosition(rTextNode, i)));
+ assert(std::get<0>(startedFields.top())->IsCoveringPosition(SwPosition(rTextNode, i)));
+ std::get<1>(startedFields.top()) = true;
+ std::get<2>(startedFields.top()) = n;
+ std::get<3>(startedFields.top()) = i;
}
break;
}
@@ -557,7 +562,7 @@ namespace sw
}
else
{ // fieldmarks must not overlap => stack
- assert(startedFields.top() == rIDMA.getFieldmarkAt(SwPosition(rTextNode, i)));
+ assert(std::get<0>(startedFields.top()) == rIDMA.getFieldmarkAt(SwPosition(rTextNode, i)));
startedFields.pop();
}
break;
@@ -579,14 +584,22 @@ namespace sw
}
while (!startedFields.empty())
{
- auto const pField(startedFields.top());
- startedFields.pop();
- SwPosition const& rStart(pField->GetMarkStart());
+ SwPosition const& rStart(std::get<0>(startedFields.top())->GetMarkStart());
std::pair<sal_uLong, sal_Int32> const pos(
rStart.nNode.GetIndex(), rStart.nContent.GetIndex());
auto it = std::lower_bound(rBreaks.begin(), rBreaks.end(), pos);
assert(it == rBreaks.end() || *it != pos);
rBreaks.insert(it, pos);
+ if (std::get<1>(startedFields.top()))
+ {
+ std::pair<sal_uLong, sal_Int32> const posSep(
+ std::get<2>(startedFields.top()),
+ std::get<3>(startedFields.top()));
+ it = std::lower_bound(rBreaks.begin(), rBreaks.end(), posSep);
+ assert(it == rBreaks.end() || *it != posSep);
+ rBreaks.insert(it, posSep);
+ }
+ startedFields.pop();
}
}
}
@@ -1963,6 +1976,10 @@ bool DocumentContentOperationsManager::DelFullPara( SwPaM& rPam )
{
SwPaM temp(rPam, nullptr);
+ if (!temp.HasMark())
+ {
+ temp.SetMark();
+ }
if (SwTextNode *const pNode = temp.Start()->nNode.GetNode().GetTextNode())
{ // rPam may not have nContent set but IsFieldmarkOverlap requires it
pNode->MakeStartIndex(&temp.Start()->nContent);
More information about the Libreoffice-commits
mailing list