summaryrefslogtreecommitdiffstats
path: root/sw/source/core
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 11:48:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 11:48:25 +0000
commit9c0049cfae49c8e4ddef9125a69db2ad134c10c6 (patch)
tree812a86c0eee63dfc5ace12f2622ed3ce9cd3d680 /sw/source/core
parentReleasing progress-linux version 4:24.2.3-2~progress7.99u1. (diff)
downloadlibreoffice-9c0049cfae49c8e4ddef9125a69db2ad134c10c6.tar.xz
libreoffice-9c0049cfae49c8e4ddef9125a69db2ad134c10c6.zip
Merging upstream version 4:24.2.4.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/source/core')
-rw-r--r--sw/source/core/access/accfrmobj.cxx15
-rw-r--r--sw/source/core/crsr/crsrsh.cxx12
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx89
-rw-r--r--sw/source/core/doc/DocumentSettingManager.cxx21
-rw-r--r--sw/source/core/doc/docdraw.cxx12
-rw-r--r--sw/source/core/doc/docfmt.cxx10
-rw-r--r--sw/source/core/doc/docnum.cxx98
-rw-r--r--sw/source/core/doc/doctxm.cxx3
-rw-r--r--sw/source/core/docnode/nodes.cxx2
-rw-r--r--sw/source/core/draw/dcontact.cxx21
-rw-r--r--sw/source/core/draw/dview.cxx129
-rw-r--r--sw/source/core/edit/autofmt.cxx2
-rw-r--r--sw/source/core/edit/edglss.cxx8
-rw-r--r--sw/source/core/edit/ednumber.cxx12
-rw-r--r--sw/source/core/fields/fldbas.cxx10
-rw-r--r--sw/source/core/fields/reffld.cxx66
-rw-r--r--sw/source/core/frmedt/fecopy.cxx40
-rw-r--r--sw/source/core/frmedt/fefly1.cxx60
-rw-r--r--sw/source/core/frmedt/feshview.cxx59
-rw-r--r--sw/source/core/inc/DocumentSettingManager.hxx2
-rw-r--r--sw/source/core/inc/frame.hxx3
-rw-r--r--sw/source/core/inc/sectfrm.hxx2
-rw-r--r--sw/source/core/layout/anchoreddrawobject.cxx4
-rw-r--r--sw/source/core/layout/anchoredobject.cxx11
-rw-r--r--sw/source/core/layout/calcmove.cxx38
-rw-r--r--sw/source/core/layout/flowfrm.cxx5
-rw-r--r--sw/source/core/layout/fly.cxx4
-rw-r--r--sw/source/core/layout/flylay.cxx41
-rw-r--r--sw/source/core/layout/frmtool.cxx40
-rw-r--r--sw/source/core/layout/layact.cxx4
-rw-r--r--sw/source/core/layout/pagechg.cxx25
-rw-r--r--sw/source/core/layout/trvlfrm.cxx39
-rw-r--r--sw/source/core/objectpositioning/anchoredobjectposition.cxx5
-rw-r--r--sw/source/core/text/inftxt.hxx6
-rw-r--r--sw/source/core/text/itratr.hxx2
-rw-r--r--sw/source/core/text/itrform2.cxx13
-rw-r--r--sw/source/core/text/itrtxt.hxx2
-rw-r--r--sw/source/core/txtnode/atrflyin.cxx3
-rw-r--r--sw/source/core/txtnode/thints.cxx4
-rw-r--r--sw/source/core/undo/undraw.cxx31
-rw-r--r--sw/source/core/undo/unnum.cxx4
-rw-r--r--sw/source/core/undo/untblk.cxx6
-rw-r--r--sw/source/core/unocore/unocrsrhelper.cxx8
-rw-r--r--sw/source/core/unocore/unoportenum.cxx4
-rw-r--r--sw/source/core/unocore/unotext.cxx6
45 files changed, 675 insertions, 306 deletions
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<SwDrawContact const*>(pContact));
- SwPageFrame const*const pPage(const_cast<SwAnchoredObject *>(
- 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<SwAnchoredObject *>(
+ 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 <IDocumentSettingAccess.hxx>
#include <UndoManager.hxx>
#include <docary.hxx>
+#include <pamtyp.hxx>
#include <textboxhelper.hxx>
#include <dcontact.hxx>
#include <grfatr.hxx>
@@ -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<SwContentIndex> 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 <ListId> 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 <SwDoc::SetNumRule(..)>, because it also handles the <ListId>
// 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, "<lcl_AdjustPositioningAttr(..)> - 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<SwDrawContact*>(GetUserCall(pObj));
+ if (!pMyContact)
+ return pNewContact;
+
const SwFormatAnchor aAnch( pMyContact->GetFormat()->GetAnchor() );
std::unique_ptr<SwUndoDrawGroup> pUndo;
@@ -216,6 +222,9 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
SwDrawContact *pContact = static_cast<SwDrawContact*>(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<SwDrawContact*>(GetUserCall(pObj));
+ if (!pContact)
+ continue;
+
std::shared_ptr<SwTextBoxNode> 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<SwRegHistory> 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 <SwNodeNum.hxx>
#include <list.hxx>
#include <calbck.hxx>
+#include <editeng/lrspitem.hxx>
#include <comphelper/string.hxx>
#include <comphelper/random.hxx>
#include <o3tl/safeint.hxx>
@@ -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<sal_uInt16> 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<sal_uInt16>(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<SwTextFrame*>(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<const SwContact*>(pObj->GetUserCall())) &&
- "<::GetUserCall(..)> - wrong type of found object user call." );
- return static_cast<SwContact*>(pObj->GetUserCall());
+ for (; pObj; pObj = pObj->getParentSdrObjectFromSdrObject())
+ {
+ if (auto pUserCall = pObj->GetUserCall())
+ {
+ assert(dynamic_cast<SwContact*>(pUserCall)
+ && "<::GetUserCall(..)> - wrong type of found object user call.");
+ return static_cast<SwContact*>(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<SwVirtFlyDrawObj *>( pObj );
if ( pFlyDrawObj )
@@ -700,16 +719,18 @@ const SwFrame* SwDrawView::CalcAnchor()
}
else
{
- SwDrawContact *pC = static_cast<SwDrawContact*>(GetUserCall(pObj));
// determine correct anchor position for 'virtual' drawing objects.
// #i26791#
- pAnch = pC->GetAnchorFrame( pObj );
- if( !pAnch )
+ if (SwDrawContact* pContact = static_cast<SwDrawContact*>(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<SwDrawContact*>(GetUserCall(pObj));
- if ( pContact->GetAnchorFrame( pObj ) &&
- pContact->GetAnchorFrame( pObj )->IsPageFrame() )
- pAnch = pContact->GetPageFrame();
- else
- pAnch = pContact->FindPage( aRect );
+ if (SwDrawContact* pContact = static_cast<SwDrawContact*>(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<SwTextNode*>(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 <aPaM>
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<SwNode*>& 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<SwNode*> 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("<SwGetRefFieldType::FindAnchor(..)> - 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<SwDrawContact*>(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<SwDrawContact*>(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<SwDrawContact*>(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<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrame(pObj);
+ pFly = static_cast<SwDrawContact*>(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<SwPaM>& 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<SwPaM> 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 <rootfrm.hxx>
#include <pagefrm.hxx>
#include <sectfrm.hxx>
+#include <rowfrm.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <dview.hxx>
@@ -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<SwDrawContact*>(GetUserCall(pObj));
+ if (!pContact)
+ return false;
+
SwFrame* pOld;
SwFlyFrame* pFly = nullptr;
- SdrObject *pObj = pMrkList.GetMark( 0 )->GetMarkedSdrObj();
if (SwVirtFlyDrawObj* pVirtO = dynamic_cast<SwVirtFlyDrawObj*>(pObj))
{
pFly = pVirtO->GetFlyFrame();
pOld = pFly->AnchorFrame();
}
else
- pOld = static_cast<SwDrawContact*>(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<SwDrawContact*>( GetUserCall(pO) )->GetAnchorFrame( pO );
+ SwDrawContact* pContact = static_cast<SwDrawContact*>(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<SwRowFrame, SwFormat> 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<SwDrawContact*>(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<SwDrawContact*>(GetUserCall(pObj));
- // --> make code robust
OSL_ENSURE( pContact, "<SwFEShell::GetObjAttr(..)> - missing <pContact>." );
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<SwDrawContact*>(GetUserCall(pObj));
- GetDoc()->SetAttr( rSet, *pContact->GetFormat() );
+ if (SwDrawContact *pContact = static_cast<SwDrawContact*>(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<SwSectionFrameInvFlags> : is_typed_flags<SwSectionFrameInvFlags, 0x0011> {};
}
-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<SwDrawContact*>(::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<SwDrawContact*>(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<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))->
- DisconnectFromLayout( false );
+ if (SwDrawContact* pContact = static_cast<SwDrawContact*>(::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<const SwFlyInContentFrame*>(pFly)->GetRefPoint().X() :
- static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y();
- nTop = aRectFnSet.YInc( nTop, -nHeight );
- tools::Long nWidth = aRectFnSet.GetWidth(pFly->getFrameArea());
- aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ?
- static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y() :
- static_cast<const SwFlyInContentFrame*>(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<const SwFlyInContentFrame*>(pFly)->GetRefPoint().X() :
+ static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y();
+ nTop = aRectFnSet.YInc( nTop, -nHeight );
+ tools::Long nWidth = aRectFnSet.GetWidth(pFly->getFrameArea());
+ aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ?
+ static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y() :
+ static_cast<const SwFlyInContentFrame*>(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<SwDrawContact*>(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<SwDrawContact*>(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<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrame(pObj);
- aPos = pObj->GetCurrentBoundRect().TopLeft();
+ if (SwDrawContact* pC = static_cast<SwDrawContact*>(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 <tabfrm.hxx>
#include <txtfrm.hxx>
#include <notxtfrm.hxx>
+#include <sectfrm.hxx>
#include <layact.hxx>
#include <flyfrms.hxx>
#include <htmltbl.hxx>
@@ -445,22 +446,21 @@ static void lcl_MakeObjs(const sw::FrameFormats<sw::SpzFrameFormat*>& rSpzs, SwP
if ( bSdrObj )
{
// OD 23.06.2003 #108784# - consider 'virtual' drawing objects
- SwDrawContact *pContact =
- static_cast<SwDrawContact*>(::GetUserCall(pSdrObj));
- if ( auto pDrawVirtObj = dynamic_cast<SwDrawVirtObj *>( pSdrObj ) )
+ if (SwDrawContact *pContact =
+ static_cast<SwDrawContact*>(::GetUserCall(pSdrObj)))
{
- if ( pContact )
+ if ( auto pDrawVirtObj = dynamic_cast<SwDrawVirtObj *>( 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<const SwVirtFlyDrawObj*>(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<SwDrawContact*>(::GetUserCall(pObj))->DisconnectFromLayout(false);
+ if (SwDrawContact* pContact = static_cast<SwDrawContact*>(::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<SwTextContentControl*>(
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<SwFormatContentControl&>(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<SwDrawContact*>(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<sal_uInt16>(pObj->GetSubList()->GetObjCount()) + 1;
m_pObjArray.reset( new SwUndoGroupObjImpl[ m_nSize ] );
- SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
- SwDrawFrameFormat* pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
+ if (SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)))
+ {
+ SwDrawFrameFormat* pFormat = static_cast<SwDrawFrameFormat*>(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<SwDrawContact*>(GetUserCall(pObj));
+ if (!pContact)
+ continue;
+
SwDrawFrameFormat *pFormat = static_cast<SwDrawFrameFormat*>(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<SwNodeIndex> 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)