From 9c0049cfae49c8e4ddef9125a69db2ad134c10c6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 7 Jun 2024 13:48:25 +0200 Subject: Merging upstream version 4:24.2.4. Signed-off-by: Daniel Baumann --- sw/source/core/access/accfrmobj.cxx | 15 ++- sw/source/core/crsr/crsrsh.cxx | 12 +- .../core/doc/DocumentContentOperationsManager.cxx | 89 ++++++++------ sw/source/core/doc/DocumentSettingManager.cxx | 21 ++++ sw/source/core/doc/docdraw.cxx | 12 ++ sw/source/core/doc/docfmt.cxx | 10 +- sw/source/core/doc/docnum.cxx | 98 +++++++++++++--- sw/source/core/doc/doctxm.cxx | 3 +- sw/source/core/docnode/nodes.cxx | 2 +- sw/source/core/draw/dcontact.cxx | 21 ++-- sw/source/core/draw/dview.cxx | 129 ++++++++++++--------- sw/source/core/edit/autofmt.cxx | 2 +- sw/source/core/edit/edglss.cxx | 8 ++ sw/source/core/edit/ednumber.cxx | 12 +- sw/source/core/fields/fldbas.cxx | 10 +- sw/source/core/fields/reffld.cxx | 66 +++++++---- sw/source/core/frmedt/fecopy.cxx | 40 +++++-- sw/source/core/frmedt/fefly1.cxx | 60 +++++++++- sw/source/core/frmedt/feshview.cxx | 59 +++++++--- sw/source/core/inc/DocumentSettingManager.hxx | 2 + sw/source/core/inc/frame.hxx | 3 + sw/source/core/inc/sectfrm.hxx | 2 +- sw/source/core/layout/anchoreddrawobject.cxx | 4 + sw/source/core/layout/anchoredobject.cxx | 11 +- sw/source/core/layout/calcmove.cxx | 38 ++++++ sw/source/core/layout/flowfrm.cxx | 5 + sw/source/core/layout/fly.cxx | 4 +- sw/source/core/layout/flylay.cxx | 41 ++++--- sw/source/core/layout/frmtool.cxx | 40 ++++--- sw/source/core/layout/layact.cxx | 4 +- sw/source/core/layout/pagechg.cxx | 25 ++-- sw/source/core/layout/trvlfrm.cxx | 39 ++++--- .../objectpositioning/anchoredobjectposition.cxx | 5 +- sw/source/core/text/inftxt.hxx | 6 +- sw/source/core/text/itratr.hxx | 2 +- sw/source/core/text/itrform2.cxx | 13 ++- sw/source/core/text/itrtxt.hxx | 2 +- sw/source/core/txtnode/atrflyin.cxx | 3 +- sw/source/core/txtnode/thints.cxx | 4 +- sw/source/core/undo/undraw.cxx | 31 +++-- sw/source/core/undo/unnum.cxx | 4 +- sw/source/core/undo/untblk.cxx | 6 +- sw/source/core/unocore/unocrsrhelper.cxx | 8 +- sw/source/core/unocore/unoportenum.cxx | 4 +- sw/source/core/unocore/unotext.cxx | 6 - 45 files changed, 675 insertions(+), 306 deletions(-) (limited to 'sw/source/core') diff --git a/sw/source/core/access/accfrmobj.cxx b/sw/source/core/access/accfrmobj.cxx index f78dc2d155..004ca4ab94 100644 --- a/sw/source/core/access/accfrmobj.cxx +++ b/sw/source/core/access/accfrmobj.cxx @@ -240,13 +240,16 @@ SwRect SwAccessibleChild::GetBox( const SwAccessibleMap& rAccMap ) const // by the mpFrame case above b) for genuine SdrObject this must be set // if it's connected to layout assert(dynamic_cast(pContact)); - SwPageFrame const*const pPage(const_cast( - pContact->GetAnchoredObj(mpDrawObj))->FindPageFrameOfAnchor()); - if (pPage) // may end up here with partial layout -> not visible + if (pContact) { - aBox = SwRect( mpDrawObj->GetCurrentBoundRect() ); - // tdf#91260 drawing object may be partially off-page - aBox.Intersection(pPage->getFrameArea()); + SwPageFrame const*const pPage(const_cast( + pContact->GetAnchoredObj(mpDrawObj))->FindPageFrameOfAnchor()); + if (pPage) // may end up here with partial layout -> not visible + { + aBox = SwRect( mpDrawObj->GetCurrentBoundRect() ); + // tdf#91260 drawing object may be partially off-page + aBox.Intersection(pPage->getFrameArea()); + } } } else if ( mpWindow ) diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index b7f6962982..33f11e9a28 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -738,9 +738,15 @@ bool SwCursorShell::MoveStartText() SwTableNode const*const pTable(pStartNode->FindTableNode()); m_pCurrentCursor->GetPoint()->Assign(*pStartNode); GetDoc()->GetNodes().GoNext(m_pCurrentCursor->GetPoint()); - while (m_pCurrentCursor->GetPoint()->GetNode().FindTableNode() != pTable - && (!pTable || pTable->GetIndex() < m_pCurrentCursor->GetPoint()->GetNode().FindTableNode()->GetIndex()) - && MoveOutOfTable()); + while (auto* pFoundTable = m_pCurrentCursor->GetPoint()->GetNode().FindTableNode()) + { + if (pFoundTable == pTable) + break; + if (pTable && pTable->GetIndex() >= pFoundTable->GetIndex()) + break; + if (!MoveOutOfTable()) + break; + } UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY); return old != *m_pCurrentCursor->GetPoint(); } diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 57b8e58310..234d73aecb 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -5065,16 +5066,14 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo // Move the PaM one node back from the insert position, so that // the position doesn't get moved pCopyPam->SetMark(); - bool bCanMoveBack = pCopyPam->Move(fnMoveBackward, GoInContent); - // If the position was shifted from more than one node, an end node has been skipped - bool bAfterTable = false; - if ((rPos.GetNodeIndex() - pCopyPam->GetPoint()->GetNodeIndex()) > SwNodeOffset(1)) + bool bCanMoveBack = false; + // First check if it will be able to move *to* first copied node. + // Note this doesn't just check IsStartNode() because SwDoc::AppendDoc() + // intentionally sets it to the body start node, perhaps it should just + // call SplitNode instead? + if (!pStt->GetNode().IsSectionNode() && !pStt->GetNode().IsTableNode()) { - // First go back to the original place - *(pCopyPam->GetPoint()) = rPos; - - bCanMoveBack = false; - bAfterTable = true; + bCanMoveBack = pCopyPam->Move(fnMoveBackward, GoInContent); } if( !bCanMoveBack ) { @@ -5084,6 +5083,7 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo SwNodeRange aRg( pStt->GetNode(), pEnd->GetNode() ); SwNodeIndex aInsPos( rPos.GetNode() ); + ::std::optional oInsContentIndex; const bool bOneNode = pStt->GetNode() == pEnd->GetNode(); SwTextNode* pSttTextNd = pStt->GetNode().GetTextNode(); SwTextNode* pEndTextNd = pEnd->GetNode().GetTextNode(); @@ -5107,12 +5107,16 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo // bullet list. // Keep also the value for possible propagation. OUString aListIdToPropagate; + SvxTextLeftMarginItem const* pTextLeftMarginToPropagate{nullptr}; + SvxFirstLineIndentItem const* pFirstLineIndentToPropagate{nullptr}; const SwNumRule* pNumRuleToPropagate = - rDoc.SearchNumRule( rPos, false, true, false, 0, aListIdToPropagate, nullptr, true ); + rDoc.SearchNumRule(rPos, false, true, false, 0, aListIdToPropagate, nullptr, + true, &pTextLeftMarginToPropagate, &pFirstLineIndentToPropagate); if ( !pNumRuleToPropagate ) { pNumRuleToPropagate = - rDoc.SearchNumRule( rPos, false, false, false, 0, aListIdToPropagate, nullptr, true ); + rDoc.SearchNumRule(rPos, false, false, false, 0, aListIdToPropagate, nullptr, + true, &pTextLeftMarginToPropagate, &pFirstLineIndentToPropagate); } // #i86492# // Do not propagate previous found list, if @@ -5236,8 +5240,8 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo // We have to set the correct PaM for Undo, if this PaM starts in a textnode, // the undo operation will try to merge this node after removing the table. // If we didn't split a textnode, the PaM should start at the inserted table node - if( rPos.GetContentIndex() == pDestTextNd->Len() ) - { // Insertion at the last position of a textnode (empty or not) + if (pDestTextNd->Len() && rPos.GetContentIndex() == pDestTextNd->Len()) + { // Insertion at the last position of a textnode ++aInsPos; // The table will be inserted behind the text node } else if( rPos.GetContentIndex() ) @@ -5269,27 +5273,18 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo --aRg.aEnd; } } - else if( bCanMoveBack ) - { // Insertion at the first position of a text node. It will not be split, the table - // will be inserted before the text node. - // See below, before the SetInsertRange function of the undo object will be called, - // the CpyPam would be moved to the next content position. This has to be avoided - // We want to be moved to the table node itself thus we have to set bCanMoveBack - // and to manipulate pCopyPam. - bCanMoveBack = false; - pCopyPam->GetPoint()->Adjust(SwNodeOffset(-1)); - } + assert(!bCanMoveBack); } pDestTextNd = aInsPos.GetNode().GetTextNode(); if (pEndTextNd) { - SwContentIndex aDestIdx( aInsPos.GetNode().GetContentNode(), rPos.GetContentIndex() ); + oInsContentIndex.emplace(aInsPos.GetNode().GetContentNode(), rPos.GetContentIndex()); if( !pDestTextNd ) { pDestTextNd = rDoc.GetNodes().MakeTextNode( aInsPos.GetNode(), rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD)); - aDestIdx.Assign( pDestTextNd, 0 ); + oInsContentIndex->Assign(pDestTextNd, 0); --aInsPos; // if we have to insert an extra text node @@ -5307,8 +5302,8 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo PUSH_NUMRULE_STATE } - pEndTextNd->CopyText( pDestTextNd, aDestIdx, SwContentIndex( pEndTextNd ), - pEnd->GetContentIndex() ); + pEndTextNd->CopyText(pDestTextNd, *oInsContentIndex, + SwContentIndex(pEndTextNd), pEnd->GetContentIndex()); // Also copy all format templates if( bCopyCollFormat && ( bOneNode || bEmptyDestNd )) @@ -5360,20 +5355,29 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo bCopyBookmarks = false; } + + // init *again* - because CopyWithFlyInFly moved startPos + SwPosition startPos(pCopyPam->GetPoint()->GetNode(), SwNodeOffset(+1)); // at-char anchors post SplitNode are on index 0 of 2nd node and will // remain there - move them back to the start (end would also work?) // ... also for at-para anchors; here start is preferable because // it's consistent with SplitNode from SwUndoInserts::RedoImpl() - if (pFlysAtInsPos) + if (pFlysAtInsPos + && (bCanMoveBack + || startPos.GetNode().IsTextNode() + || (pCopyPam->GetPoint()->GetNode().IsStartNode() + && startPos.GetNode().IsSectionNode()))) // not into table { - // init *again* - because CopyWithFlyInFly moved startPos - SwPosition startPos(pCopyPam->GetPoint()->GetNode(), SwNodeOffset(+1)); if (bCanMoveBack) { // pCopyPam is actually 1 before the copy range so move it fwd SwPaM temp(*pCopyPam->GetPoint()); temp.Move(fnMoveForward, GoInContent); startPos = *temp.GetPoint(); } + else if (startPos.GetNode().IsSectionNode()) + { // probably on top-level start node, so no CheckNodesRange here; + GoNextPos(&startPos, false); // SwFEShell::Paste() deletes node + } assert(startPos.GetNode().IsContentNode()); SwPosition startPosAtPara(startPos); startPosAtPara.nContent.Assign(nullptr, 0); @@ -5456,26 +5460,31 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo } else // incremented in (!pSttTextNd && pDestTextNd) above { - pCopyPam->GetMark()->Assign(aInsPos); + // assign also content index in this case, see testSectionAnchorCopyTableAtStart + assert(oInsContentIndex); + assert(oInsContentIndex->GetContentNode() == &aInsPos.GetNode()); + pCopyPam->GetMark()->Assign(aInsPos, oInsContentIndex->GetIndex()); } rPos = *pCopyPam->GetMark(); } else *pCopyPam->GetMark() = rPos; - if ( !bAfterTable ) - pCopyPam->Move( fnMoveForward, bCanMoveBack ? GoInContent : GoInNode ); + if (bCanMoveBack) + { + pCopyPam->Move(fnMoveForward, GoInContent); + } else { // Reset the offset to 0 as it was before the insertion pCopyPam->GetPoint()->Adjust(SwNodeOffset(+1)); - // If the next node is a start node, then step back: the start node - // has been copied and needs to be in the selection for the undo + // If the next node is a start node, then step back: SetInsertRange() + // will add 1 in this case, but that is too much... if (pCopyPam->GetPoint()->GetNode().IsStartNode()) pCopyPam->GetPoint()->Adjust(SwNodeOffset(-1)); - } + oInsContentIndex.reset(); pCopyPam->Exchange(); // Also copy all bookmarks @@ -5513,8 +5522,12 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo // #i86492# - use , because it also handles the // Don't reset indent attributes, that would mean loss of direct // formatting. - rDoc.SetNumRule( *pCopyPam, *pNumRuleToPropagate, false, nullptr, - aListIdToPropagate, true, /*bResetIndentAttrs=*/false ); + // It could be that pNumRuleToPropagate is already applied via + // the paragraph style, in that case applying it again in mpAttrSet could + // override indents, so avoid that. + rDoc.SetNumRule(*pCopyPam, *pNumRuleToPropagate, + SwDoc::SetNumRuleMode::DontSetIfAlreadyApplied, nullptr, aListIdToPropagate, + pTextLeftMarginToPropagate, pFirstLineIndentToPropagate); } rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld ); diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx index baa0f29326..14cfa5fd3c 100644 --- a/sw/source/core/doc/DocumentSettingManager.cxx +++ b/sw/source/core/doc/DocumentSettingManager.cxx @@ -250,10 +250,14 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const case DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE: return mbAutoFirstLineIndentDisregardLineSpace; case DocumentSettingId::HYPHENATE_URLS: return mbHyphenateURLs; + case DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH: + return mbApplyTextAttrToEmptyLineAtEndOfParagraph; case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES: return mbDoNotBreakWrappedTables; case DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK: return mbAllowTextAfterFloatingTableBreak; + case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS: + return mbDoNotMirrorRtlDrawObjs; case DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING: return mbJustifyLinesWithShrinking; case DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY: return mbNoNumberingShowFollowBy; @@ -444,6 +448,14 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo mbHyphenateURLs = value; break; + case DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH: + mbApplyTextAttrToEmptyLineAtEndOfParagraph = value; + break; + + case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS: + mbDoNotMirrorRtlDrawObjs = value; + break; + case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES: mbDoNotBreakWrappedTables = value; break; @@ -1091,7 +1103,16 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mnImagePreferredDPI")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(mnImagePreferredDPI).getStr())); + (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbApplyTextAttrToEmptyLineAtEndOfParagraph")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::boolean(mbApplyTextAttrToEmptyLineAtEndOfParagraph).getStr())); + (void)xmlTextWriterEndElement(pWriter); + + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbDoNotMirrorRtlDrawObjs")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::boolean(mbDoNotMirrorRtlDrawObjs).getStr())); (void)xmlTextWriterEndElement(pWriter); (void)xmlTextWriterEndElement(pWriter); diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx index 521ca2b0ba..09b1d9afb6 100644 --- a/sw/source/core/doc/docdraw.cxx +++ b/sw/source/core/doc/docdraw.cxx @@ -68,6 +68,9 @@ static void lcl_AdjustPositioningAttr( SwDrawFrameFormat* _pFrameFormat, const SwContact* pContact = GetUserCall( &_rSdrObj ); OSL_ENSURE( pContact, " - missing contact object." ); + if (!pContact) + return; + // determine position of new group object relative to its anchor frame position SwTwips nHoriRelPos = 0; SwTwips nVertRelPos = 0; @@ -195,6 +198,9 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView ) // Revoke anchor attribute. SwDrawContact *pMyContact = static_cast(GetUserCall(pObj)); + if (!pMyContact) + return pNewContact; + const SwFormatAnchor aAnch( pMyContact->GetFormat()->GetAnchor() ); std::unique_ptr pUndo; @@ -216,6 +222,9 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView ) pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); SwDrawContact *pContact = static_cast(GetUserCall(pObj)); + if (!pContact) + continue; + // #i53320# #if OSL_DEBUG_LEVEL > 0 SwAnchoredDrawObject* pAnchoredDrawObj = @@ -352,6 +361,9 @@ void SwDoc::UnGroupSelection( SdrView& rDrawView ) { SwDrawContact *pContact = static_cast(GetUserCall(pObj)); + if (!pContact) + continue; + std::shared_ptr pTextBoxNode; if (auto pGroupFormat = pContact->GetFormat()) pTextBoxNode = pGroupFormat->GetOtherTextBoxFormats(); diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 1c696bebb6..3390a50605 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -1040,14 +1040,12 @@ static bool lcl_SetTextFormatColl( SwNode* pNode, void* pArgs ) } } + std::optional oRegH; + if (pPara->pHistory) + oRegH.emplace(&rTNd, rTNd, pPara->pHistory); + if ( bChangeOfListStyleAtParagraph ) { - std::unique_ptr< SwRegHistory > pRegH; - if ( pPara->pHistory ) - { - pRegH.reset(new SwRegHistory(&rTNd, rTNd, pPara->pHistory)); - } - pCNd->ResetAttr( RES_PARATR_NUMRULE ); // reset all list attributes diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx index 0735380e5d..01c4a1b387 100644 --- a/sw/source/core/doc/docnum.cxx +++ b/sw/source/core/doc/docnum.cxx @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -860,11 +861,11 @@ static void lcl_ChgNumRule( SwDoc& rDoc, const SwNumRule& rRule ) OUString SwDoc::SetNumRule( const SwPaM& rPam, const SwNumRule& rRule, - const bool bCreateNewList, + SetNumRuleMode eMode, SwRootFrame const*const pLayout, const OUString& sContinuedListId, - bool bSetItem, - const bool bResetIndentAttrs ) + SvxTextLeftMarginItem const*const pTextLeftMarginToPropagate, + SvxFirstLineIndentItem const*const pFirstLineIndentToPropagate) { OUString sListId; @@ -902,9 +903,9 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam, } } - if ( bSetItem ) + if (!(eMode & SetNumRuleMode::DontSetItem)) { - if ( bCreateNewList ) + if (eMode & SetNumRuleMode::CreateNewList) { if ( bNewNumRuleCreated ) { @@ -944,7 +945,7 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam, if (pRule && pRule->GetName() == pNewOrChangedNumRule->GetName()) { - bSetItem = false; + eMode |= SetNumRuleMode::DontSetItem; if ( !pTextNd->IsInList() ) { pTextNd->AddToList(); @@ -961,21 +962,67 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam, if ( pCollRule && pCollRule->GetName() == pNewOrChangedNumRule->GetName() ) { pTextNd->ResetAttr( RES_PARATR_NUMRULE ); - bSetItem = false; + eMode |= SetNumRuleMode::DontSetItem; } } } } } - if ( bSetItem ) + if (!(eMode & SetNumRuleMode::DontSetItem)) { - getIDocumentContentOperations().InsertPoolItem(aPam, - SwNumRuleItem(pNewOrChangedNumRule->GetName()), - SetAttrMode::DEFAULT, pLayout); + if (eMode & SetNumRuleMode::DontSetIfAlreadyApplied) + { + for (SwNodeIndex i = aPam.Start()->nNode; i <= aPam.End()->nNode; ++i) + { + if (SwTextNode const*const pNode = i.GetNode().GetTextNode()) + { + if (pNode->GetNumRule(true) != pNewOrChangedNumRule) + { + // only apply if it doesn't already have it - to + // avoid overriding indents from style + SwPaM const temp(*pNode, 0, *pNode, pNode->Len()); + getIDocumentContentOperations().InsertPoolItem(temp, + SwNumRuleItem(pNewOrChangedNumRule->GetName()), + SetAttrMode::DEFAULT, pLayout); + // apply provided margins to get visually same result + if (pTextLeftMarginToPropagate) + { + getIDocumentContentOperations().InsertPoolItem(temp, + *pTextLeftMarginToPropagate, + SetAttrMode::DEFAULT, pLayout); + } + if (pFirstLineIndentToPropagate) + { + getIDocumentContentOperations().InsertPoolItem(temp, + *pFirstLineIndentToPropagate, + SetAttrMode::DEFAULT, pLayout); + } + } + } + } + } + else + { + getIDocumentContentOperations().InsertPoolItem(aPam, + SwNumRuleItem(pNewOrChangedNumRule->GetName()), + SetAttrMode::DEFAULT, pLayout); + if (pTextLeftMarginToPropagate) + { + getIDocumentContentOperations().InsertPoolItem(aPam, + *pTextLeftMarginToPropagate, + SetAttrMode::DEFAULT, pLayout); + } + if (pFirstLineIndentToPropagate) + { + getIDocumentContentOperations().InsertPoolItem(aPam, + *pFirstLineIndentToPropagate, + SetAttrMode::DEFAULT, pLayout); + } + } } - if ( bResetIndentAttrs + if ((eMode & SetNumRuleMode::ResetIndentAttrs) && pNewOrChangedNumRule->Get( 0 ).GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT ) { const o3tl::sorted_vector attrs{ RES_MARGIN_FIRSTLINE, RES_MARGIN_TEXTLEFT, RES_MARGIN_RIGHT }; @@ -1275,7 +1322,7 @@ void SwDoc::MakeUniqueNumRules(const SwPaM & rPaM) SetNumRule( aPam, *aListStyleData.pReplaceNumRule, - aListStyleData.bCreateNewList, + aListStyleData.bCreateNewList ? SetNumRuleMode::CreateNewList : SetNumRuleMode::Default, nullptr, aListStyleData.sListId ); if ( aListStyleData.bCreateNewList ) @@ -1624,7 +1671,9 @@ const SwNumRule * SwDoc::SearchNumRule(const SwPosition & rPos, int nNonEmptyAllowed, OUString& sListId, SwRootFrame const* pLayout, - const bool bInvestigateStartNode) + const bool bInvestigateStartNode, + SvxTextLeftMarginItem const** o_ppTextLeftMargin, + SvxFirstLineIndentItem const** o_ppFirstLineIndent) { const SwNumRule * pResult = nullptr; SwTextNode * pTextNd = rPos.GetNode().GetTextNode(); @@ -1661,9 +1710,28 @@ const SwNumRule * SwDoc::SearchNumRule(const SwPosition & rPos, ( ( bNum && pNumRule->Get(0).IsEnumeration()) || ( !bNum && pNumRule->Get(0).IsItemize() ) ) ) // #i22362#, #i29560# { - pResult = pTextNd->GetNumRule(); + pResult = pNumRule; // provide also the list id, to which the text node belongs. sListId = pTextNd->GetListId(); + // also get the margins that override the numrule + int const nListLevel{pTextNd->GetActualListLevel()}; + if ((o_ppTextLeftMargin || o_ppFirstLineIndent) + && 0 <= nListLevel + && pNumRule->Get(o3tl::narrowing(nListLevel)) + .GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT) + { + ::sw::ListLevelIndents const indents{pTextNd->AreListLevelIndentsApplicable()}; + if (!(indents & ::sw::ListLevelIndents::LeftMargin) + && o_ppTextLeftMargin) + { + *o_ppTextLeftMargin = &pTextNd->SwContentNode::GetAttr(RES_MARGIN_TEXTLEFT); + } + if (!(indents & ::sw::ListLevelIndents::FirstLine) + && o_ppFirstLineIndent) + { + *o_ppFirstLineIndent = &pTextNd->SwContentNode::GetAttr(RES_MARGIN_FIRSTLINE); + } + } } break; diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx index d29223050b..f9533b37f6 100644 --- a/sw/source/core/doc/doctxm.cxx +++ b/sw/source/core/doc/doctxm.cxx @@ -1375,7 +1375,8 @@ void SwTOXBaseSection::UpdateTemplate(const SwTextNode* pOwnChapterNode, pTextNd->getLayoutFrame(pLayout) && pTextNd->GetNodes().IsDocNodes() && // tdf#40142 - consider level settings of the various text nodes - o3tl::make_unsigned(pTextNd->GetAttrOutlineLevel()) <= GetLevel() && + (TOX_CONTENT != SwTOXBase::GetType() || + o3tl::make_unsigned(pTextNd->GetAttrOutlineLevel()) <= GetLevel()) && (!pLayout || !pLayout->HasMergedParas() || static_cast(pTextNd->getLayoutFrame(pLayout))->GetTextNodeForParaProps() == pTextNd) && (!IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pTextNd))) diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx index 3506dff230..850dc5a827 100644 --- a/sw/source/core/docnode/nodes.cxx +++ b/sw/source/core/docnode/nodes.cxx @@ -1862,7 +1862,7 @@ void SwNodes::CopyNodes( const SwNodeRange& rRange, // If the end of the section is outside the copy range, // the section node will skipped, not copied! // If someone want to change this behaviour, he has to adjust the function - // lcl_NonCopyCount(..) in ndcopy.cxx which relies on it. + // lcl_NonCopyCount() which relies on it. if( pCurrentNode->EndOfSectionIndex() < aRg.aEnd.GetIndex() ) { // copy of the whole section, so create a new SectionNode diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx index aac8f2393c..a91e92569f 100644 --- a/sw/source/core/draw/dcontact.cxx +++ b/sw/source/core/draw/dcontact.cxx @@ -170,12 +170,16 @@ SwRect GetBoundRectOfAnchoredObj( const SdrObject* pObj ) /// Returns the UserCall if applicable from the group object SwContact* GetUserCall( const SdrObject* pObj ) { - SdrObject *pTmp; - while ( !pObj->GetUserCall() && nullptr != (pTmp = pObj->getParentSdrObjectFromSdrObject()) ) - pObj = pTmp; - assert((!pObj->GetUserCall() || nullptr != dynamic_cast(pObj->GetUserCall())) && - "<::GetUserCall(..)> - wrong type of found object user call." ); - return static_cast(pObj->GetUserCall()); + for (; pObj; pObj = pObj->getParentSdrObjectFromSdrObject()) + { + if (auto pUserCall = pObj->GetUserCall()) + { + assert(dynamic_cast(pUserCall) + && "<::GetUserCall(..)> - wrong type of found object user call."); + return static_cast(pUserCall); + } + } + return nullptr; } /// Returns true if the SrdObject is a Marquee-Object (scrolling text) @@ -2216,8 +2220,9 @@ namespace sdr::contact void VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const { - // tdf#91260 have already checked top-level one is on the right page - assert(isPrimitiveVisible(rDisplayInfo)); + // this may be called for painting where it's a precondition that + // isPrimitiveVisible() is true, or for e.g. getObjectRange() (even + // during layout) where there are no preconditions... // nasty corner case: override to clear page frame to disable the // sub-objects' anchor check, because their anchor is always on // the first page that the page style is applied to diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx index fe0db61925..5499dad7c9 100644 --- a/sw/source/core/draw/dview.cxx +++ b/sw/source/core/draw/dview.cxx @@ -210,10 +210,14 @@ void SwDrawView::AddCustomHdl() { const SdrMarkList &rMrkList = GetMarkedObjectList(); - if(rMrkList.GetMarkCount() != 1 || !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj())) + if(rMrkList.GetMarkCount() != 1) return; SdrObject *pObj = rMrkList.GetMark(0)->GetMarkedSdrObj(); + SwContact* pContact = ::GetUserCall( pObj ); + if (!pContact) + return; + // make code robust SwFrameFormat* pFrameFormat( ::FindFrameFormat( pObj ) ); if ( !pFrameFormat ) @@ -236,7 +240,7 @@ void SwDrawView::AddCustomHdl() { // #i28701# - use last character rectangle saved at object // in order to avoid a format of the anchor frame - SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); + SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj ); // Invalidate/recalc LastCharRect which can contain invalid frame offset because // of later frame changes @@ -360,7 +364,8 @@ void SwDrawView::MoveRepeatedObjs( const SwAnchoredObject& _rMovedAnchoredObj, { const SwContact* pContact = ::GetUserCall( _rMovedAnchoredObj.GetDrawObj() ); assert(pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash."); - pContact->GetAnchoredObjs( aAnchoredObjs ); + if (pContact) + pContact->GetAnchoredObjs( aAnchoredObjs ); } // check, if 'repeated' objects exists. @@ -402,7 +407,8 @@ void SwDrawView::MoveRepeatedObjs( const SwAnchoredObject& _rMovedAnchoredObj, { const SwContact* pContact = ::GetUserCall( pChildObj ); assert(pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash."); - pContact->GetAnchoredObjs( aAnchoredObjs ); + if (pContact) + pContact->GetAnchoredObjs( aAnchoredObjs ); } // move 'repeated' ones to the same order number as the already moved one. const size_t nTmpNewPos = pChildObj->GetOrdNum(); @@ -449,8 +455,11 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, pDrawPage->RecalcObjOrdNums(); const size_t nObjCount = pDrawPage->GetObjCount(); - SwAnchoredObject* pMovedAnchoredObj = - ::GetUserCall( pObj )->GetAnchoredObj( pObj ); + SwContact* pContact = ::GetUserCall( pObj ); + if (!pContact) + return; + + SwAnchoredObject* pMovedAnchoredObj = pContact->GetAnchoredObj( pObj ); const SwFlyFrame* pParentAnchoredObj = pMovedAnchoredObj->GetAnchorFrame()->FindFlyFrame(); @@ -493,21 +502,22 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, if ( pTmpObj ) { size_t nTmpNewPos( nNewPos ); - if ( bMovedForward ) - { - // move before the top 'repeated' object - const sal_uInt32 nTmpMaxOrdNum = - ::GetUserCall( pTmpObj )->GetMaxOrdNum(); - if ( nTmpMaxOrdNum > nNewPos ) - nTmpNewPos = nTmpMaxOrdNum; - } - else + if (const SwContact* pContact2 = ::GetUserCall( pTmpObj )) { - // move behind the bottom 'repeated' object - const sal_uInt32 nTmpMinOrdNum = - ::GetUserCall( pTmpObj )->GetMinOrdNum(); - if ( nTmpMinOrdNum < nNewPos ) - nTmpNewPos = nTmpMinOrdNum; + if ( bMovedForward ) + { + // move before the top 'repeated' object + const sal_uInt32 nTmpMaxOrdNum = pContact2->GetMaxOrdNum(); + if ( nTmpMaxOrdNum > nNewPos ) + nTmpNewPos = nTmpMaxOrdNum; + } + else + { + // move behind the bottom 'repeated' object + const sal_uInt32 nTmpMinOrdNum = pContact2->GetMinOrdNum(); + if ( nTmpMinOrdNum < nNewPos ) + nTmpNewPos = nTmpMinOrdNum; + } } if ( nTmpNewPos != nNewPos ) { @@ -529,18 +539,25 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, { // determine position before the object before its top 'child' object const SdrObject* pTmpObj = pDrawPage->GetObj( nMaxChildOrdNum ); - size_t nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum() + 1; - if ( nTmpNewPos >= nObjCount ) + if (SwContact* pContact2 = ::GetUserCall( pTmpObj )) { - --nTmpNewPos; + size_t nTmpNewPos = pContact2->GetMaxOrdNum() + 1; + if ( nTmpNewPos >= nObjCount ) + { + --nTmpNewPos; + } + // assure, that determined position isn't between 'repeated' objects + pTmpObj = pDrawPage->GetObj( nTmpNewPos ); + pContact2 = ::GetUserCall( pTmpObj ); + if (pContact2) + { + nTmpNewPos = pContact2->GetMaxOrdNum(); + // apply new position + pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos ); + nNewPos = nTmpNewPos; + pDrawPage->RecalcObjOrdNums(); + } } - // assure, that determined position isn't between 'repeated' objects - pTmpObj = pDrawPage->GetObj( nTmpNewPos ); - nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum(); - // apply new position - pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos ); - nNewPos = nTmpNewPos; - pDrawPage->RecalcObjOrdNums(); } } @@ -564,16 +581,18 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, if ( pTmpParentObj && pTmpParentObj->GetFrameFormat() != pParentFrameFormat ) { - if ( bMovedForward ) + if (const SwContact* pContact2 = ::GetUserCall( pTmpObj )) { - nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum(); - pTmpObj = pDrawPage->GetObj( nTmpNewPos + 1 ); - } - else - { - nTmpNewPos = ::GetUserCall( pTmpParentObj->GetDrawObj() ) - ->GetMinOrdNum(); - pTmpObj = pTmpParentObj->GetDrawObj(); + if ( bMovedForward ) + { + nTmpNewPos = pContact2->GetMaxOrdNum(); + pTmpObj = pDrawPage->GetObj( nTmpNewPos + 1 ); + } + else + { + nTmpNewPos = pContact2->GetMinOrdNum(); + pTmpObj = pTmpParentObj->GetDrawObj(); + } } } else @@ -690,7 +709,7 @@ const SwFrame* SwDrawView::CalcAnchor() //Search for paragraph bound objects, otherwise only the //current anchor. Search only if we currently drag. - const SwFrame* pAnch; + const SwFrame* pAnch = nullptr; tools::Rectangle aMyRect; auto pFlyDrawObj = dynamic_cast( pObj ); if ( pFlyDrawObj ) @@ -700,16 +719,18 @@ const SwFrame* SwDrawView::CalcAnchor() } else { - SwDrawContact *pC = static_cast(GetUserCall(pObj)); // determine correct anchor position for 'virtual' drawing objects. // #i26791# - pAnch = pC->GetAnchorFrame( pObj ); - if( !pAnch ) + if (SwDrawContact* pContact = static_cast(GetUserCall(pObj))) { - pC->ConnectToLayout(); - // determine correct anchor position for 'virtual' drawing objects. - // #i26791# - pAnch = pC->GetAnchorFrame( pObj ); + pAnch = pContact->GetAnchorFrame( pObj ); + if( !pAnch ) + { + pContact->ConnectToLayout(); + // determine correct anchor position for 'virtual' drawing objects. + // #i26791# + pAnch = pContact->GetAnchorFrame( pObj ); + } } aMyRect = pObj->GetSnapRect(); } @@ -744,12 +765,14 @@ const SwFrame* SwDrawView::CalcAnchor() { const SwRect aRect( aPt.getX(), aPt.getY(), 1, 1 ); - SwDrawContact* pContact = static_cast(GetUserCall(pObj)); - if ( pContact->GetAnchorFrame( pObj ) && - pContact->GetAnchorFrame( pObj )->IsPageFrame() ) - pAnch = pContact->GetPageFrame(); - else - pAnch = pContact->FindPage( aRect ); + if (SwDrawContact* pContact = static_cast(GetUserCall(pObj))) + { + if ( pContact->GetAnchorFrame( pObj ) && + pContact->GetAnchorFrame( pObj )->IsPageFrame() ) + pAnch = pContact->GetPageFrame(); + else + pAnch = pContact->FindPage( aRect ); + } } } if( pAnch && !pAnch->IsProtected() ) diff --git a/sw/source/core/edit/autofmt.cxx b/sw/source/core/edit/autofmt.cxx index 6fafe1310d..2082fa3ae4 100644 --- a/sw/source/core/edit/autofmt.cxx +++ b/sw/source/core/edit/autofmt.cxx @@ -1710,7 +1710,7 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel ) const_cast(m_pCurTextFrame->GetTextNodeForParaProps())->SetAttrListLevel(nLvl); // start new list - m_pDoc->SetNumRule(m_aDelPam, aRule, true, m_pEditShell->GetLayout()); + m_pDoc->SetNumRule(m_aDelPam, aRule, SwDoc::SetNumRuleMode::CreateNewList, m_pEditShell->GetLayout()); m_aDelPam.DeleteMark(); *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0)); diff --git a/sw/source/core/edit/edglss.cxx b/sw/source/core/edit/edglss.cxx index 80310bab4f..b5dc871a6e 100644 --- a/sw/source/core/edit/edglss.cxx +++ b/sw/source/core/edit/edglss.cxx @@ -229,6 +229,14 @@ bool SwEditShell::CopySelToDoc( SwDoc& rInsDoc ) // but we want to copy the table and the start node before // the first cell as well. aPaM.Start()->Assign(*oSelectAll->first); + if (SwSectionNode const* pSection = oSelectAll->first->GetSectionNode()) + { + if (aPaM.End()->GetNodeIndex() < pSection->EndOfSectionIndex()) + { + // include section end so that section is copied + aPaM.End()->Assign(*oSelectAll->first->GetNodes()[pSection->EndOfSectionIndex() + 1]); + } + } } bRet = GetDoc()->getIDocumentContentOperations().CopyRange( aPaM, aPos, SwCopyFlags::CheckPosInFly) || bRet; diff --git a/sw/source/core/edit/ednumber.cxx b/sw/source/core/edit/ednumber.cxx index c272aa5f8e..65391d376b 100644 --- a/sw/source/core/edit/ednumber.cxx +++ b/sw/source/core/edit/ednumber.cxx @@ -355,7 +355,7 @@ void SwEditShell::SetIndent(short nIndent, const SwPosition & rPos) // change numbering rule - changed numbering rule is not applied at SwPaM aPaM(pos); - GetDoc()->SetNumRule(aPaM, aRule, false, GetLayout(), OUString(), false); + GetDoc()->SetNumRule(aPaM, aRule, SwDoc::SetNumRuleMode::DontSetItem, GetLayout(), OUString()); } EndAllAction(); @@ -751,8 +751,9 @@ void SwEditShell::SetCurNumRule( const SwNumRule& rRule, for (SwPaM& rPaM : pCursor->GetRingContainer()) { OUString sListId = GetDoc()->SetNumRule(rPaM, rRule, - bCreateNewList, GetLayout(), sContinuedListId, - true, bResetIndentAttrs ); + (bCreateNewList ? SwDoc::SetNumRuleMode::CreateNewList : SwDoc::SetNumRuleMode::Default) + | (bResetIndentAttrs ? SwDoc::SetNumRuleMode::ResetIndentAttrs : SwDoc::SetNumRuleMode::Default), + GetLayout(), sContinuedListId); //tdf#87548 On creating a new list for a multi-selection only //create a single new list for the multi-selection, not one per selection @@ -768,8 +769,9 @@ void SwEditShell::SetCurNumRule( const SwNumRule& rRule, else { GetDoc()->SetNumRule( *pCursor, rRule, - bCreateNewList, GetLayout(), rContinuedListId, - true, bResetIndentAttrs ); + (bCreateNewList ? SwDoc::SetNumRuleMode::CreateNewList : SwDoc::SetNumRuleMode::Default) + | (bResetIndentAttrs ? SwDoc::SetNumRuleMode::ResetIndentAttrs : SwDoc::SetNumRuleMode::Default), + GetLayout(), rContinuedListId); GetDoc()->SetCounted( *pCursor, true, GetLayout() ); } GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSATTR, nullptr ); diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx index b3fab811f1..69f08a4eab 100644 --- a/sw/source/core/fields/fldbas.cxx +++ b/sw/source/core/fields/fldbas.cxx @@ -48,13 +48,12 @@ using namespace ::com::sun::star; using namespace nsSwDocInfoSubType; -static LanguageType lcl_GetLanguageOfFormat( LanguageType nLng, sal_uLong nFormat, - const SvNumberFormatter& rFormatter ) +static LanguageType lcl_GetLanguageOfFormat(LanguageType nLng, sal_uLong nFormat) { if( nLng == LANGUAGE_NONE ) // Bug #60010 nLng = LANGUAGE_SYSTEM; else if( nLng == ::GetAppLanguage() ) - switch( rFormatter.GetIndexTableOffset( nFormat )) + switch( SvNumberFormatter::GetIndexTableOffset( nFormat )) { case NF_NUMBER_SYSTEM: case NF_DATE_SYSTEM_SHORT: @@ -583,7 +582,7 @@ OUString SwValueFieldType::ExpandValue( const double& rVal, const Color* pCol = nullptr; // Bug #60010 - LanguageType nFormatLng = ::lcl_GetLanguageOfFormat( nLng, nFormat, *pFormatter ); + LanguageType nFormatLng = ::lcl_GetLanguageOfFormat( nLng, nFormat ); if( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && LANGUAGE_SYSTEM != nFormatLng ) { @@ -752,8 +751,7 @@ void SwValueField::SetLanguage( LanguageType nLng ) { // Bug #60010 SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); - LanguageType nFormatLng = ::lcl_GetLanguageOfFormat( nLng, GetFormat(), - *pFormatter ); + LanguageType nFormatLng = ::lcl_GetLanguageOfFormat( nLng, GetFormat() ); if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET || LANGUAGE_SYSTEM != nFormatLng ) && diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx index 0ee26771bb..85a18c7892 100644 --- a/sw/source/core/fields/reffld.cxx +++ b/sw/source/core/fields/reffld.cxx @@ -1220,7 +1220,9 @@ namespace /// Picks the first text node with a matching style from a double ended queue, starting at the front /// This allows us to use the deque either as a stack or as a queue depending on whether we want to search up or down SwTextNode* SearchForStyleAnchor(SwTextNode* pSelf, const std::deque& pToSearch, - std::u16string_view rStyleName, bool bCaseSensitive = true) + std::u16string_view rStyleName, + sal_Int32 *const pStart, sal_Int32 *const pEnd, + bool bCaseSensitive = true) { std::deque pSearching(pToSearch); while (!pSearching.empty()) @@ -1235,15 +1237,38 @@ namespace if (!pTextNode) continue; - if (bCaseSensitive) + if (bCaseSensitive + ? pTextNode->GetFormatColl()->GetName() == rStyleName + : pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName)) { - if (pTextNode->GetFormatColl()->GetName() == rStyleName) - return pTextNode; + *pStart = 0; + if (pEnd) + { + *pEnd = pTextNode->GetText().getLength(); + } + return pTextNode; } - else + + if (auto const pHints = pTextNode->GetpSwpHints()) { - if (pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName)) - return pTextNode; + for (size_t i = 0; i < pHints->Count(); ++i) + { + auto const*const pHint(pHints->Get(i)); + if (pHint->Which() == RES_TXTATR_CHARFMT) + { + if (bCaseSensitive + ? pHint->GetCharFormat().GetCharFormat()->HasName(rStyleName) + : pHint->GetCharFormat().GetCharFormat()->GetName().equalsIgnoreAsciiCase(rStyleName)) + { + *pStart = pHint->GetStart(); + if (pEnd) + { + *pEnd = *pHint->End(); + } + return pTextNode; + } + } + } } } @@ -1505,21 +1530,21 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark, pSearchThird.push_back(nodes[n]); } - pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark); + pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark, pStt, pEnd); if (pTextNd) { break; } // 2. Search up from the top of the page - pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark); + pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, pStt, pEnd); if (pTextNd) { break; } // 3. Search down from the bottom of the page - pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, rRefMark); + pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, rRefMark, pStt, pEnd); if (pTextNd) { break; @@ -1528,21 +1553,21 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark, // Word has case insensitive styles. LO has case sensitive styles. If we didn't find // it yet, maybe we could with a case insensitive search. Let's do that - pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark, + pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark, pStt, pEnd, false /* bCaseSensitive */); if (pTextNd) { break; } - pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, + pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, pStt, pEnd, false /* bCaseSensitive */); if (pTextNd) { break; } - pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, rRefMark, + pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, rRefMark, pStt, pEnd, false /* bCaseSensitive */); break; } @@ -1574,7 +1599,7 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark, // 1. Search up until we hit the top of the document - pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, rRefMark); + pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, rRefMark, pStt, pEnd); if (pTextNd) { break; @@ -1582,7 +1607,7 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark, // 2. Search down until we hit the bottom of the document - pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark); + pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, pStt, pEnd); if (pTextNd) { break; @@ -1590,14 +1615,14 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark, // Again, we need to remember that Word styles are not case sensitive - pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, rRefMark, + pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, rRefMark, pStt, pEnd, false /* bCaseSensitive */); if (pTextNd) { break; } - pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, + pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, pStt, pEnd, false /* bCaseSensitive */); break; } @@ -1605,13 +1630,6 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark, OSL_FAIL(" - unknown getref element type"); } - if (pTextNd) - { - *pStt = 0; - if (pEnd) - *pEnd = pTextNd->GetText().getLength(); - } - break; } diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx index 1d8b0ef680..01eee5072f 100644 --- a/sw/source/core/frmedt/fecopy.cxx +++ b/sw/source/core/frmedt/fecopy.cxx @@ -195,18 +195,20 @@ void SwFEShell::Copy( SwDoc& rClpDoc, const OUString* pNewClpText ) } else { - SwDrawContact *pContact = static_cast(GetUserCall( pObj )); - SwFrameFormat *pFormat = pContact->GetFormat(); - SwFormatAnchor aAnchor( pFormat->GetAnchor() ); - if ((RndStdIds::FLY_AT_PARA == aAnchor.GetAnchorId()) || - (RndStdIds::FLY_AT_CHAR == aAnchor.GetAnchorId()) || - (RndStdIds::FLY_AT_FLY == aAnchor.GetAnchorId()) || - (RndStdIds::FLY_AS_CHAR == aAnchor.GetAnchorId())) + if (SwDrawContact *pContact = static_cast(GetUserCall( pObj ))) { - aAnchor.SetAnchor( &aPos ); - } + SwFrameFormat *pFormat = pContact->GetFormat(); + SwFormatAnchor aAnchor( pFormat->GetAnchor() ); + if ((RndStdIds::FLY_AT_PARA == aAnchor.GetAnchorId()) || + (RndStdIds::FLY_AT_CHAR == aAnchor.GetAnchorId()) || + (RndStdIds::FLY_AT_FLY == aAnchor.GetAnchorId()) || + (RndStdIds::FLY_AS_CHAR == aAnchor.GetAnchorId())) + { + aAnchor.SetAnchor( &aPos ); + } - rClpDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, true, true ); + rClpDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, true, true ); + } } } } @@ -297,6 +299,9 @@ bool SwFEShell::CopyDrawSel( SwFEShell& rDestShell, const Point& rSttPt, SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj(); SwDrawContact *pContact = static_cast(GetUserCall( pObj )); + if (!pContact) + continue; + SwFrameFormat *pFormat = pContact->GetFormat(); const SwFormatAnchor& rAnchor = pFormat->GetAnchor(); @@ -1088,9 +1093,24 @@ bool SwFEShell::Paste(SwDoc& rClpDoc, bool bNestedTable) --aIndexBefore; + // copying to the clipboard, the section is inserted + // at the start of the nodes, followed by empty text node + bool const isSourceSection(aCpyPam.Start()->GetNode().IsSectionNode() + && aCpyPam.End()->GetNodeIndex() == aCpyPam.Start()->GetNode().EndOfSectionIndex() + 1 + && aCpyPam.End()->GetNode().IsTextNode() + && aCpyPam.End()->GetNode().GetTextNode()->Len() == 0); + rClpDoc.getIDocumentContentOperations().CopyRange(aCpyPam, rInsPos, SwCopyFlags::CheckPosInFly); // Note: aCpyPam is invalid now + if (isSourceSection + && aIndexBefore.GetNode().IsStartNode() + && rInsPos.GetNode().GetTextNode()->Len() == 0) + { // if there is an empty text node at the start, it + // should be *replaced* by the section, so delete it + GetDoc()->getIDocumentContentOperations().DelFullPara(rPaM); + } + ++aIndexBefore; SwPaM aPaM(aIndexBefore.GetNode(), rInsPos.GetNode()); diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx index 93ad4212cf..d6ff8b2969 100644 --- a/sw/source/core/frmedt/fefly1.cxx +++ b/sw/source/core/frmedt/fefly1.cxx @@ -382,11 +382,13 @@ const SwFrameFormat* SwFEShell::IsFlyInFly() return nullptr; return pFly->GetFormat(); } - else if ( rMrkList.GetMarkCount() != 1 || - !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) ) + else if ( rMrkList.GetMarkCount() != 1 ) return nullptr; SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); + SwContact* pContact = GetUserCall( pObj ); + if (!pContact) + return nullptr; SwFrameFormat *pFormat = FindFrameFormat( pObj ); if( pFormat && RndStdIds::FLY_AT_FLY == pFormat->GetAnchor().GetAnchorId() ) @@ -398,7 +400,7 @@ const SwFrameFormat* SwFEShell::IsFlyInFly() } else { - pFly = static_cast(GetUserCall(pObj))->GetAnchorFrame(pObj); + pFly = static_cast(pContact)->GetAnchorFrame(pObj); } OSL_ENSURE( pFly, "IsFlyInFly: Where's my anchor?" ); @@ -491,11 +493,12 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) SdrObject* pObj = rMrkList.GetMark(0)->GetMarkedSdrObj(); - if (!GetUserCall(pObj)) + SwContact* pContact = ::GetUserCall( pObj ); + if (!pContact) return aRet; // #i28701# - SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); + SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj ); SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); const RndStdIds nAnchorId = pFormat->GetAnchor().GetAnchorId(); @@ -890,6 +893,43 @@ const SwFrameFormat *SwFEShell::NewFlyFrame( const SfxItemSet& rSet, bool bAnchV return pRet; } +namespace +{ +/// If pCursor points to an as-char anchored graphic node, then set the node's anchor position on +/// pAnchor and rPam. +bool SetAnchorOnGrfNodeForAsChar(SwShellCursor *pCursor, SwFormatAnchor* pAnchor, std::optional& rPam) +{ + const SwPosition* pPoint = pCursor->GetPoint(); + if (pAnchor->GetAnchorId() != RndStdIds::FLY_AS_CHAR) + { + return false; + } + + if (!pPoint->GetNode().IsGrfNode()) + { + return false; + } + + SwFrameFormat* pFrameFormat = pPoint->GetNode().GetFlyFormat(); + if (!pFrameFormat) + { + return false; + } + + const SwPosition* pContentAnchor = pFrameFormat->GetAnchor().GetContentAnchor(); + if (!pContentAnchor) + { + return false; + } + + SwPosition aPosition(*pContentAnchor); + ++aPosition.nContent; + pAnchor->SetAnchor(&aPosition); + rPam.emplace(aPosition); + return true; +} +} + void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName, const Graphic* pGraphic, const SfxItemSet* pFlyAttrSet ) @@ -905,6 +945,7 @@ void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName, break; // Has the anchor not been set or been set incompletely? + std::optional oPam; if( pFlyAttrSet ) { if( const SwFormatAnchor* pItem = pFlyAttrSet->GetItemIfSet( RES_ANCHOR, false ) ) @@ -917,6 +958,13 @@ void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName, case RndStdIds::FLY_AS_CHAR: if( !pAnchor->GetAnchorNode() ) { + if (SetAnchorOnGrfNodeForAsChar(pCursor, pAnchor, oPam)) + { + // Don't anchor the image on the previous image, rather insert them next + // to each other. + break; + } + pAnchor->SetAnchor( pCursor->GetPoint() ); } break; @@ -940,7 +988,7 @@ void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName, } } pFormat = GetDoc()->getIDocumentContentOperations().InsertGraphic( - *pCursor, rGrfName, + oPam.has_value() ? *oPam : *pCursor, rGrfName, rFltName, pGraphic, pFlyAttrSet, nullptr, nullptr ); diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx index 9154758364..353cb5214e 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -376,22 +377,27 @@ bool SwFEShell::MoveAnchor( SwMove nDir ) const SdrMarkList& pMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); if (1 != pMrkList.GetMarkCount()) return false; + + SdrObject *pObj = pMrkList.GetMark( 0 )->GetMarkedSdrObj(); + SwDrawContact* pContact = static_cast(GetUserCall(pObj)); + if (!pContact) + return false; + SwFrame* pOld; SwFlyFrame* pFly = nullptr; - SdrObject *pObj = pMrkList.GetMark( 0 )->GetMarkedSdrObj(); if (SwVirtFlyDrawObj* pVirtO = dynamic_cast(pObj)) { pFly = pVirtO->GetFlyFrame(); pOld = pFly->AnchorFrame(); } else - pOld = static_cast(GetUserCall(pObj))->GetAnchorFrame( pObj ); + pOld = pContact->GetAnchorFrame( pObj ); bool bRet = false; if( pOld ) { SwFrame* pNew = pOld; // #i28701# - SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); + SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj ); SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); SwFormatAnchor aAnch( pFormat->GetAnchor() ); RndStdIds nAnchorId = aAnch.GetAnchorId(); @@ -874,7 +880,11 @@ static void lcl_NotifyNeighbours( const SdrMarkList *pLst ) } else { - SwFrame* pAnch = static_cast( GetUserCall(pO) )->GetAnchorFrame( pO ); + SwDrawContact* pContact = static_cast(GetUserCall(pO)); + if (!pContact) + continue; + + SwFrame* pAnch = pContact->GetAnchorFrame( pO ); if( !pAnch ) continue; pPage = pAnch->FindPageFrame(); @@ -1316,12 +1326,15 @@ bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) { if ( pObj->GetLayer() == rIDDMA.GetHellId() ) { - const SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); - const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); - const SwFormatSurround& rSurround = pFormat->GetSurround(); - if ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH ) + if (const SwContact* pContact = ::GetUserCall( pObj )) { - bObjInBackground = true; + const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj ); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rSurround = pFormat->GetSurround(); + if ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH ) + { + bObjInBackground = true; + } } } } @@ -1392,6 +1405,27 @@ bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) } } } + + // within table row, where image cropped by the fixed table row height, + // click position must be in the cell, where the image anchored as character + if ( bRet && pContact && pContact->ObjAnchoredAsChar() ) + { + if ( const SwTableBox *pBox = pContact->GetAnchorNode().GetTableBox() ) + { + SwIterator aIter( *pBox->GetUpper()->GetFrameFormat() ); + bool bContainsClickPosition = false; + for (SwRowFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next()) + { + if ( pFrame->getFrameArea().Contains( rPt ) ) + { + bContainsClickPosition = true; + break; + } + } + if ( !bContainsClickPosition ) + bRet = false; + } + } } } @@ -2330,7 +2364,7 @@ bool SwFEShell::IsGroupSelected(bool bAllowDiagams) // Thus, use corresponding method instead of checking type. if ( pObj->IsGroupObject() && // --> #i38505# No ungroup allowed for 3d objects - !pObj->Is3DObj() && + !pObj->Is3DObj() && GetUserCall(pObj) && RndStdIds::FLY_AS_CHAR != static_cast(GetUserCall(pObj))-> GetFormat()->GetAnchor().GetAnchorId() ) { @@ -2659,7 +2693,6 @@ bool SwFEShell::GetObjAttr( SfxItemSet &rSet ) const { SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); SwDrawContact *pContact = static_cast(GetUserCall(pObj)); - // --> make code robust OSL_ENSURE( pContact, " - missing ." ); if ( pContact ) { @@ -2689,8 +2722,8 @@ void SwFEShell::SetObjAttr( const SfxItemSet& rSet ) for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i ) { SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); - SwDrawContact *pContact = static_cast(GetUserCall(pObj)); - GetDoc()->SetAttr( rSet, *pContact->GetFormat() ); + if (SwDrawContact *pContact = static_cast(GetUserCall(pObj))) + GetDoc()->SetAttr( rSet, *pContact->GetFormat() ); } EndUndo( SwUndoId::INSATTR ); diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx index 3e5be92c64..6599c9bf2a 100644 --- a/sw/source/core/inc/DocumentSettingManager.hxx +++ b/sw/source/core/inc/DocumentSettingManager.hxx @@ -178,6 +178,8 @@ class DocumentSettingManager final : bool mbDoNotBreakWrappedTables = false; bool mbAllowTextAfterFloatingTableBreak = false; bool mbJustifyLinesWithShrinking = false; + bool mbApplyTextAttrToEmptyLineAtEndOfParagraph = true; + bool mbDoNotMirrorRtlDrawObjs = false; // If this is on as_char flys wrapping will be handled the same like in Word bool mbNoNumberingShowFollowBy; bool mbDropCapPunctuation; // tdf#150200, tdf#150438 diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 604488a18c..a863585081 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -948,6 +948,9 @@ public: virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const; void dumpChildrenAsXml(xmlTextWriterPtr writer) const; bool IsCollapse() const; + + /// Determines if the upper margin of this frame should be ignored. + bool IsCollapseUpper() const; }; inline bool SwFrame::IsInDocBody() const diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx index 69158b3358..3debf367f0 100644 --- a/sw/source/core/inc/sectfrm.hxx +++ b/sw/source/core/inc/sectfrm.hxx @@ -46,7 +46,7 @@ namespace o3tl { template<> struct typed_flags : is_typed_flags {}; } -class SwSectionFrame final: public SwLayoutFrame, public SwFlowFrame +class SW_DLLPUBLIC SwSectionFrame final: public SwLayoutFrame, public SwFlowFrame , public SvtListener // TODO? { SwSection* m_pSection; diff --git a/sw/source/core/layout/anchoreddrawobject.cxx b/sw/source/core/layout/anchoreddrawobject.cxx index 5a9e1245af..fe01bbc3b3 100644 --- a/sw/source/core/layout/anchoreddrawobject.cxx +++ b/sw/source/core/layout/anchoreddrawobject.cxx @@ -266,6 +266,8 @@ void SwAnchoredDrawObject::MakeObjPos() SwDrawContact* pDrawContact = static_cast(::GetUserCall( GetDrawObj() )); + if (!pDrawContact) + return; // --> #i28749# - if anchored drawing object hasn't been yet // positioned, convert its positioning attributes, if its positioning @@ -849,6 +851,8 @@ void SwAnchoredDrawObject::SetPositioningAttr() { SwDrawContact* pDrawContact = static_cast(GetUserCall( GetDrawObj() )); + if (!pDrawContact) + return; SwFrameFormat* pObjFormat = GetFrameFormat(); if ( !pDrawContact->ObjAnchoredAsChar() ) diff --git a/sw/source/core/layout/anchoredobject.cxx b/sw/source/core/layout/anchoredobject.cxx index a74438afb3..43c5baa396 100644 --- a/sw/source/core/layout/anchoredobject.cxx +++ b/sw/source/core/layout/anchoredobject.cxx @@ -44,10 +44,13 @@ SwObjPositioningInProgress::SwObjPositioningInProgress( SdrObject& _rSdrObj ) : // --> #i52904# mbOldObjPositioningInProgress( false ) { - mpAnchoredObj = ::GetUserCall( &_rSdrObj )->GetAnchoredObj( &_rSdrObj ); - // --> #i52904# - mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress(); - mpAnchoredObj->SetPositioningInProgress( true ); + if (SwContact* pContact = ::GetUserCall( &_rSdrObj )) + { + mpAnchoredObj = pContact->GetAnchoredObj( &_rSdrObj ); + // --> #i52904# + mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress(); + mpAnchoredObj->SetPositioningInProgress( true ); + } } SwObjPositioningInProgress::SwObjPositioningInProgress( SwAnchoredObject& _rAnchoredObj ) : mpAnchoredObj( &_rAnchoredObj ), diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index e13fdf0121..f358d74af0 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -1076,6 +1076,44 @@ bool SwFrame::IsCollapse() const return pTextFrame->GetText().isEmpty() && pTextNode && pTextNode->IsCollapse(); } +bool SwFrame::IsCollapseUpper() const +{ + const SwTextFrame* pTextFrame = DynCastTextFrame(); + if (!pTextFrame) + { + return false; + } + + const SwDoc& rDoc = pTextFrame->GetDoc(); + const IDocumentSettingAccess& rIDSA = rDoc.getIDocumentSettingAccess(); + if (!rIDSA.get(DocumentSettingId::TAB_OVER_SPACING) || rIDSA.get(DocumentSettingId::TAB_OVER_MARGIN)) + { + // Writer or Word Word <= 2010 style: upper margin is never ignored. + return false; + } + + if (IsInFly()) + { + // Not in a page's body. + return false; + } + + // Word >= 2013 style: when we're at the top of the page's body, but not on the first page, then + // ignore the upper margin for paragraphs. + if (GetPrev() || !GetUpper() || !GetUpper()->IsBodyFrame()) + { + return false; + } + + const SwPageFrame* pPageFrame = FindPageFrame(); + if (!pPageFrame || !pPageFrame->GetPrev()) + { + return false; + } + + return true; +} + void SwContentFrame::MakePrtArea( const SwBorderAttrs &rAttrs ) { if ( isFramePrintAreaValid() ) diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index 88158161c5..37fd20b323 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -1658,6 +1658,11 @@ SwTwips SwFlowFrame::CalcUpperSpace( const SwBorderAttrs *pAttrs, CastFlowFrame( pOwn )->HasParaSpaceAtPages( m_rThis.IsSctFrame() ) ) { nUpper = pAttrs->GetULSpace().GetUpper(); + + if (m_rThis.IsCollapseUpper()) + { + nUpper = 0; + } } } diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index db50a42de0..b454bd9591 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -2528,8 +2528,8 @@ void SwFrame::AppendDrawObj( SwAnchoredObject& _rNewObj ) assert(!m_pDrawObjs || m_pDrawObjs->is_sorted()); // perform disconnect from layout, if 'master' drawing object is appended // to a new frame. - static_cast(::GetUserCall( _rNewObj.GetDrawObj() ))-> - DisconnectFromLayout( false ); + if (SwDrawContact* pContact = static_cast(::GetUserCall( _rNewObj.GetDrawObj() ))) + pContact->DisconnectFromLayout( false ); assert(!m_pDrawObjs || m_pDrawObjs->is_sorted()); } diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx index 7ac95d65e0..b0ef08a01f 100644 --- a/sw/source/core/layout/flylay.cxx +++ b/sw/source/core/layout/flylay.cxx @@ -1430,27 +1430,30 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove ) } tools::Long nHeight = (9*aRectFnSet.GetHeight(rRect))/10; tools::Long nTop; - const SwFormat *pFormat = GetUserCall(pSdrObj)->GetFormat(); - const SvxULSpaceItem &rUL = pFormat->GetULSpace(); - if( bMove ) + if (const SwContact* pContact = ::GetUserCall( pSdrObj )) { - nTop = aRectFnSet.IsVert() ? static_cast(pFly)->GetRefPoint().X() : - static_cast(pFly)->GetRefPoint().Y(); - nTop = aRectFnSet.YInc( nTop, -nHeight ); - tools::Long nWidth = aRectFnSet.GetWidth(pFly->getFrameArea()); - aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ? - static_cast(pFly)->GetRefPoint().Y() : - static_cast(pFly)->GetRefPoint().X(), nWidth ); - nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper(); - } - else - { - nTop = aRectFnSet.YInc( aRectFnSet.GetBottom(pFly->getFrameArea()), - rUL.GetLower() - nHeight ); - nHeight = 2*nHeight - aRectFnSet.GetHeight(pFly->getFrameArea()) - - rUL.GetLower() - rUL.GetUpper(); + const SwFormat *pFormat = pContact->GetFormat(); + const SvxULSpaceItem &rUL = pFormat->GetULSpace(); + if( bMove ) + { + nTop = aRectFnSet.IsVert() ? static_cast(pFly)->GetRefPoint().X() : + static_cast(pFly)->GetRefPoint().Y(); + nTop = aRectFnSet.YInc( nTop, -nHeight ); + tools::Long nWidth = aRectFnSet.GetWidth(pFly->getFrameArea()); + aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ? + static_cast(pFly)->GetRefPoint().Y() : + static_cast(pFly)->GetRefPoint().X(), nWidth ); + nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper(); + } + else + { + nTop = aRectFnSet.YInc( aRectFnSet.GetBottom(pFly->getFrameArea()), + rUL.GetLower() - nHeight ); + nHeight = 2*nHeight - aRectFnSet.GetHeight(pFly->getFrameArea()) + - rUL.GetLower() - rUL.GetUpper(); + } + aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight ); } - aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight ); } } else diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index baf632d6eb..38667bd5c4 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -297,6 +297,8 @@ void SwFrameNotify::ImplDestroy() bool bNotify = false; bool bNotifySize = false; SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() ); + if (!pContact) + continue; const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar(); if ( !bAnchoredAsChar ) { @@ -1067,22 +1069,23 @@ void AppendObj(SwFrame *const pFrame, SwPageFrame *const pPage, SwFrameFormat *c InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect()); } - SwDrawContact* pNew = - static_cast(GetUserCall( pSdrObj )); - if ( !pNew->GetAnchorFrame() ) - { - pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( nullptr )) ); - } - // OD 19.06.2003 #108784# - add 'virtual' drawing object, - // if necessary. But control objects have to be excluded. - else if ( !::CheckControlLayer( pSdrObj ) && - pNew->GetAnchorFrame() != pFrame && - !pNew->GetDrawObjectByAnchorFrame( *pFrame ) ) + if (SwDrawContact* pNew = static_cast(GetUserCall( pSdrObj ))) { - SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj(*pFrame); - pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) ); + if ( !pNew->GetAnchorFrame() ) + { + pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( nullptr )) ); + } + // OD 19.06.2003 #108784# - add 'virtual' drawing object, + // if necessary. But control objects have to be excluded. + else if ( !::CheckControlLayer( pSdrObj ) && + pNew->GetAnchorFrame() != pFrame && + !pNew->GetDrawObjectByAnchorFrame( *pFrame ) ) + { + SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj(*pFrame); + pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) ); - pDrawVirtObj->ActionChanged(); + pDrawVirtObj->ActionChanged(); + } } } else @@ -3598,8 +3601,13 @@ bool Is_Lower_Of(const SwFrame *pCurrFrame, const SdrObject* pObj) } else { - pFrame = static_cast(GetUserCall(pObj))->GetAnchorFrame(pObj); - aPos = pObj->GetCurrentBoundRect().TopLeft(); + if (SwDrawContact* pC = static_cast(GetUserCall(pObj))) + { + pFrame = pC->GetAnchorFrame(pObj); + aPos = pObj->GetCurrentBoundRect().TopLeft(); + } + else + return false; } OSL_ENSURE( pFrame, "8-( Fly is lost in Space." ); pFrame = GetVirtualUpper( pFrame, aPos ); diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx index 1a0a1260a1..ad437f9852 100644 --- a/sw/source/core/layout/layact.cxx +++ b/sw/source/core/layout/layact.cxx @@ -1439,9 +1439,9 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrame *pLa PopFormatLayout(); } } - else if (pLay->IsSctFrame() && pLow->IsTextFrame() && pLow == pLay->GetLastLower()) + else if (pLay->IsSctFrame() && pLay->GetNext() && pLay->GetNext()->IsSctFrame() && pLow->IsTextFrame() && pLow == pLay->GetLastLower()) { - // else: only calc the last text lower of sections + // else: only calc the last text lower of sections, followed by sections pLow->OptCalc(); } diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx index f8c029ea12..2575c98278 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -445,22 +446,21 @@ static void lcl_MakeObjs(const sw::FrameFormats& rSpzs, SwP if ( bSdrObj ) { // OD 23.06.2003 #108784# - consider 'virtual' drawing objects - SwDrawContact *pContact = - static_cast(::GetUserCall(pSdrObj)); - if ( auto pDrawVirtObj = dynamic_cast( pSdrObj ) ) + if (SwDrawContact *pContact = + static_cast(::GetUserCall(pSdrObj))) { - if ( pContact ) + if ( auto pDrawVirtObj = dynamic_cast( pSdrObj ) ) { pDrawVirtObj->RemoveFromWriterLayout(); pDrawVirtObj->RemoveFromDrawingPage(); pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pDrawVirtObj )) ); } - } - else - { - if ( pContact->GetAnchorFrame() ) - pContact->DisconnectFromLayout( false ); - pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) ); + else + { + if ( pContact->GetAnchorFrame() ) + pContact->DisconnectFromLayout( false ); + pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) ); + } } } else @@ -790,8 +790,11 @@ SwPageDesc *SwPageFrame::FindPageDesc() } SwContentFrame* pFirstContent = FindFirstBodyContent(); - while (pFirstContent && pFirstContent->IsHiddenNow()) + while (pFirstContent && pFirstContent->IsInSct() + && pFirstContent->FindSctFrame()->IsHiddenNow()) + { pFirstContent = pFirstContent->GetNextContentFrame(); + } SwFrame* pFlow = pFirstContent; if ( pFlow && pFlow->IsInTab() ) pFlow = pFlow->FindTabFrame(); diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index 89a5f03302..0e3d135706 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -70,26 +70,29 @@ namespace { { const SwVirtFlyDrawObj* pObj = static_cast(aIter()); - const SwAnchoredObject* pAnchoredObj = GetUserCall( aIter() )->GetAnchoredObj( aIter() ); - const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); - const SwFormatSurround& rSurround = pObjFormat->GetSurround(); - const SvxOpaqueItem& rOpaque = pObjFormat->GetOpaque(); - bool bInBackground = ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH ) && !rOpaque.GetValue(); - - bool bBackgroundMatches = bInBackground == bSearchBackground; - - const SwFlyFrame* pFly = pObj ? pObj->GetFlyFrame() : nullptr; - if ( pFly && bBackgroundMatches && - ( ( pCMS && pCMS->m_bSetInReadOnly ) || - !pFly->IsProtected() ) && - pFly->GetModelPositionForViewPoint( pPos, aPoint, pCMS ) ) + if (const SwContact* pContact = ::GetUserCall( aIter() )) { - bRet = true; - break; - } + const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( aIter() ); + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rSurround = pObjFormat->GetSurround(); + const SvxOpaqueItem& rOpaque = pObjFormat->GetOpaque(); + bool bInBackground = ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH ) && !rOpaque.GetValue(); + + bool bBackgroundMatches = bInBackground == bSearchBackground; + + const SwFlyFrame* pFly = pObj ? pObj->GetFlyFrame() : nullptr; + if ( pFly && bBackgroundMatches && + ( ( pCMS && pCMS->m_bSetInReadOnly ) || + !pFly->IsProtected() ) && + pFly->GetModelPositionForViewPoint( pPos, aPoint, pCMS ) ) + { + bRet = true; + break; + } - if ( pCMS && pCMS->m_bStop ) - return false; + if ( pCMS && pCMS->m_bStop ) + return false; + } aIter.Prev(); } return bRet; diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx b/sw/source/core/objectpositioning/anchoredobjectposition.cxx index ab35ae7af7..4af3af542b 100644 --- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx +++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx @@ -852,7 +852,10 @@ SwTwips SwAnchoredObjectPosition::CalcRelPosX( if ( _rHoriOrient.GetHoriOrient() == text::HoriOrientation::NONE ) { // 'manual' horizontal position - const bool bR2L = rAnchorFrame.IsRightToLeft(); + const IDocumentSettingAccess& rIDSA = mpFrameFormat->getIDocumentSettingAccess(); + // If compat flag is active, then disable automatic mirroring for RTL. + bool bMirrorRtlDrawObjs = !rIDSA.get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS); + const bool bR2L = rAnchorFrame.IsRightToLeft() && bMirrorRtlDrawObjs; if( IsAnchoredToChar() && text::RelOrientation::CHAR == eRelOrient ) { if( bR2L ) diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx index 2ddaee7b2e..cb11d02b1e 100644 --- a/sw/source/core/text/inftxt.hxx +++ b/sw/source/core/text/inftxt.hxx @@ -71,8 +71,8 @@ class SwLineInfo void CtorInitLineInfo( const SwAttrSet& rAttrSet, const SwTextNode& rTextNode ); - SwLineInfo(); - ~SwLineInfo(); + SW_DLLPUBLIC SwLineInfo(); + SW_DLLPUBLIC ~SwLineInfo(); public: // #i24363# tab stops relative to indent - returns the tab stop following nSearchPos or NULL const SvxTabStop* GetTabStop(const SwTwips nSearchPos, SwTwips& nRight) const; @@ -183,7 +183,7 @@ public: SwTextSizeInfo( const SwTextSizeInfo &rInf ); SwTextSizeInfo( const SwTextSizeInfo &rInf, const OUString* pText, TextFrameIndex nIdx = TextFrameIndex(0) ); - SwTextSizeInfo(SwTextFrame *pTextFrame, TextFrameIndex nIndex = TextFrameIndex(0)); + SW_DLLPUBLIC SwTextSizeInfo(SwTextFrame *pTextFrame, TextFrameIndex nIndex = TextFrameIndex(0)); // GetMultiAttr returns the text attribute of the multiportion, // if rPos is inside any multi-line part. diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx index eb15400cf5..9a5f0b3f01 100644 --- a/sw/source/core/text/itratr.hxx +++ b/sw/source/core/text/itratr.hxx @@ -29,7 +29,7 @@ class SwRedlineItr; class SwViewShell; class SwTextFrame; -class SwAttrIter +class SW_DLLPUBLIC SwAttrIter { friend class SwFontSave; protected: diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 6623000c33..dad32bf4fc 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -852,6 +852,7 @@ void SwTextFormatter::CalcAscent( SwTextFormatInfo &rInf, SwLinePortion *pPor ) // In empty lines the attributes are switched on via SeekStart const bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx(); + if ( pPor->IsQuoVadisPortion() ) bChg = SeekStartAndChg( rInf, true ); else @@ -860,10 +861,16 @@ void SwTextFormatter::CalcAscent( SwTextFormatInfo &rInf, SwLinePortion *pPor ) { if( !rInf.GetText().isEmpty() ) { - if ( pPor->GetLen() || !rInf.GetIdx() - || ( m_pCurr != pLast && !pLast->IsFlyPortion() ) - || !m_pCurr->IsRest() ) // instead of !rInf.GetRest() + if ((rInf.GetIdx() != TextFrameIndex(rInf.GetText().getLength()) + || rInf.GetRest() // field continued - not empty + || !GetTextFrame()->GetDoc().getIDocumentSettingAccess().get( + DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH)) + && (pPor->GetLen() || !rInf.GetIdx() + || (m_pCurr != pLast && !pLast->IsFlyPortion()) + || !m_pCurr->IsRest())) // instead of !rInf.GetRest() + { bChg = SeekAndChg( rInf ); + } else bChg = SeekAndChgBefore( rInf ); } diff --git a/sw/source/core/text/itrtxt.hxx b/sw/source/core/text/itrtxt.hxx index 8db063d616..b5ea78369d 100644 --- a/sw/source/core/text/itrtxt.hxx +++ b/sw/source/core/text/itrtxt.hxx @@ -156,7 +156,7 @@ protected: // For FormatQuoVadis void Right( const SwTwips nNew ) { mnRight = nNew; } - void CtorInitTextMargin( SwTextFrame *pFrame, SwTextSizeInfo *pInf ); + SW_DLLPUBLIC void CtorInitTextMargin( SwTextFrame *pFrame, SwTextSizeInfo *pInf ); explicit SwTextMargin(SwTextNode const * pTextNode) : SwTextIter(pTextNode) , mnLeft(0) diff --git a/sw/source/core/txtnode/atrflyin.cxx b/sw/source/core/txtnode/atrflyin.cxx index 28eb7b38e5..fbefb76fa8 100644 --- a/sw/source/core/txtnode/atrflyin.cxx +++ b/sw/source/core/txtnode/atrflyin.cxx @@ -197,7 +197,8 @@ void SwTextFlyCnt::SetAnchor( const SwTextNode *pNode ) { if (SdrObject const*const pObj = pFormat->FindSdrObject()) { // tdf#123259 disconnect with *old* anchor position - static_cast(::GetUserCall(pObj))->DisconnectFromLayout(false); + if (SwDrawContact* pContact = static_cast(::GetUserCall( pObj ))) + pContact->DisconnectFromLayout(false); } } pFormat->SetFormatAttr( aAnchor ); // only set the anchor diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index cf5e1ff1cc..c499294f4f 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -1700,7 +1700,9 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode ) // for all of its content. auto* pTextContentControl = static_txtattr_cast( GetTextAttrAt(pAttr->GetStart(), RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent)); - if (pTextContentControl) + // If the caller is SwTextNode::CopyText, we just copy an existing attribute, no need to + // correct it. + if (pTextContentControl && !(nMode & SetAttrMode::NOTXTATRCHR)) { auto& rFormatContentControl = static_cast(pTextContentControl->GetAttr()); diff --git a/sw/source/core/undo/undraw.cxx b/sw/source/core/undo/undraw.cxx index 134c686297..73a58a0f52 100644 --- a/sw/source/core/undo/undraw.cxx +++ b/sw/source/core/undo/undraw.cxx @@ -274,6 +274,8 @@ void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &) SdrObject* pObj = rSave.pObj; SwDrawContact *pContact = static_cast(GetUserCall(pObj)); + if (!pContact) + continue; // Save the textboxes if (auto pOldTextBoxNode = rSave.pFormat->GetOtherTextBoxFormats()) @@ -350,23 +352,25 @@ SwUndoDrawUnGroup::SwUndoDrawUnGroup( SdrObjGroup* pObj, const SwDoc& rDoc ) m_nSize = o3tl::narrowing(pObj->GetSubList()->GetObjCount()) + 1; m_pObjArray.reset( new SwUndoGroupObjImpl[ m_nSize ] ); - SwDrawContact *pContact = static_cast(GetUserCall(pObj)); - SwDrawFrameFormat* pFormat = static_cast(pContact->GetFormat()); + if (SwDrawContact *pContact = static_cast(GetUserCall(pObj))) + { + SwDrawFrameFormat* pFormat = static_cast(pContact->GetFormat()); - m_pObjArray[0].pObj = pObj; - m_pObjArray[0].pFormat = pFormat; + m_pObjArray[0].pObj = pObj; + m_pObjArray[0].pFormat = pFormat; - // object will destroy itself - pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() ); - pObj->SetUserCall( nullptr ); + // object will destroy itself + pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() ); + pObj->SetUserCall( nullptr ); - ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx ); + ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx ); - pFormat->RemoveAllUnos(); + pFormat->RemoveAllUnos(); - // remove from array - sw::SpzFrameFormats& rFlyFormats = *pFormat->GetDoc()->GetSpzFrameFormats(); - rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat )); + // remove from array + sw::SpzFrameFormats& rFlyFormats = *pFormat->GetDoc()->GetSpzFrameFormats(); + rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat )); + } } SwUndoDrawUnGroup::~SwUndoDrawUnGroup() @@ -622,6 +626,9 @@ void SwUndoDrawDelete::RedoImpl(::sw::UndoRedoContext & rContext) SwUndoGroupObjImpl& rSave = m_pObjArray[n]; SdrObject *pObj = rSave.pObj; SwDrawContact *pContact = static_cast(GetUserCall(pObj)); + if (!pContact) + continue; + SwDrawFrameFormat *pFormat = static_cast(pContact->GetFormat()); // object will destroy itself diff --git a/sw/source/core/undo/unnum.cxx b/sw/source/core/undo/unnum.cxx index 1251635a31..a0aa39f3fc 100644 --- a/sw/source/core/undo/unnum.cxx +++ b/sw/source/core/undo/unnum.cxx @@ -112,7 +112,7 @@ void SwUndoInsNum::RedoImpl(::sw::UndoRedoContext & rContext) else { // #i42921# - adapt to changed signature - rDoc.SetNumRule(rPam, m_aNumRule, false); + rDoc.SetNumRule(rPam, m_aNumRule, SwDoc::SetNumRuleMode::Default); } } } @@ -131,7 +131,7 @@ void SwUndoInsNum::RepeatImpl(::sw::RepeatContext & rContext) if( m_sReplaceRule.isEmpty() ) { // #i42921# - adapt to changed signature - rDoc.SetNumRule(rContext.GetRepeatPaM(), m_aNumRule, false); + rDoc.SetNumRule(rContext.GetRepeatPaM(), m_aNumRule, SwDoc::SetNumRuleMode::Default); } } else diff --git a/sw/source/core/undo/untblk.cxx b/sw/source/core/undo/untblk.cxx index fd5c3239c0..c8967178c2 100644 --- a/sw/source/core/undo/untblk.cxx +++ b/sw/source/core/undo/untblk.cxx @@ -390,6 +390,10 @@ void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext) rPam.GetPoint()->GetNodeIndex())); ::std::optional oMvBkwrd = MovePtBackward(rPam); + bool const isMoveFlyAnchors(!oMvBkwrd // equivalent to bCanMoveBack + || m_oUndoNodeIndex->GetNode().IsTextNode() + || (oMvBkwrd->GetNode().IsStartNode() + && m_oUndoNodeIndex->GetNode().IsSectionNode())); // re-insert content again (first detach m_oUndoNodeIndex!) SwNodeOffset const nMvNd = m_oUndoNodeIndex->GetIndex(); @@ -403,7 +407,7 @@ void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext) // at-char anchors post SplitNode are on index 0 of 2nd node and will // remain there - move them back to the start (end would also work?) - if (pFlysAtInsPos) + if (pFlysAtInsPos && isMoveFlyAnchors) { for (SwFrameFormat * pFly : *pFlysAtInsPos) { diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx index 30f6d6e619..deb0d443b5 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -905,14 +905,14 @@ void setNumberingProperty(const Any& rValue, SwPaM& rPam) for ( size_t n = 0; n < aRangeArr.Count(); ++n ) { // no start of a new list - rDoc.SetNumRule( aRangeArr.SetPam( n, aPam ), aRule, false ); + rDoc.SetNumRule(aRangeArr.SetPam( n, aPam ), aRule, SwDoc::SetNumRuleMode::Default); } rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr ); } else { // no start of a new list - rDoc.SetNumRule( rPam, aRule, false ); + rDoc.SetNumRule(rPam, aRule, SwDoc::SetNumRuleMode::Default); } } @@ -923,7 +923,7 @@ void setNumberingProperty(const Any& rValue, SwPaM& rPam) if ( !pRule ) throw RuntimeException(); // no start of a new list - rDoc.SetNumRule( rPam, *pRule, false ); + rDoc.SetNumRule(rPam, *pRule, SwDoc::SetNumRuleMode::Default); } else { @@ -933,7 +933,7 @@ void setNumberingProperty(const Any& rValue, SwPaM& rPam) SwNumRule* pRule = rDoc.GetOutlineNumRule(); if(!pRule) throw RuntimeException(); - rDoc.SetNumRule( rPam, *pRule, false ); + rDoc.SetNumRule(rPam, *pRule, SwDoc::SetNumRuleMode::Default); } } } diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx index 709d79ef4d..9177765c0e 100644 --- a/sw/source/core/unocore/unoportenum.cxx +++ b/sw/source/core/unocore/unoportenum.cxx @@ -608,7 +608,9 @@ static void lcl_ExportBookmark( const SwXBookmarkPortion_ImplSharedPtr& pPtr = *aIter; if ( nIndex > pPtr->getIndex() ) { - assert(!"Some bookmarks were not consumed earlier"); + // We may get here, if SwXTextPortionEnumeration ctor was called with nStart greater + // than this bookmark's index. Just drop it. + aIter = rBkmArr.erase(aIter); continue; } if ( nIndex < pPtr->getIndex() ) diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx index 93603d6d40..3f720e452f 100644 --- a/sw/source/core/unocore/unotext.cxx +++ b/sw/source/core/unocore/unotext.cxx @@ -2337,12 +2337,6 @@ SwXText::copyText( // us, even if we have only a single paragraph. m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, SwCopyFlags::CheckPosInFly); } - if (!pFirstNode) - { // the node at rPos was split; get rid of the first empty one so - // that the pasted table is first - auto pDelCursor(m_pImpl->m_pDoc->CreateUnoCursor(SwPosition(*GetStartNode(), SwNodeOffset(1)))); - m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pDelCursor); - } } SwXBodyText::SwXBodyText(SwDoc *const pDoc) -- cgit v1.2.3