summaryrefslogtreecommitdiffstats
path: root/sw/source
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/core/access/AccessibilityCheck.cxx5
-rw-r--r--sw/source/core/doc/docfly.cxx19
-rw-r--r--sw/source/core/edit/eddel.cxx8
-rw-r--r--sw/source/core/fields/expfld.cxx2
-rw-r--r--sw/source/core/layout/layact.cxx12
-rw-r--r--sw/source/core/layout/paintfrm.cxx3
-rw-r--r--sw/source/core/layout/tabfrm.cxx15
-rw-r--r--sw/source/core/text/frmform.cxx101
-rw-r--r--sw/source/core/undo/untbl.cxx15
-rw-r--r--sw/source/core/unocore/unoframe.cxx13
-rw-r--r--sw/source/core/unocore/unoobj.cxx12
-rw-r--r--sw/source/core/unocore/unoportenum.cxx3
-rw-r--r--sw/source/filter/html/htmlatr.cxx40
-rw-r--r--sw/source/filter/html/htmlctxt.cxx3
-rw-r--r--sw/source/filter/ww8/wrtw8nds.cxx41
-rw-r--r--sw/source/filter/ww8/ww8par.cxx43
-rw-r--r--sw/source/filter/ww8/ww8par5.cxx30
-rw-r--r--sw/source/ui/fldui/fldref.cxx2
-rw-r--r--sw/source/ui/index/cnttab.cxx4
-rw-r--r--sw/source/ui/index/swuiidxmrk.cxx1
-rw-r--r--sw/source/uibase/shells/textsh.cxx9
-rw-r--r--sw/source/uibase/wrtsh/delete.cxx4
22 files changed, 276 insertions, 109 deletions
diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index e515b5cae7..dfa94c3ed9 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -901,6 +901,11 @@ public:
}
case '\t':
{
+ // Don't warn about tabs in ToC
+ auto pSection = SwDoc::GetCurrSection(SwPosition(*pTextNode, 0));
+ if (pSection && pSection->GetTOXBase())
+ continue;
+
if (bPreviousWasChar)
{
++nTabCount;
diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx
index c492212487..2038941230 100644
--- a/sw/source/core/doc/docfly.cxx
+++ b/sw/source/core/doc/docfly.cxx
@@ -149,6 +149,25 @@ SwFrameFormat* SwDoc::GetFlyNum( size_t nIdx, FlyCntType eType, bool bIgnoreText
return pRetFormat;
}
+SwFrameFormat* SwDoc::GetFlyFrameFormatByName( const OUString& rFrameFormatName )
+{
+ auto pFrameFormats = GetSpzFrameFormats();
+ auto it = pFrameFormats->findByTypeAndName( RES_FLYFRMFMT, rFrameFormatName );
+ auto endIt = pFrameFormats->typeAndNameEnd();
+ for ( ; it != endIt; ++it)
+ {
+ sw::SpzFrameFormat* pFlyFormat = *it;
+ const SwNodeIndex* pIdx = pFlyFormat->GetContent().GetContentIdx();
+ if( !pIdx || !pIdx->GetNodes().IsDocNodes() )
+ continue;
+
+ const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
+ if( !pNd->IsNoTextNode())
+ return pFlyFormat;
+ }
+ return nullptr;
+}
+
std::vector<SwFrameFormat const*> SwDoc::GetFlyFrameFormats(
FlyCntType const eType, bool const bIgnoreTextBoxes)
{
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index 9eb51da617..b8d6b0e395 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -33,7 +33,8 @@
#include <strings.hrc>
#include <vector>
-void SwEditShell::DeleteSel(SwPaM& rPam, bool const isArtificialSelection, bool *const pUndo)
+void SwEditShell::DeleteSel(SwPaM& rPam, bool const isArtificialSelection, bool goLeft,
+ bool* const pUndo)
{
auto const oSelectAll(StartsWith_() != SwCursorShell::StartsWith::None
? ExtendedSelectedAll()
@@ -127,11 +128,12 @@ void SwEditShell::DeleteSel(SwPaM& rPam, bool const isArtificialSelection, bool
}
}
+ rPam.Normalize(goLeft); // change tracking case: will make sure to end up in the correct point
// Selection is not needed anymore
rPam.DeleteMark();
}
-bool SwEditShell::Delete(bool const isArtificialSelection)
+bool SwEditShell::Delete(bool const isArtificialSelection, bool goLeft)
{
CurrShell aCurr( this );
bool bRet = false;
@@ -159,7 +161,7 @@ bool SwEditShell::Delete(bool const isArtificialSelection)
for(SwPaM& rPaM : GetCursor()->GetRingContainer())
{
- DeleteSel(rPaM, isArtificialSelection, &bUndo);
+ DeleteSel(rPaM, isArtificialSelection, goLeft, &bUndo);
}
// If undo container then close here
diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx
index 6ed4cdb7c1..47c675cc42 100644
--- a/sw/source/core/fields/expfld.cxx
+++ b/sw/source/core/fields/expfld.cxx
@@ -233,7 +233,7 @@ const SwTextNode* GetBodyTextNode( const SwDoc& rDoc, SwPosition& rPos,
else
pContentFrame = pPgFrame->FindLastBodyContent();
- if( pContentFrame )
+ if( pContentFrame && !pContentFrame->IsInFootnote() )
{
assert(pContentFrame->IsTextFrame());
SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(pContentFrame));
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index a705ef2511..1a0a1260a1 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -809,6 +809,12 @@ void SwLayAction::InternalAction(OutputDevice* pRenderContext)
unlockPositionOfObjects( pPg );
pPg = static_cast<SwPageFrame*>(pPg->GetNext());
}
+ if (m_pRoot->IsSuperfluous()) // could be newly set now!
+ {
+ bool bOld = IsAgain();
+ m_pRoot->RemoveSuperfluous();
+ SetAgain(bOld);
+ }
// reset flag for special interrupt content formatting.
mbFormatContentOnInterrupt = false;
}
@@ -1433,7 +1439,11 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrame *pLa
PopFormatLayout();
}
}
- // else: don't calc content frames any more
+ else if (pLay->IsSctFrame() && pLow->IsTextFrame() && pLow == pLay->GetLastLower())
+ {
+ // else: only calc the last text lower of sections
+ pLow->OptCalc();
+ }
if ( IsAgain() )
return false;
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 0f048c4e80..5472695e97 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -7012,7 +7012,8 @@ void SwPageFrame::RefreshSubsidiary( const SwRect &rRect ) const
void SwLayoutFrame::RefreshLaySubsidiary( const SwPageFrame *pPage,
const SwRect &rRect ) const
{
- const bool bSubsOpt = isSubsidiaryLinesEnabled() || isSubsidiaryLinesForSectionsEnabled();
+ const bool bSubsOpt
+ = isSubsidiaryLinesEnabled() || (IsSctFrame() && isSubsidiaryLinesForSectionsEnabled());
if ( bSubsOpt )
PaintSubsidiaryLines( pPage, rRect );
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index c4a742c037..adffbba177 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -1165,7 +1165,13 @@ bool SwTabFrame::Split(const SwTwips nCutPos, bool bTryToSplit,
OSL_ENSURE( !GetIndPrev(), "Table is supposed to be at beginning" );
if ( !IsInSct() )
{
- m_pTable->SetRowsToRepeat(0);
+ // This would mean the layout modifies the doc model, so RowsToRepeat drops to 0 while
+ // there are existing row frames with RepeatedHeadline == true. Avoid this at least
+ // inside split flys, it would lead to a crash in SwTabFrame::MakeAll().
+ if (!pFly || !pFly->IsFlySplitAllowed())
+ {
+ m_pTable->SetRowsToRepeat(0);
+ }
return false;
}
else
@@ -1517,7 +1523,8 @@ namespace
}
}
}
- if (rTab.IsCollapsingBorders() && !rCell.Lower()->IsRowFrame())
+ assert(rCell.Lower());
+ if (rTab.IsCollapsingBorders() && rCell.Lower() && !rCell.Lower()->IsRowFrame())
{
if (rRow.GetTopMarginForLowers() != 0
|| rRow.GetBottomMarginForLowers() != 0)
@@ -6371,6 +6378,10 @@ void SwTabFrame::dumpAsXml(xmlTextWriterPtr writer) const
{
(void)xmlTextWriterStartElement(writer, reinterpret_cast<const xmlChar*>("tab"));
SwFrame::dumpAsXmlAttributes( writer );
+
+ (void)xmlTextWriterWriteAttribute(writer, BAD_CAST("has-follow-flow-line"),
+ BAD_CAST(OString::boolean(m_bHasFollowFlowLine).getStr()));
+
if ( HasFollow() )
(void)xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrameId() );
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index e19b834a56..97eff3e607 100644
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -1081,6 +1081,54 @@ void SwTextFrame::ChangeOffset( SwTextFrame* pFrame, TextFrameIndex nNew )
MoveFlyInCnt( pFrame, nNew, TextFrameIndex(COMPLETE_STRING) );
}
+static bool isFirstVisibleFrameInBody(const SwTextFrame* pFrame)
+{
+ const SwFrame* pBodyFrame = pFrame->FindBodyFrame();
+ if (!pBodyFrame)
+ return false;
+ for (const SwFrame* pCur = pFrame;;)
+ {
+ for (const SwFrame* pPrev = pCur->GetPrev(); pPrev; pPrev = pPrev->GetPrev())
+ if (!pPrev->IsHiddenNow())
+ return false;
+ pCur = pCur->GetUpper();
+ assert(pCur); // We found pBodyFrame, right?
+ if (pCur->IsBodyFrame())
+ return true;
+ }
+}
+
+static bool hasFly(const SwTextFrame* pFrame)
+{
+ if (auto pDrawObjs = pFrame->GetDrawObjs(); pDrawObjs && pDrawObjs->size())
+ {
+ auto anchorId = (*pDrawObjs)[0]->GetFrameFormat()->GetAnchor().GetAnchorId();
+ if (anchorId == RndStdIds::FLY_AT_PARA || anchorId == RndStdIds::FLY_AT_CHAR)
+ return true;
+ }
+ return false;
+}
+
+static bool hasAtPageFly(const SwFrame* pFrame)
+{
+ auto pPageFrame = pFrame->FindPageFrame();
+ if (!pPageFrame)
+ return false;
+ auto pPageDrawObjs = pPageFrame->GetDrawObjs();
+ if (pPageDrawObjs)
+ {
+ for (const auto pObject : *pPageDrawObjs)
+ if (pObject->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE)
+ return true;
+ }
+ return false;
+}
+
+static bool isReallyEmptyMaster(const SwTextFrame* pFrame)
+{
+ return pFrame->IsEmptyMaster() && (!pFrame->GetDrawObjs() || !pFrame->GetDrawObjs()->size());
+}
+
void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
WidowsAndOrphans &rFrameBreak,
TextFrameIndex const nStrLen,
@@ -1108,27 +1156,55 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
? 1 : 0;
SwTextFormatInfo& rInf = rLine.GetInfo();
+ bool bEmptyWithSplitFly = false;
if (nNew == 0 && !nStrLen && !rInf.GetTextFly().IsOn() && IsEmptyWithSplitFly())
{
// Empty paragraph, so IsBreakNow() is not called, but we should split the fly portion and
// the paragraph marker.
nNew = 1;
+ bEmptyWithSplitFly = true;
}
+ const SwFrame *pBodyFrame = FindBodyFrame();
+
// i#84870
// no split of text frame, which only contains an as-character anchored object
- bool bOnlyContainsAsCharAnchoredObj =
+ bool bLoneAsCharAnchoredObj =
+ pBodyFrame &&
!IsFollow() && nStrLen == TextFrameIndex(1) &&
GetDrawObjs() && GetDrawObjs()->size() == 1 &&
(*GetDrawObjs())[0]->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR;
- // Still try split text frame if we have columns.
- if (FindColFrame())
- bOnlyContainsAsCharAnchoredObj = false;
-
- if ( nNew && bOnlyContainsAsCharAnchoredObj )
+ if (bLoneAsCharAnchoredObj)
{
- nNew = 0;
+ // Still try split text frame if we have columns.
+ if (FindColFrame())
+ bLoneAsCharAnchoredObj = false;
+ // tdf#160526: only no split if there is no preceding frames on same page
+ else if (!isFirstVisibleFrameInBody(this))
+ bLoneAsCharAnchoredObj = false;
+ else
+ nNew = 0;
+ }
+ else if (nNew)
+ {
+ if (IsFollow())
+ {
+ // tdf#160549: do not split the frame at the very beginning again, if its master was empty
+ auto precede = static_cast<SwTextFrame*>(GetPrecede());
+ assert(precede);
+ auto precedeText = precede->DynCastTextFrame();
+ assert(precedeText);
+ if (isReallyEmptyMaster(precedeText))
+ nNew = 0;
+ }
+ else if (!bEmptyWithSplitFly)
+ {
+ // Do not split immediately in the beginning of page (unless there is an at-para or
+ // at-char or at-page fly, which pushes the rest down)
+ if (isFirstVisibleFrameInBody(this) && !hasFly(this) && !hasAtPageFly(pBodyFrame))
+ nNew = 0;
+ }
}
if ( nNew )
@@ -1136,8 +1212,6 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
SplitFrame( nEnd );
}
- const SwFrame *pBodyFrame = FindBodyFrame();
-
const tools::Long nBodyHeight = pBodyFrame ? ( IsVertical() ?
pBodyFrame->getFrameArea().Width() :
pBodyFrame->getFrameArea().Height() ) : 0;
@@ -1239,9 +1313,10 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
// content or contains no content, but has a numbering.
// i#84870 - No split, if text frame only contains one
// as-character anchored object.
- if ( !bOnlyContainsAsCharAnchoredObj &&
- (nStrLen > TextFrameIndex(0) ||
- bHasVisibleNumRule )
+ if (!bLoneAsCharAnchoredObj
+ && (bHasVisibleNumRule
+ || (nStrLen > TextFrameIndex(0)
+ && (nEnd != rLine.GetStart() || rInf.GetRest())))
)
{
SplitFrame( nEnd );
@@ -1265,7 +1340,7 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
//#i84870# - no shrink of text frame, if it only contains one as-character anchored object.
- if ( nChg < 0 && !bDelta && bOnlyContainsAsCharAnchoredObj )
+ if (nChg < 0 && !bDelta && bLoneAsCharAnchoredObj)
{
nChg = 0;
}
diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx
index 72f1c809e2..52157df0ca 100644
--- a/sw/source/core/undo/untbl.cxx
+++ b/sw/source/core/undo/untbl.cxx
@@ -2599,11 +2599,17 @@ void SwUndoTableCpyTable::AddBoxBefore( const SwTableBox& rBox, bool bDelContent
if( bDelContent )
{
SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
- pDoc->GetNodes().MakeTextNode( aInsIdx.GetNode(), pDoc->GetDfltTextFormatColl() );
+ SwTextNode *const pNewNode(pDoc->GetNodes().MakeTextNode(aInsIdx.GetNode(), pDoc->GetDfltTextFormatColl()));
SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() );
if( !pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
+ {
+ { // move cursors to new node which precedes aPam
+ SwPosition const pos(*pNewNode, 0);
+ ::PaMCorrAbs(aPam, pos);
+ }
pEntry->pUndo = std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, true);
+ }
}
pEntry->pBoxNumAttr = std::make_unique<SfxItemSetFixed<
@@ -2627,6 +2633,13 @@ void SwUndoTableCpyTable::AddBoxAfter( const SwTableBox& rBox, const SwNodeIndex
SwDoc* pDoc = rBox.GetFrameFormat()->GetDoc();
DEBUG_REDLINE( pDoc )
+ { // move cursors to first node which was inserted
+ SwPaM pam(SwNodeIndex(*rBox.GetSttNd(), 1));
+ assert(pam.GetPoint()->GetNode().IsTextNode());
+ pam.SetMark();
+ pam.Move(fnMoveForward, GoInContent);
+ ::PaMCorrAbs(pam, *pam.GetPoint());
+ }
if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
{
SwPosition aTmpPos( rIdx );
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
index 7880a749b9..62c4c76ac3 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -1713,18 +1713,7 @@ void SwXFrame::setPropertyValue(const OUString& rPropertyName, const ::uno::Any&
}
else
{
- const size_t nCount = pDoc->GetFlyCount(FLYCNTTYPE_FRM);
-
- SwFrameFormat* pChain = nullptr;
- for( size_t i = 0; i < nCount; ++i )
- {
- SwFrameFormat* pFormat2 = pDoc->GetFlyNum(i, FLYCNTTYPE_FRM);
- if(sChainName == pFormat2->GetName() )
- {
- pChain = pFormat2;
- break;
- }
- }
+ SwFrameFormat* pChain = pDoc->GetFlyFrameFormatByName(sChainName);
if(pChain)
{
SwFrameFormat* pSource = bNextFrame ? pFormat : pChain;
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
index 49562c1d02..df02c4773a 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -752,13 +752,19 @@ void SwXTextCursor::DeleteAndInsert(std::u16string_view aText,
}
if(nTextLen)
{
+ // Store node and content indexes prior to insertion: to select the inserted text,
+ // we need to account for possible surrogate pairs, combining characters, etc.; it
+ // is easier to just restore the correct position from the indexes.
+ const auto start = pCurrent->Start();
+ const auto nodeIndex = start->GetNodeIndex();
+ const auto contentIndex = start->GetContentIndex();
const bool bSuccess(
SwUnoCursorHelper::DocInsertStringSplitCR(
- rDoc, *pCurrent, aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints)));
+ rDoc, SwPaM(*start, pCurrent), aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints)));
OSL_ENSURE( bSuccess, "Doc->Insert(Str) failed." );
- SwUnoCursorHelper::SelectPam(*pUnoCursor, true);
- pCurrent->Left(aText.size());
+ pCurrent->SetMark();
+ pCurrent->GetPoint()->Assign(nodeIndex, contentIndex);
}
pCurrent = pCurrent->GetNext();
} while (pCurrent != pUnoCursor);
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 494cec7468..709d79ef4d 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -150,8 +150,11 @@ namespace
bool const hasOther = isExpanded && rStartPos != rEndPos;
bool const bStartPosInNode = rStartPos.GetNode() == rOwnNode;
bool const bEndPosInNode = rEndPos.GetNode() == rOwnNode;
+ // tdf#160700: Crossrefbookmarks only need separate start and end, when the start
+ // isn't in the end position (so in empty nodes, no need to handle them specially)
sw::mark::CrossRefBookmark* const pCrossRefMark
= !isExpanded && bStartPosInNode
+ && rStartPos.GetContentIndex() < rStartPos.GetContentNode()->Len()
? dynamic_cast<sw::mark::CrossRefBookmark*>(pBkmk)
: nullptr;
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index c880082018..f298f93dc5 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -1524,8 +1524,9 @@ void HTMLEndPosLst::SplitItem( const SfxPoolItem& rItem, sal_Int32 nStart,
for (auto it = items.begin(); it != items.end();)
{
- HTMLStartEndPos* pTest = *it;
- sal_Int32 nTestEnd = pTest->GetEnd();
+ auto itTest = it++; // forward early, allow 'continue', and keep a copy for 'erase'
+ HTMLStartEndPos* pTest = *itTest;
+ const sal_Int32 nTestEnd = pTest->GetEnd();
if (nTestEnd <= nStart)
continue;
@@ -1533,28 +1534,25 @@ void HTMLEndPosLst::SplitItem( const SfxPoolItem& rItem, sal_Int32 nStart,
const SfxPoolItem& rTestItem = pTest->GetItem();
// only the corresponding OnTag attributes have to be considered
- if (rTestItem.Which() == nWhich && HTML_ON_VALUE == GetHTMLItemState(rTestItem))
- {
- // if necessary, insert the second part of the split
- // attribute
- if (nTestEnd > nEnd)
- InsertItem(pTest->GetItem(), nEnd, nTestEnd);
+ if (rTestItem.Which() != nWhich || HTML_ON_VALUE != GetHTMLItemState(rTestItem))
+ continue;
- if (nTestStart >= nStart)
- {
- // the Test item only starts after the new end of the
- // attribute. Therefore, it can be completely erased.
- it = items.erase(it);
- std::erase(m_aEndLst[pTest->GetEnd()], pTest);
- delete pTest;
- continue;
- }
+ // if necessary, insert the second part of the split attribute
+ if (nTestEnd > nEnd)
+ InsertItem(rTestItem, nEnd, nTestEnd);
- // the start of the new attribute corresponds to the new
- // end of the attribute
- FixSplittedItem(pTest, nStart);
+ if (nTestStart >= nStart)
+ {
+ // the Test item only starts after the new end of the
+ // attribute. Therefore, it can be completely erased.
+ it = items.erase(itTest);
+ std::erase(m_aEndLst[nTestEnd], pTest);
+ delete pTest;
+ continue;
}
- ++it;
+
+ // the start of the new attribute corresponds to the new end of the attribute
+ FixSplittedItem(pTest, nStart);
}
}
}
diff --git a/sw/source/filter/html/htmlctxt.cxx b/sw/source/filter/html/htmlctxt.cxx
index 80245ba2ea..0e87b83644 100644
--- a/sw/source/filter/html/htmlctxt.cxx
+++ b/sw/source/filter/html/htmlctxt.cxx
@@ -656,7 +656,8 @@ void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
}
#endif
- for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ SfxItemIter aIter2(rItemSet);
+ for (const SfxPoolItem* pItem = aIter2.GetCurItem(); pItem; pItem = aIter2.NextItem())
{
HTMLAttr **ppAttr = nullptr;
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 68437c9529..e33e8708f4 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2658,33 +2658,36 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
assert(pFieldmark);
- if (pFieldmark->GetFieldname() == ODF_FORMDATE)
+ if (pFieldmark)
{
- if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
+ if (pFieldmark->GetFieldname() == ODF_FORMDATE)
{
- OutputField( nullptr, ww::eFORMDATE, OUString(), FieldFlags::Close );
+ if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
+ {
+ OutputField( nullptr, ww::eFORMDATE, OUString(), FieldFlags::Close );
+ }
}
- }
- else
- {
- ww::eField eFieldId = lcl_getFieldId( pFieldmark );
- if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
+ else
{
- IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
- if ( it != pFieldmark->GetParameters()->end() )
+ ww::eField eFieldId = lcl_getFieldId( pFieldmark );
+ if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
{
- OUString sFieldId;
- it->second >>= sFieldId;
- eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
+ IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
+ if ( it != pFieldmark->GetParameters()->end() )
+ {
+ OUString sFieldId;
+ it->second >>= sFieldId;
+ eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
+ }
}
- }
- OutputField( nullptr, eFieldId, OUString(), FieldFlags::Close );
+ OutputField( nullptr, eFieldId, OUString(), FieldFlags::Close );
- if (pFieldmark->GetFieldname() == ODF_FORMTEXT
- && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
- {
- AppendBookmark( pFieldmark->GetName() );
+ if (pFieldmark->GetFieldname() == ODF_FORMTEXT
+ && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
+ {
+ AppendBookmark( pFieldmark->GetName() );
+ }
}
}
}
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 10ccaa4878..976a68b88a 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -27,6 +27,7 @@
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/packages/XPackageEncryption.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XTextFieldsSupplier.hpp>
#include <i18nlangtag/languagetag.hxx>
@@ -4808,27 +4809,35 @@ void SwWW8ImplReader::ReadDocVars()
aDocVarStrings, &aDocVarStringIds, &aDocValueStrings);
if (m_bVer67) return;
- uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
- m_pDocShell->GetModel(), uno::UNO_QUERY_THROW);
- uno::Reference<document::XDocumentProperties> xDocProps(
- xDPS->getDocumentProperties());
- OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
- uno::Reference<beans::XPropertyContainer> xUserDefinedProps =
- xDocProps->getUserDefinedProperties();
- OSL_ENSURE(xUserDefinedProps.is(), "UserDefinedProperties is null");
-
- for(size_t i=0; i<aDocVarStrings.size(); i++)
+ uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<css::lang::XMultiServiceFactory> xTextFactory(m_pDocShell->GetModel(), uno::UNO_QUERY);
+ uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters();
+ for(size_t i = 0; i < aDocVarStrings.size(); i++)
{
const OUString &rName = aDocVarStrings[i];
uno::Any aValue;
- aValue <<= rName;
- try {
- xUserDefinedProps->addProperty( rName,
- beans::PropertyAttribute::REMOVABLE,
- aValue );
- } catch (const uno::Exception &) {
- // ignore
+ if (aDocValueStrings.size() > i)
+ {
+ OUString value = aDocValueStrings[i];
+ value = value.replaceAll("\r\n", "\n");
+ value = value.replaceAll("\r", "\n");
+ aValue <<= value;
+ }
+
+ uno::Reference< beans::XPropertySet > xMaster;
+ OUString sFieldMasterService("com.sun.star.text.FieldMaster.User." + rName);
+
+ // Find or create Field Master
+ if (xFieldMasterAccess->hasByName(sFieldMasterService))
+ {
+ xMaster.set(xFieldMasterAccess->getByName(sFieldMasterService), uno::UNO_QUERY_THROW);
+ }
+ else
+ {
+ xMaster.set(xTextFactory->createInstance("com.sun.star.text.FieldMaster.User"), uno::UNO_QUERY_THROW);
+ xMaster->setPropertyValue("Name", uno::Any(rName));
}
+ xMaster->setPropertyValue("Content", aValue);
}
}
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index c87c33dde0..6750fa21ae 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -58,6 +58,7 @@
#include <IDocumentState.hxx>
#include <flddat.hxx>
#include <docufld.hxx>
+#include <usrfld.hxx>
#include <reffld.hxx>
#include <IMark.hxx>
#include <expfld.hxx>
@@ -1831,12 +1832,29 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr )
aData = aData.replaceAll("\"", "");
}
- const auto pType(static_cast<SwDocInfoFieldType*>(
- m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocInfo)));
- SwDocInfoField aField(pType, nSub|nReg, aData, GetFieldResult(pF), nFormat);
- if (bDateTime)
- ForceFieldLanguage(aField, nLang);
- m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
+ bool bDone = false;
+ if (DI_CUSTOM == nSub)
+ {
+ const auto pType(static_cast<SwUserFieldType*>(
+ m_rDoc.getIDocumentFieldsAccess().GetFieldType(SwFieldIds::User, aData, false)));
+ if (pType)
+ {
+ SwUserField aField(pType, 0, nFormat);
+ if (bDateTime)
+ ForceFieldLanguage(aField, nLang);
+ m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
+ bDone = true;
+ }
+ }
+ if (!bDone)
+ {
+ const auto pType(static_cast<SwDocInfoFieldType*>(
+ m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocInfo)));
+ SwDocInfoField aField(pType, nSub|nReg, aData, GetFieldResult(pF), nFormat);
+ if (bDateTime)
+ ForceFieldLanguage(aField, nLang);
+ m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
+ }
return eF_ResT::OK;
}
diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx
index a08715c8ca..434e10a6a2 100644
--- a/sw/source/ui/fldui/fldref.cxx
+++ b/sw/source/ui/fldui/fldref.cxx
@@ -268,7 +268,7 @@ void SwFieldRefPage::Reset(const SfxItemSet* )
nFieldDlgFormatSel = 0;
sal_uInt16 nFormatBoxPosition = USHRT_MAX;
- if( !IsRefresh() )
+ if( !IsFieldEdit() )
{
sal_Int32 nIdx{ 0 };
const OUString sUserData = GetUserData();
diff --git a/sw/source/ui/index/cnttab.cxx b/sw/source/ui/index/cnttab.cxx
index a5d3bf92dd..535dc298dd 100644
--- a/sw/source/ui/index/cnttab.cxx
+++ b/sw/source/ui/index/cnttab.cxx
@@ -2933,7 +2933,7 @@ SwTOXWidget* SwTokenWindow::InsertItem(const OUString& rText, const SwFormToken&
//use the first two chars as symbol
OUString sTmp(SwAuthorityFieldType::GetAuthFieldName(
static_cast<ToxAuthorityField>(rToken.nAuthorityField)));
- pButton->SetText(sTmp.copy(0, 2));
+ pButton->SetText(sTmp.copy(0, std::min(sTmp.getLength(), sal_Int32(2))));
}
sal_uInt32 nIndex = GetControlIndex( rToken.eTokenType );
@@ -3140,7 +3140,7 @@ void SwTokenWindow::InsertAtSelection(const SwFormToken& rToken)
//use the first two chars as symbol
OUString sTmp(SwAuthorityFieldType::GetAuthFieldName(
static_cast<ToxAuthorityField>(aToInsertToken.nAuthorityField)));
- pButton->SetText(sTmp.copy(0, 2));
+ pButton->SetText(sTmp.copy(0, std::min(sTmp.getLength(), sal_Int32(2))));
}
pButton->Check();
diff --git a/sw/source/ui/index/swuiidxmrk.cxx b/sw/source/ui/index/swuiidxmrk.cxx
index 8a6f74b86e..03d5733a87 100644
--- a/sw/source/ui/index/swuiidxmrk.cxx
+++ b/sw/source/ui/index/swuiidxmrk.cxx
@@ -441,6 +441,7 @@ IMPL_LINK_NOARG(SwIndexMarkPane, SyncSelectionHdl, weld::Button&, void)
m_xApplyToAllCB->show();
m_xSearchCaseSensitiveCB->show();
m_xSearchCaseWordOnlyCB->show();
+ m_xDialog->resize_to_request();
m_xApplyToAllCB->set_sensitive(!m_aOrgStr.isEmpty() &&
!(nFrameType & ( FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FLY_ANY )));
SearchTypeHdl(*m_xApplyToAllCB);
diff --git a/sw/source/uibase/shells/textsh.cxx b/sw/source/uibase/shells/textsh.cxx
index 97de985401..29242d9946 100644
--- a/sw/source/uibase/shells/textsh.cxx
+++ b/sw/source/uibase/shells/textsh.cxx
@@ -885,10 +885,13 @@ void SwTextShell::ExecRotateTransliteration( SfxRequest const & rReq )
}
else
{
- rSh.Push(); // save cur cursor
- if ((rSh.IsEndWrd() || rSh.IsStartWord() || rSh.IsInWord()) && rSh.SelWrd())
+ if (rSh.IsEndSentence())
+ {
+ rSh.BwdSentence(true);
+ rSh.TransliterateText(m_aRotateCase.getNextMode());
+ }
+ else if ((rSh.IsEndWrd() || rSh.IsStartWord() || rSh.IsInWord()) && rSh.SelWrd())
rSh.TransliterateText(m_aRotateCase.getNextMode());
- rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
}
}
}
diff --git a/sw/source/uibase/wrtsh/delete.cxx b/sw/source/uibase/wrtsh/delete.cxx
index e7a09d0165..46b0a40cca 100644
--- a/sw/source/uibase/wrtsh/delete.cxx
+++ b/sw/source/uibase/wrtsh/delete.cxx
@@ -171,7 +171,7 @@ bool SwWrtShell::DelLeft()
{
SwActContext aActContext(this);
ResetCursorStack();
- Delete(false);
+ Delete(false, true);
UpdateAttr();
}
if( IsBlockMode() )
@@ -274,7 +274,7 @@ bool SwWrtShell::DelLeft()
SwCursorShell::Pop( SwCursorShell::PopMode::DeleteStack );
}
}
- bool bRet = Delete(true);
+ bool bRet = Delete(true, true);
if( !bRet && bSwap )
SwCursorShell::SwapPam();
CloseMark( bRet );