diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 09:27:54 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 09:27:54 +0000 |
commit | adb203bc05e3e36173cbd46b9951f79821a81799 (patch) | |
tree | 6e6739df9b3f0a567330a0dd7ee0e03ae70876a3 /sw/source | |
parent | Adding debian version 4:24.2.0-3. (diff) | |
download | libreoffice-adb203bc05e3e36173cbd46b9951f79821a81799.tar.xz libreoffice-adb203bc05e3e36173cbd46b9951f79821a81799.zip |
Merging upstream version 4:24.2.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/source')
74 files changed, 988 insertions, 574 deletions
diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx index e4eaa089ef..e515b5cae7 100644 --- a/sw/source/core/access/AccessibilityCheck.cxx +++ b/sw/source/core/access/AccessibilityCheck.cxx @@ -344,6 +344,10 @@ public: if (!pNextTextNode) return; + SwSectionNode* pNd = pCurrentTextNode->FindSectionNode(); + if (pNd && pNd->GetSection().GetType() == SectionType::ToxContent) + return; + for (auto& rPair : m_aNumberingCombinations) { if (pCurrentTextNode->GetText().startsWith(rPair.first) diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index 04b263cda7..173414ed4d 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -2936,6 +2936,7 @@ OUString SwCursorShell::GetSelText() const } /** get the nth character of the current SSelection + in the same paragraph as the start/end. @param bEnd Start counting from the end? From start otherwise. @param nOffset position of the character @@ -2951,8 +2952,14 @@ sal_Unicode SwCursorShell::GetChar( bool bEnd, tools::Long nOffset ) if( !pTextNd ) return 0; - const sal_Int32 nPos = pPos->GetContentIndex(); - const OUString& rStr = pTextNd->GetText(); + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(pTextNd->getLayoutFrame(GetLayout()))); + if (!pFrame) + { + return 0; + } + + const sal_Int32 nPos(sal_Int32(pFrame->MapModelToViewPos(*pPos))); + const OUString& rStr(pFrame->GetText()); sal_Unicode cCh = 0; if (((nPos+nOffset) >= 0 ) && (nPos+nOffset) < rStr.getLength()) diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx index db11d4ea33..81323787d7 100644 --- a/sw/source/core/crsr/crstrvl.cxx +++ b/sw/source/core/crsr/crstrvl.cxx @@ -600,6 +600,7 @@ const SwTOXMark& SwCursorShell::GotoTOXMark( const SwTOXMark& rStart, SwPosition& rPos = *GetCursor()->GetPoint(); rPos.Assign(rNewMark.GetTextTOXMark()->GetTextNode(), rNewMark.GetTextTOXMark()->GetStart() ); + GetCursor()->DeleteMark(); // tdf#158783 prevent UpdateCursor resetting point if( !m_pCurrentCursor->IsSelOvr() ) UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE | diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx index ebe116c682..baa0f29326 100644 --- a/sw/source/core/doc/DocumentSettingManager.cxx +++ b/sw/source/core/doc/DocumentSettingManager.cxx @@ -192,6 +192,7 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const case DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION: return mbConsiderWrapOnObjPos; case DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: return mbDoNotJustifyLinesWithManualBreak; case DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING: return mbIgnoreFirstLineIndentInNumbering; + case DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER: return mbNoGapAfterNoteNumber; case DocumentSettingId::TABLE_ROW_KEEP: return mbTableRowKeep; case DocumentSettingId::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION: return mbIgnoreTabsAndBlanksForLineCalculation; case DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE: return mbDoNotCaptureDrawObjsOnPage; @@ -337,6 +338,9 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo case DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING: mbIgnoreFirstLineIndentInNumbering = value; break; + case DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER: + mbNoGapAfterNoteNumber = value; + break; case DocumentSettingId::TABLE_ROW_KEEP: mbTableRowKeep = value; @@ -697,6 +701,7 @@ void sw::DocumentSettingManager::ReplaceCompatibilityOptions(const DocumentSetti mbStylesNoDefault = rSource.mbStylesNoDefault; mbOldNumbering = rSource.mbOldNumbering; mbIgnoreFirstLineIndentInNumbering = rSource.mbIgnoreFirstLineIndentInNumbering; + mbNoGapAfterNoteNumber = rSource.mbNoGapAfterNoteNumber; mbDoNotJustifyLinesWithManualBreak = rSource.mbDoNotJustifyLinesWithManualBreak; mbDoNotResetParaAttrsForNumFont = rSource.mbDoNotResetParaAttrsForNumFont; mbTableRowKeep = rSource.mbTableRowKeep; @@ -880,6 +885,12 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const BAD_CAST(OString::boolean(mbIgnoreFirstLineIndentInNumbering).getStr())); (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbNoGapAfterNoteNumber")); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("value"), + BAD_CAST(OString::boolean(mbNoGapAfterNoteNumber).getStr())); + (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbDoNotJustifyLinesWithManualBreak")); (void)xmlTextWriterWriteAttribute( pWriter, BAD_CAST("value"), diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index 00681135b4..730da32625 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -1410,6 +1410,16 @@ namespace sw::mark return IDocumentMarkAccess::iterator(ret); } + // find the first Mark that does not start before + IDocumentMarkAccess::const_iterator_t MarkManager::findFirstMarkNotStartsBefore(const SwPosition& rPos) const + { + return std::lower_bound( + m_vAllMarks.begin(), + m_vAllMarks.end(), + rPos, + CompareIMarkStartsBefore()); + } + IDocumentMarkAccess::const_iterator_t MarkManager::getAllMarksBegin() const { return m_vAllMarks.begin(); } diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx index aecbe2ac82..521ca2b0ba 100644 --- a/sw/source/core/doc/docdraw.cxx +++ b/sw/source/core/doc/docdraw.cxx @@ -463,14 +463,17 @@ bool SwDoc::DeleteSelection( SwDrawView& rDrawView ) SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); if( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) { - SwDrawContact *pC = static_cast<SwDrawContact*>(GetUserCall(pObj)); - SwDrawFrameFormat *pFrameFormat = static_cast<SwDrawFrameFormat*>(pC->GetFormat()); - if( pFrameFormat && - RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId() ) + if (SwDrawContact* pC = static_cast<SwDrawContact*>(GetUserCall(pObj))) { - rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), true ); - --i; - getIDocumentLayoutAccess().DelLayoutFormat( pFrameFormat ); + SwDrawFrameFormat* pFrameFormat + = static_cast<SwDrawFrameFormat*>(pC->GetFormat()); + if (pFrameFormat + && RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId()) + { + rDrawView.MarkObj(pObj, rDrawView.Imp().GetPageView(), true); + --i; + getIDocumentLayoutAccess().DelLayoutFormat(pFrameFormat); + } } } } diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 57c42c529e..d6c943dbcd 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -25,10 +25,10 @@ #include <editeng/lrspitem.hxx> #include <editeng/formatbreakitem.hxx> #include <editeng/rsiditem.hxx> -#include <editeng/colritem.hxx> #include <officecfg/Office/Common.hxx> #include <osl/diagnose.h> #include <svl/zforlist.hxx> +#include <svx/DocumentColorHelper.hxx> #include <comphelper/processfactory.hxx> #include <unotools/configmgr.hxx> #include <sal/log.hxx> @@ -2036,17 +2036,11 @@ std::set<Color> SwDoc::GetDocColors() { std::set<Color> aDocColors; SwAttrPool& rPool = GetAttrPool(); - const sal_uInt16 pAttribs[] = {RES_CHRATR_COLOR, RES_CHRATR_HIGHLIGHT, RES_BACKGROUND}; - for (sal_uInt16 nAttrib : pAttribs) - { - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nAttrib)) - { - auto pColorItem = static_cast<const SvxColorItem*>(pItem); - Color aColor( pColorItem->GetValue() ); - if (COL_AUTO != aColor) - aDocColors.insert(aColor); - } - } + + svx::DocumentColorHelper::queryColors<SvxColorItem>(RES_CHRATR_COLOR, &rPool, aDocColors); + svx::DocumentColorHelper::queryColors<SvxBrushItem>(RES_CHRATR_HIGHLIGHT, &rPool, aDocColors); + svx::DocumentColorHelper::queryColors<SvxBrushItem>(RES_CHRATR_BACKGROUND, &rPool, aDocColors); + return aDocColors; } diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx index 2ecea30dc3..ebbefd9738 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -554,10 +554,8 @@ SwPosFlyFrames SwDoc::GetAllFlyFormats( const SwPaM* pCmpRange, bool bDrawAlso, for(SwAnchoredObject* pAnchoredObj : rObjs) { SwFrameFormat *pFly; - if ( pAnchoredObj->DynCastFlyFrame() != nullptr ) - pFly = &(pAnchoredObj->GetFrameFormat()); - else if ( bDrawAlso ) - pFly = &(pAnchoredObj->GetFrameFormat()); + if (bDrawAlso || pAnchoredObj->DynCastFlyFrame()) + pFly = pAnchoredObj->GetFrameFormat(); else continue; diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx index 5c2147ed91..aac8f2393c 100644 --- a/sw/source/core/draw/dcontact.cxx +++ b/sw/source/core/draw/dcontact.cxx @@ -493,7 +493,7 @@ sal_uInt32 SwFlyDrawContact::GetOrdNumForNewRef(const SwFlyFrame* pFly, { for (SwAnchoredObject const*const pAnchoredObj : *pObjs) { - if (&pAnchoredObj->GetFrameFormat() == pDrawFormat) + if (pAnchoredObj->GetFrameFormat() == pDrawFormat) { return pAnchoredObj->GetDrawObj()->GetOrdNum() + 1; } @@ -1235,7 +1235,7 @@ void SwDrawContact::Changed_( const SdrObject& rObj, // #i31698# - determine layout direction // via draw frame format. SwFrameFormat::tLayoutDir eLayoutDir = - pAnchoredDrawObj->GetFrameFormat().GetLayoutDir(); + pAnchoredDrawObj->GetFrameFormat()->GetLayoutDir(); // use geometry of drawing object tools::Rectangle aObjRect( rObj.GetSnapRect() ); // If drawing object is a member of a group, the adjustment @@ -1967,7 +1967,7 @@ void SwDrawContact::ConnectToLayout( const SwFormatAnchor* pAnch ) { for (const SwAnchoredObject* pAnchoredObj : *pObjs) { - if (&pAnchoredObj->GetFrameFormat() == pFlyFormat) + if (pAnchoredObj->GetFrameFormat() == pFlyFormat) { SdrPage* pDrawPage = pAnchoredObj->GetDrawObj()->getSdrPageFromSdrObject(); if (pDrawPage) @@ -2359,7 +2359,7 @@ void SwDrawVirtObj::AddToDrawingPage(SwFrame const& rAnchorFrame) { for (SwAnchoredObject const*const pAnchoredObj : *pObjs) { - if (&pAnchoredObj->GetFrameFormat() == pFlyFormat) + if (pAnchoredObj->GetFrameFormat() == pFlyFormat) { assert(dynamic_cast<SwFlyFrame const*>(pAnchoredObj)); diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx index 9d704647c3..fe0db61925 100644 --- a/sw/source/core/draw/dview.cxx +++ b/sw/source/core/draw/dview.cxx @@ -550,7 +550,7 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, { size_t nTmpNewPos( nNewPos ); const SwFrameFormat* pParentFrameFormat = - pParentAnchoredObj ? &(pParentAnchoredObj->GetFrameFormat()) : nullptr; + pParentAnchoredObj ? pParentAnchoredObj->GetFrameFormat() : nullptr; const SdrObject* pTmpObj = pDrawPage->GetObj( nNewPos + 1 ); while ( pTmpObj ) { @@ -562,7 +562,7 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, const SwFlyFrame* pTmpParentObj = pTmpAnchorFrame ? pTmpAnchorFrame->FindFlyFrame() : nullptr; if ( pTmpParentObj && - &(pTmpParentObj->GetFrameFormat()) != pParentFrameFormat ) + pTmpParentObj->GetFrameFormat() != pParentFrameFormat ) { if ( bMovedForward ) { @@ -977,16 +977,19 @@ void SwDrawView::DeleteMarked() { SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj(); SwContact* pContact = GetUserCall(pObject); - SwFrameFormat* pFormat = pContact->GetFormat(); - if (pObject->getChildrenOfSdrObject()) + if (pContact) { - auto pChildTextBoxes = SwTextBoxHelper::CollectTextBoxes(pObject, pFormat); - for (auto& rChildTextBox : pChildTextBoxes) - aTextBoxesToDelete.push_back(rChildTextBox); - } - else - if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) + SwFrameFormat* pFormat = pContact->GetFormat(); + if (pObject->getChildrenOfSdrObject()) + { + auto pChildTextBoxes = SwTextBoxHelper::CollectTextBoxes(pObject, pFormat); + for (auto& rChildTextBox : pChildTextBoxes) + aTextBoxesToDelete.push_back(rChildTextBox); + } + else if (SwFrameFormat* pTextBox + = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) aTextBoxesToDelete.push_back(pTextBox); + } } if ( pDoc->DeleteSelection( *this ) ) diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx index 434f676729..6ed4cdb7c1 100644 --- a/sw/source/core/fields/expfld.cxx +++ b/sw/source/core/fields/expfld.cxx @@ -881,10 +881,9 @@ std::unique_ptr<SwField> SwSetExpField::Copy() const void SwSetExpField::SetSubType(sal_uInt16 nSub) { + assert((nSub & 0xff) != (nsSwGetSetExpType::GSE_STRING|nsSwGetSetExpType::GSE_EXPR) && "SubType is illegal!"); static_cast<SwSetExpFieldType*>(GetTyp())->SetType(nSub & 0xff); mnSubType = nSub & 0xff00; - - OSL_ENSURE( (nSub & 0xff) != 3, "SubType is illegal!" ); } sal_uInt16 SwSetExpField::GetSubType() const @@ -1100,8 +1099,19 @@ bool SwSetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId ) break; case FIELD_PROP_SUBTYPE: nTmp32 = lcl_APIToSubType(rAny); - if(nTmp32 >= 0) - SetSubType(o3tl::narrowing<sal_uInt16>((GetSubType() & 0xff00) | nTmp32)); + if (0 <= nTmp32 && nTmp32 != (GetSubType() & 0xff)) + { + auto const subType(o3tl::narrowing<sal_uInt16>((GetSubType() & 0xff00) | nTmp32)); + if (((nTmp32 & nsSwGetSetExpType::GSE_STRING) != (GetSubType() & nsSwGetSetExpType::GSE_STRING)) + && GetInputFlag()) + { + SwXTextField::TransmuteLeadToInputField(*this, &subType); + } + else + { + SetSubType(subType); + } + } break; case FIELD_PROP_PAR3: rAny >>= maPText; @@ -1120,7 +1130,7 @@ bool SwSetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId ) if (static_cast<SwSetExpFieldType*>(GetTyp())->GetType() & nsSwGetSetExpType::GSE_STRING) { - SwXTextField::TransmuteLeadToInputField(*this); + SwXTextField::TransmuteLeadToInputField(*this, nullptr); } else { diff --git a/sw/source/core/fields/postithelper.cxx b/sw/source/core/fields/postithelper.cxx index a3f27be6f5..06fb3db7ef 100644 --- a/sw/source/core/fields/postithelper.cxx +++ b/sw/source/core/fields/postithelper.cxx @@ -97,8 +97,8 @@ SwAnchoredObject* GetAnchoredObjectOfAnnotationMark(const sw::mark::IMark& rAnno for (SwAnchoredObject* pObject : *pAnchored) { - SwFrameFormat& rFrameFormat = pObject->GetFrameFormat(); - const SwPosition* pFrameAnchor = rFrameFormat.GetAnchor().GetContentAnchor(); + SwFrameFormat* pFrameFormat = pObject->GetFrameFormat(); + const SwPosition* pFrameAnchor = pFrameFormat->GetAnchor().GetContentAnchor(); if (!pFrameAnchor) { continue; diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx index 9e2fedcc38..93ad4212cf 100644 --- a/sw/source/core/frmedt/fefly1.cxx +++ b/sw/source/core/frmedt/fefly1.cxx @@ -286,8 +286,8 @@ void SwFEShell::UnfloatFlyFrame() return; } - SwFrameFormat& rFlyFormat = pFly->GetFrameFormat(); - const SwFormatContent& rContent = rFlyFormat.GetContent(); + SwFrameFormat* pFlyFormat = pFly->GetFrameFormat(); + const SwFormatContent& rContent = pFlyFormat->GetContent(); const SwNodeIndex* pFlyStart = rContent.GetContentIdx(); if (!pFlyStart) { @@ -315,7 +315,7 @@ void SwFEShell::UnfloatFlyFrame() } SwNodeRange aRange(pFlyStart->GetNode(), SwNodeOffset(1), *pFlyEnd, SwNodeOffset(-1)); - const SwFormatAnchor& rAnchor = rFlyFormat.GetAnchor(); + const SwFormatAnchor& rAnchor = pFlyFormat->GetAnchor(); SwNode* pAnchor = rAnchor.GetAnchorNode(); if (!pAnchor) { @@ -327,8 +327,8 @@ void SwFEShell::UnfloatFlyFrame() rIDCO.MoveNodeRange(aRange, aInsertPos.GetNode(), SwMoveFlags::CREATEUNDOOBJ); // Remove the fly frame frame. - IDocumentLayoutAccess& rIDLA = rFlyFormat.getIDocumentLayoutAccess(); - rIDLA.DelLayoutFormat(&rFlyFormat); + IDocumentLayoutAccess& rIDLA = pFlyFormat->getIDocumentLayoutAccess(); + rIDLA.DelLayoutFormat(pFlyFormat); } // Get selected fly @@ -496,8 +496,8 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) // #i28701# SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); - SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - const RndStdIds nAnchorId = rFormat.GetAnchor().GetAnchorId(); + SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + const RndStdIds nAnchorId = pFormat->GetAnchor().GetAnchorId(); if ( RndStdIds::FLY_AS_CHAR == nAnchorId ) return aRet; @@ -505,9 +505,9 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) bool bFlyFrame = dynamic_cast<SwVirtFlyDrawObj *>(pObj) != nullptr; bool bTextBox = false; - if (rFormat.Which() == RES_DRAWFRMFMT) + if (pFormat->Which() == RES_DRAWFRMFMT) { - bTextBox = SwTextBoxHelper::isTextBox(&rFormat, RES_DRAWFRMFMT, pObj); + bTextBox = SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT, pObj); } SwFlyFrame* pFly = nullptr; @@ -534,7 +534,7 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) { auto pFlyFormat = dynamic_cast<const SwFlyFrameFormat*>(SwTextBoxHelper::getOtherTextBoxFormat( - &rFormat, RES_DRAWFRMFMT, pObj)); + pFormat, RES_DRAWFRMFMT, pObj)); if (pFlyFormat) { pFly = pFlyFormat->GetFrame(); @@ -608,7 +608,7 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) if ( bMoveIt || (nAnchorId == RndStdIds::FLY_AT_CHAR) ) { - SwFormatAnchor aAnch( rFormat.GetAnchor() ); + SwFormatAnchor aAnch( pFormat->GetAnchor() ); switch ( nAnchorId ) { case RndStdIds::FLY_AT_PARA: @@ -665,24 +665,24 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) // anchor attribute is change and re-create them afterwards. { std::unique_ptr<SwHandleAnchorNodeChg> pHandleAnchorNodeChg; - SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat*>(&rFormat) ); + SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat*>(pFormat) ); if ( pFlyFrameFormat ) { pHandleAnchorNodeChg.reset( new SwHandleAnchorNodeChg( *pFlyFrameFormat, aAnch )); } - rFormat.GetDoc()->SetAttr( aAnch, rFormat ); - if (SwTextBoxHelper::getOtherTextBoxFormat(&rFormat, RES_DRAWFRMFMT, + pFormat->GetDoc()->SetAttr( aAnch, *pFormat ); + if (SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT, pObj)) { if (SdrObjList* pObjList = pObj->getChildrenOfSdrObject()) { for (const rtl::Reference<SdrObject>& pChild : *pObjList) - SwTextBoxHelper::changeAnchor(&rFormat, pChild.get()); + SwTextBoxHelper::changeAnchor(pFormat, pChild.get()); } else SwTextBoxHelper::syncFlyFrameAttr( - rFormat, rFormat.GetAttrSet(), pObj); + *pFormat, pFormat->GetAttrSet(), pObj); } } // #i28701# - no call of method diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx index 9a18e7934c..9154758364 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -392,8 +392,8 @@ bool SwFEShell::MoveAnchor( SwMove nDir ) SwFrame* pNew = pOld; // #i28701# SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); - SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - SwFormatAnchor aAnch( rFormat.GetAnchor() ); + SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + SwFormatAnchor aAnch( pFormat->GetAnchor() ); RndStdIds nAnchorId = aAnch.GetAnchorId(); if ( RndStdIds::FLY_AS_CHAR == nAnchorId ) return false; @@ -582,13 +582,13 @@ bool SwFEShell::MoveAnchor( SwMove nDir ) // anchor attribute is change and re-create them afterwards. { std::unique_ptr<SwHandleAnchorNodeChg> pHandleAnchorNodeChg; - SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat*>(&rFormat) ); + SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat*>(pFormat) ); if ( pFlyFrameFormat ) { pHandleAnchorNodeChg.reset( new SwHandleAnchorNodeChg( *pFlyFrameFormat, aAnch )); } - rFormat.GetDoc()->SetAttr( aAnch, rFormat ); + pFormat->GetDoc()->SetAttr( aAnch, *pFormat ); } // #i28701# - no call of method // <CheckCharRectAndTopOfLine()> for to-character anchored @@ -1317,8 +1317,8 @@ bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) if ( pObj->GetLayer() == rIDDMA.GetHellId() ) { const SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); - const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - const SwFormatSurround& rSurround = rFormat.GetSurround(); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rSurround = pFormat->GetSurround(); if ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH ) { bObjInBackground = true; @@ -2221,14 +2221,16 @@ RndStdIds SwFEShell::GetAnchorId() const nRet = RndStdIds::UNKNOWN; break; } - SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)); - RndStdIds nId = pContact->GetFormat()->GetAnchor().GetAnchorId(); - if ( nRet == RndStdIds(SHRT_MAX) ) - nRet = nId; - else if ( nRet != nId ) + if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj))) { - nRet = RndStdIds::UNKNOWN; - break; + RndStdIds nId = pContact->GetFormat()->GetAnchor().GetAnchorId(); + if (nRet == RndStdIds(SHRT_MAX)) + nRet = nId; + else if (nRet != nId) + { + nRet = RndStdIds::UNKNOWN; + break; + } } } } @@ -3152,17 +3154,19 @@ Color SwFEShell::GetShapeBackground() const OSL_ENSURE( dynamic_cast<const SwVirtFlyDrawObj*>( pSdrObj) == nullptr, "wrong usage of SwFEShell::GetShapeBackground - selected object is not a drawing object!"); if ( dynamic_cast<const SwVirtFlyDrawObj*>( pSdrObj) == nullptr ) { - // determine page frame of the frame the shape is anchored. - const SwFrame* pAnchorFrame = - static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrame( pSdrObj ); - OSL_ENSURE( pAnchorFrame, "inconsistent model - no anchor at shape!"); - if ( pAnchorFrame ) + if (SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall(pSdrObj))) { - const SwPageFrame* pPageFrame = pAnchorFrame->FindPageFrame(); - OSL_ENSURE( pPageFrame, "inconsistent model - no page!"); - if ( pPageFrame ) + // determine page frame of the frame the shape is anchored. + const SwFrame * pAnchorFrame = pDrawContact->GetAnchorFrame(pSdrObj); + OSL_ENSURE(pAnchorFrame, "inconsistent model - no anchor at shape!"); + if (pAnchorFrame) { - aRetColor = pPageFrame->GetDrawBackgroundColor(); + const SwPageFrame* pPageFrame = pAnchorFrame->FindPageFrame(); + OSL_ENSURE(pPageFrame, "inconsistent model - no page!"); + if (pPageFrame) + { + aRetColor = pPageFrame->GetDrawBackgroundColor(); + } } } } diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx index 79f5eb6b5e..33b9c9327b 100644 --- a/sw/source/core/frmedt/fetab.cxx +++ b/sw/source/core/frmedt/fetab.cxx @@ -2116,8 +2116,8 @@ SwTab SwFEShell::WhichMouseTabCol( const Point &rPt ) const { while( pFrame && pFrame->Lower() && pFrame->Lower()->IsRowFrame() ) pFrame = static_cast<const SwCellFrame*>(static_cast<const SwLayoutFrame*>(pFrame->Lower())->Lower()); - if( pFrame && pFrame->GetTabBox()->GetSttNd() && - pFrame->GetTabBox()->GetSttNd()->IsInProtectSect() ) + if( pFrame && ((pFrame->GetTabBox()->GetSttNd() && + pFrame->GetTabBox()->GetSttNd()->IsInProtectSect()) || (pFrame->GetTabBox()->getRowSpan() < 0))) pFrame = nullptr; } diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx index bce8e2bb97..539f485313 100644 --- a/sw/source/core/frmedt/fews.cxx +++ b/sw/source/core/frmedt/fews.cxx @@ -464,12 +464,12 @@ void SwFEShell::InsertLabel( const SwLabelType eType, const OUString &rText, con // This table is in a split fly, but we will insert a label, which means this is not // a floating table anymore, disable the "can split" bit, it'll be hidden on the UI // anyway. - SwFrameFormat& rFlyFormat = pFly->GetFrameFormat(); + SwFrameFormat* pFormat = pFly->GetFrameFormat(); SfxItemSetFixed<RES_FLY_SPLIT, RES_FLY_SPLIT> aSet(GetDoc()->GetAttrPool()); SwFormatFlySplit aSplit(false); aSet.Put(aSplit); // SwUndoFormatAttr is created for us. - GetDoc()->SetFlyFrameAttr(rFlyFormat, aSet); + GetDoc()->SetFlyFrameAttr(*pFormat, aSet); } } break; diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx index 284dccf9cf..3e5be92c64 100644 --- a/sw/source/core/inc/DocumentSettingManager.hxx +++ b/sw/source/core/inc/DocumentSettingManager.hxx @@ -132,6 +132,7 @@ class DocumentSettingManager final : // non-ui-compatibility flags: bool mbOldNumbering : 1; bool mbIgnoreFirstLineIndentInNumbering : 1; // #i47448# + bool mbNoGapAfterNoteNumber : 1 = false; // tdf#159382 bool mbDoNotJustifyLinesWithManualBreak : 1; // #i49277# bool mbDoNotResetParaAttrsForNumFont : 1; // #i53199# bool mbTableRowKeep : 1; diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx index ef0e79d74c..dd7eb9f6f1 100644 --- a/sw/source/core/inc/MarkManager.hxx +++ b/sw/source/core/inc/MarkManager.hxx @@ -81,6 +81,7 @@ namespace sw::mark { virtual const_iterator_t getAllMarksEnd() const override; virtual sal_Int32 getAllMarksCount() const override; virtual const_iterator_t findMark(const OUString& rName) const override; + virtual const_iterator_t findFirstMarkNotStartsBefore(const SwPosition& rPos) const override; // bookmarks virtual bool isBookmarkDeleted(SwPaM const& rPaM, bool isReplace) const override; diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx index d1f14591bc..dfbd7e8daf 100644 --- a/sw/source/core/inc/flyfrm.hxx +++ b/sw/source/core/inc/flyfrm.hxx @@ -266,8 +266,8 @@ public: virtual void InvalidateObjPos() override; virtual void RegisterAtPage(SwPageFrame&) override; - virtual SwFrameFormat& GetFrameFormat() override; - virtual const SwFrameFormat& GetFrameFormat() const override; + virtual SwFrameFormat* GetFrameFormat() override; + virtual const SwFrameFormat* GetFrameFormat() const override; virtual SwRect GetObjRect() const override; diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index aa2246727f..e60dbd20fb 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -588,7 +588,7 @@ public: TextFrameIndex GetDropLen(TextFrameIndex nWishLen) const; LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, - bool bNoChar = false) const; + bool bNoChar = false, bool bNoneIfNoHyphenation = false ) const; virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override; virtual void CheckDirection( bool bVert ) override; diff --git a/sw/source/core/inc/unofield.hxx b/sw/source/core/inc/unofield.hxx index 55214020c0..313185a000 100644 --- a/sw/source/core/inc/unofield.hxx +++ b/sw/source/core/inc/unofield.hxx @@ -133,7 +133,7 @@ private: public: SwServiceType GetServiceId() const; - static void TransmuteLeadToInputField(SwSetExpField & rField); + static void TransmuteLeadToInputField(SwSetExpField & rField, sal_uInt16 const*const pSubType); /// @return an SwXTextField, either an already existing one or a new one static rtl::Reference<SwXTextField> diff --git a/sw/source/core/layout/anchoreddrawobject.cxx b/sw/source/core/layout/anchoreddrawobject.cxx index 6dc6cac5d1..5a9e1245af 100644 --- a/sw/source/core/layout/anchoreddrawobject.cxx +++ b/sw/source/core/layout/anchoreddrawobject.cxx @@ -214,13 +214,13 @@ SwAnchoredDrawObject::~SwAnchoredDrawObject() // --> #i62875# void SwAnchoredDrawObject::UpdateLayoutDir() { - SwFrameFormat::tLayoutDir nOldLayoutDir( GetFrameFormat().GetLayoutDir() ); + SwFrameFormat::tLayoutDir nOldLayoutDir( GetFrameFormat()->GetLayoutDir() ); SwAnchoredObject::UpdateLayoutDir(); if ( !NotYetPositioned() && - GetFrameFormat().GetLayoutDir() != nOldLayoutDir && - GetFrameFormat().GetDoc()->GetDocumentSettingManager().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) && + GetFrameFormat()->GetLayoutDir() != nOldLayoutDir && + GetFrameFormat()->GetDoc()->GetDocumentSettingManager().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) && !IsOutsidePage() ) { mbCaptureAfterLayoutDirChange = true; @@ -284,7 +284,7 @@ void SwAnchoredDrawObject::MakeObjPos() // #i44334#, #i44681# - check, if positioning // attributes already have been set. if ( dynamic_cast< const SwDrawVirtObj* >(GetDrawObj()) == nullptr && - !static_cast<SwDrawFrameFormat&>(GetFrameFormat()).IsPosAttrSet() ) + !static_cast<SwDrawFrameFormat*>(GetFrameFormat())->IsPosAttrSet() ) { SetPositioningAttr(); } @@ -395,7 +395,7 @@ void SwAnchoredDrawObject::MakeObjPosAnchoredAtPara() // Format of anchor is needed for (vertical) fly offsets, otherwise the // lack of fly portions will result in an incorrect 0 offset. - bool bAddVerticalFlyOffsets = GetFrameFormat().getIDocumentSettingAccess().get( + bool bAddVerticalFlyOffsets = GetFrameFormat()->getIDocumentSettingAccess().get( DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS); bool bFormatAnchorOnce = !bJoinLocked && bAddVerticalFlyOffsets; @@ -518,11 +518,12 @@ void SwAnchoredDrawObject::SetDrawObjAnchor() // correct object position, caused by setting new anchor position DrawObj()->Move( aMove ); // Sync textbox if it wasn't done at move - if ( SwTextBoxHelper::isTextBox(&GetFrameFormat(), RES_DRAWFRMFMT) && GetFrameFormat().GetDoc() && - GetFrameFormat().GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() && - GetFrameFormat().GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell()->IsInConstructor()) + SwFrameFormat* pObjFormat = GetFrameFormat(); + if ( SwTextBoxHelper::isTextBox(pObjFormat, RES_DRAWFRMFMT) && pObjFormat->GetDoc() && + pObjFormat->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() && + pObjFormat->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell()->IsInConstructor()) { - SwTextBoxHelper::changeAnchor(&GetFrameFormat(), GetFrameFormat().FindRealSdrObject()); + SwTextBoxHelper::changeAnchor(pObjFormat, pObjFormat->FindRealSdrObject()); } // --> #i70122# - missing invalidation InvalidateObjRectWithSpaces(); @@ -543,7 +544,7 @@ void SwAnchoredDrawObject::InvalidatePage_( SwPageFrame* _pPageFrame ) // --> #i35007# - correct invalidation for as-character // anchored objects. - if ( GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR ) + if ( GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR ) { _pPageFrame->InvalidateFlyInCnt(); } @@ -582,13 +583,14 @@ void SwAnchoredDrawObject::InvalidateObjPos() // anchored object, because its positioned by the format of its anchor frame. // --> #i44559# - assure, that text hint is already // existing in the text frame + const SwFrameFormat* pObjFormat = GetFrameFormat(); if ( GetAnchorFrame()->DynCastTextFrame() != nullptr && - (GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) ) + (pObjFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) ) { SwTextFrame* pAnchorTextFrame( static_cast<SwTextFrame*>(AnchorFrame()) ); - if (pAnchorTextFrame->CalcFlyPos(&GetFrameFormat()) != TextFrameIndex(COMPLETE_STRING)) + if (pAnchorTextFrame->CalcFlyPos(pObjFormat) != TextFrameIndex(COMPLETE_STRING)) { - AnchorFrame()->Prepare( PrepareHint::FlyFrameAttributesChanged, &GetFrameFormat() ); + AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, pObjFormat); } } @@ -615,15 +617,17 @@ void SwAnchoredDrawObject::InvalidateObjPos() } } -SwFrameFormat& SwAnchoredDrawObject::GetFrameFormat() +SwFrameFormat* SwAnchoredDrawObject::GetFrameFormat() { - assert(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat()); - return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat()); + if (SwDrawContact* pDC = static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))) + return pDC->GetFormat(); + return nullptr; } -const SwFrameFormat& SwAnchoredDrawObject::GetFrameFormat() const +const SwFrameFormat* SwAnchoredDrawObject::GetFrameFormat() const { - assert(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat()); - return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat()); + if (SwDrawContact* pDC = static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))) + return pDC->GetFormat(); + return nullptr; } SwRect SwAnchoredDrawObject::GetObjRect() const @@ -807,10 +811,11 @@ void SwAnchoredDrawObject::AdjustPositioningAttr( const SwFrame* _pNewAnchorFram SwFormatHoriOrient hori(nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME); SwFormatVertOrient vert(nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME); - SfxItemSetFixed<RES_VERT_ORIENT, RES_HORI_ORIENT> items(GetFrameFormat().GetDoc()->GetAttrPool()); + SwFrameFormat* pObjFormat = GetFrameFormat(); + SfxItemSetFixed<RES_VERT_ORIENT, RES_HORI_ORIENT> items(pObjFormat->GetDoc()->GetAttrPool()); items.Put(hori); items.Put(vert); - GetFrameFormat().GetDoc()->SetAttr(items, GetFrameFormat()); + pObjFormat->GetDoc()->SetAttr(items, *pObjFormat); } // --> #i34748# - change return type. @@ -845,6 +850,7 @@ void SwAnchoredDrawObject::SetPositioningAttr() SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall( GetDrawObj() )); + SwFrameFormat* pObjFormat = GetFrameFormat(); if ( !pDrawContact->ObjAnchoredAsChar() ) { SwRect aObjRect( GetObjRect() ); @@ -853,10 +859,10 @@ void SwAnchoredDrawObject::SetPositioningAttr() SwTwips nVertPos = aObjRect.Top(); // #i44334#, #i44681# // perform conversion only if position is in horizontal-left-to-right-layout. - if ( GetFrameFormat().GetPositionLayoutDir() == + if (pObjFormat->GetPositionLayoutDir() == text::PositionLayoutDir::PositionInHoriL2R ) { - SwFrameFormat::tLayoutDir eLayoutDir = GetFrameFormat().GetLayoutDir(); + SwFrameFormat::tLayoutDir eLayoutDir = pObjFormat->GetLayoutDir(); switch ( eLayoutDir ) { case SwFrameFormat::HORI_L2R: @@ -885,28 +891,28 @@ void SwAnchoredDrawObject::SetPositioningAttr() // --> #i71182# // only change position - do not lose other attributes - SwFormatHoriOrient aHori( GetFrameFormat().GetHoriOrient() ); + SwFormatHoriOrient aHori(pObjFormat->GetHoriOrient()); if (nHoriPos != aHori.GetPos()) { aHori.SetPos( nHoriPos ); InvalidateObjRectWithSpaces(); - GetFrameFormat().SetFormatAttr( aHori ); + pObjFormat->SetFormatAttr(aHori); } - SwFormatVertOrient aVert( GetFrameFormat().GetVertOrient() ); + SwFormatVertOrient aVert(pObjFormat->GetVertOrient()); if (nVertPos != aVert.GetPos()) { aVert.SetPos( nVertPos ); InvalidateObjRectWithSpaces(); - GetFrameFormat().SetFormatAttr( aVert ); + pObjFormat->SetFormatAttr(aVert); } // --> #i36010# - set layout direction of the position - GetFrameFormat().SetPositionLayoutDir( + pObjFormat->SetPositionLayoutDir( text::PositionLayoutDir::PositionInLayoutDirOfAnchor ); } // --> #i65798# - also for as-character anchored objects // --> #i45952# - indicate that position // attributes are set now. - static_cast<SwDrawFrameFormat&>(GetFrameFormat()).PosAttrSet(); + static_cast<SwDrawFrameFormat*>(pObjFormat)->PosAttrSet(); } void SwAnchoredDrawObject::NotifyBackground( SwPageFrame* _pPageFrame, diff --git a/sw/source/core/layout/anchoredobject.cxx b/sw/source/core/layout/anchoredobject.cxx index 42e7dd39fc..a74438afb3 100644 --- a/sw/source/core/layout/anchoredobject.cxx +++ b/sw/source/core/layout/anchoredobject.cxx @@ -32,6 +32,7 @@ #include <layouter.hxx> #include <osl/diagnose.h> #include <flyfrms.hxx> +#include <dcontact.hxx> using namespace ::com::sun::star; @@ -215,7 +216,7 @@ void SwAnchoredObject::CheckCharRectAndTopOfLine( GetAnchorFrame()->IsTextFrame()) ) return; - const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rAnch = GetFrameFormat()->GetAnchor(); if ( !((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) && rAnch.GetAnchorNode()) ) return; @@ -262,8 +263,9 @@ void SwAnchoredObject::CheckCharRect( const SwFormatAnchor& _rAnch, { SwRectFnSet aRectFnSet(&_rAnchorCharFrame); // determine positioning and alignment - SwFormatVertOrient aVert( GetFrameFormat().GetVertOrient() ); - SwFormatHoriOrient aHori( GetFrameFormat().GetHoriOrient() ); + const SwFrameFormat* pObjFormat = GetFrameFormat(); + SwFormatVertOrient aVert( pObjFormat->GetVertOrient() ); + SwFormatHoriOrient aHori( pObjFormat->GetHoriOrient() ); // check for anchor character rectangle changes for certain // positionings and alignments // add condition to invalidate position, @@ -316,7 +318,7 @@ void SwAnchoredObject::CheckTopOfLine( const SwFormatAnchor& _rAnch, return; // check alignment for invalidation of position - if ( GetFrameFormat().GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE ) + if ( GetFrameFormat()->GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE ) { // #i26945#, #i35911# - unlock position of // anchored object, if it isn't registered at the page, @@ -373,7 +375,7 @@ void SwAnchoredObject::UpdateLayoutDir() nLayoutDir = SwFrameFormat::HORI_R2L; } } - GetFrameFormat().SetLayoutDir( nLayoutDir ); + GetFrameFormat()->SetLayoutDir( nLayoutDir ); } /** method to perform necessary invalidations for the positioning of @@ -408,29 +410,31 @@ bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() const { bool bRet( false ); - const SwFrameFormat& rObjFormat = GetFrameFormat(); - - // --> #i3317# - add condition <IsTmpConsiderWrapInfluence()> - // --> #i55204# - // - correction: wrapping style influence has been considered, if condition - // <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type - // or its wrapping style. - if ( IsTmpConsiderWrapInfluence() ) - { - bRet = true; - } - else if ( rObjFormat.getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ) + if (const SwFrameFormat* pObjFormat = GetFrameFormat()) { - const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor(); - if ( ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) || - (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)) && - rObjFormat.GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH ) + // --> #i3317# - add condition <IsTmpConsiderWrapInfluence()> + // --> #i55204# + // - correction: wrapping style influence has been considered, if condition + // <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type + // or its wrapping style. + if (IsTmpConsiderWrapInfluence()) { - // --> #i34520# - text also wraps around anchored - // objects in the layer Hell - see the text formatting. - // Thus, it hasn't to be checked here. bRet = true; } + else if (pObjFormat->getIDocumentSettingAccess().get( + DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION)) + { + const SwFormatAnchor& rAnchor = pObjFormat->GetAnchor(); + if (((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) + || (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)) + && pObjFormat->GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH) + { + // --> #i34520# - text also wraps around anchored + // objects in the layer Hell - see the text formatting. + // Thus, it hasn't to be checked here. + bRet = true; + } + } } return bRet; @@ -567,18 +571,22 @@ const SwRect& SwAnchoredObject::GetObjRectWithSpaces() const if ( !mbObjRectWithSpacesValid ) { maObjRectWithSpaces = GetObjBoundRect(); - const SwFrameFormat& rFormat = GetFrameFormat(); - const SvxULSpaceItem& rUL = rFormat.GetULSpace(); - const SvxLRSpaceItem& rLR = rFormat.GetLRSpace(); + if (const SwFrameFormat* pFormat = GetFrameFormat()) { - maObjRectWithSpaces.Top ( std::max( maObjRectWithSpaces.Top() - tools::Long(rUL.GetUpper()), tools::Long(0) )); - maObjRectWithSpaces.Left( std::max( maObjRectWithSpaces.Left()- rLR.GetLeft(), tools::Long(0) )); - maObjRectWithSpaces.AddHeight(rUL.GetLower() ); - maObjRectWithSpaces.AddWidth(rLR.GetRight() ); - } + const SvxULSpaceItem& rUL = pFormat->GetULSpace(); + const SvxLRSpaceItem& rLR = pFormat->GetLRSpace(); + { + maObjRectWithSpaces.Top(std::max( + maObjRectWithSpaces.Top() - tools::Long(rUL.GetUpper()), tools::Long(0))); + maObjRectWithSpaces.Left( + std::max(maObjRectWithSpaces.Left() - rLR.GetLeft(), tools::Long(0))); + maObjRectWithSpaces.AddHeight(rUL.GetLower()); + maObjRectWithSpaces.AddWidth(rLR.GetRight()); + } - mbObjRectWithSpacesValid = true; - maLastObjRect = GetObjRect(); + mbObjRectWithSpacesValid = true; + maLastObjRect = GetObjRect(); + } } return maObjRectWithSpaces; @@ -617,7 +625,7 @@ void SwAnchoredObject::UpdateObjInSortedList() if(!GetAnchorFrame()) return; - if ( GetFrameFormat().getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ) + if ( GetFrameFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ) { // invalidate position of all anchored objects at anchor frame if ( GetAnchorFrame()->GetDrawObjs() ) @@ -652,7 +660,7 @@ void SwAnchoredObject::UpdateObjInSortedList() // update its position in the sorted object list of its page frame // note: as-character anchored object aren't registered at a page frame if ( GetPageFrame() && GetPageFrame()->GetSortedObjs() && - GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR ) + GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR ) { GetPageFrame()->GetSortedObjs()->Update( *this ); } @@ -709,39 +717,43 @@ SwTextFrame* SwAnchoredObject::FindAnchorCharFrame() // --> #i44339# - check, if anchor frame exists. if ( mpAnchorFrame ) { - const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor(); - if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) || - (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)) + if (const SwFrameFormat* pFormat = GetFrameFormat()) { - SwTextFrame *const pFrame(static_cast<SwTextFrame*>(AnchorFrame())); - TextFrameIndex const nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor())); - pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset); - } - else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame()) - { - // See if this fly is split. If so, then the anchor is also split. All anchors are - // empty, except the last follow. - if (pFlyFrame->IsFlySplitAllowed()) + const SwFormatAnchor& rAnch = pFormat->GetAnchor(); + if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) + || (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)) + { + SwTextFrame* const pFrame(static_cast<SwTextFrame*>(AnchorFrame())); + TextFrameIndex const nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor())); + pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset); + } + else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame()) { - auto pFlyAtContentFrame = static_cast<SwFlyAtContentFrame*>(pFlyFrame); - SwFlyAtContentFrame* pFly = pFlyAtContentFrame; - SwTextFrame* pAnchor = static_cast<SwTextFrame*>(AnchorFrame()); - // If we have to jump back N frames to find the master fly, then we have to step N - // frames from the master anchor to reach the correct follow anchor. - while (pFly->GetPrecede()) + // See if this fly is split. If so, then the anchor is also split. All anchors are + // empty, except the last follow. + if (pFlyFrame->IsFlySplitAllowed()) { - pFly = pFly->GetPrecede(); - if (!pAnchor) + auto pFlyAtContentFrame = static_cast<SwFlyAtContentFrame*>(pFlyFrame); + SwFlyAtContentFrame* pFly = pFlyAtContentFrame; + SwTextFrame* pAnchor = static_cast<SwTextFrame*>(AnchorFrame()); + // If we have to jump back N frames to find the master fly, then we have to step N + // frames from the master anchor to reach the correct follow anchor. + while (pFly->GetPrecede()) { - SAL_WARN("sw.layout", "SwAnchoredObject::FindAnchorCharFrame: fly chain " - "length is longer then anchor chain length"); - break; + pFly = pFly->GetPrecede(); + if (!pAnchor) + { + SAL_WARN("sw.layout", + "SwAnchoredObject::FindAnchorCharFrame: fly chain " + "length is longer then anchor chain length"); + break; + } + pAnchor = pAnchor->GetFollow(); + } + if (pAnchor) + { + pAnchorCharFrame = pAnchor; } - pAnchor = pAnchor->GetFollow(); - } - if (pAnchor) - { - pAnchorCharFrame = pAnchor; } } } @@ -758,7 +770,9 @@ SwTextFrame* SwAnchoredObject::FindAnchorCharFrame() */ bool SwAnchoredObject::IsFormatPossible() const { - return GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetDrawObj()->GetLayer() ); + if (const SwFrameFormat* pFormat = GetFrameFormat()) + return pFormat->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetDrawObj()->GetLayer() ); + return false; } bool SwAnchoredObject::IsDraggingOffPageAllowed(const SwFrameFormat* pFrameFormat) @@ -777,7 +791,7 @@ void SwAnchoredObject::SetTmpConsiderWrapInfluence( const bool _bTmpConsiderWrap // --> #i35911# if ( mbTmpConsiderWrapInfluence ) { - SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrameFormat().GetDoc()), + SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrameFormat()->GetDoc()), *this ); } } @@ -787,7 +801,7 @@ void SwAnchoredObject::ClearTmpConsiderWrapInfluence() mbTmpConsiderWrapInfluence = false; mbClearedEnvironment = false; SetClearedEnvironment( false ); - SwLayouter::RemoveObjForTmpConsiderWrapInfluence( *(GetFrameFormat().GetDoc()), + SwLayouter::RemoveObjForTmpConsiderWrapInfluence( *(GetFrameFormat()->GetDoc()), *this ); } void SwAnchoredObject::SetTmpConsiderWrapInfluenceOfOtherObjs() diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx index 2a1ab80763..5e95d1aaf7 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -3121,7 +3121,7 @@ void SwFlyFrameFormat::MakeFrames() // #i28701# - consider changed type of // <SwSortedObjs> entries. if( pObj->DynCastFlyFrame() != nullptr && - (&pObj->GetFrameFormat()) == this ) + (pObj->GetFrameFormat()) == this ) { bAdd = false; break; diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index 4d4b2de289..c2bbdd8904 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -1131,18 +1131,18 @@ void SwContentFrame::MakePrtArea( const SwBorderAttrs &rAttrs ) // #i28701# - consider changed type of // <SwSortedObjs> entries SwAnchoredObject* pObj = (*GetDrawObjs())[i]; - const SwFrameFormat& rFormat = pObj->GetFrameFormat(); + const SwFrameFormat* pFormat = pObj->GetFrameFormat(); const bool bFly = pObj->DynCastFlyFrame() != nullptr; if ((bFly && (FAR_AWAY == pObj->GetObjRect().Width())) - || rFormat.GetFrameSize().GetWidthPercent()) + || pFormat->GetFrameSize().GetWidthPercent()) { continue; } - if ( RndStdIds::FLY_AS_CHAR == rFormat.GetAnchor().GetAnchorId() ) + if ( RndStdIds::FLY_AS_CHAR == pFormat->GetAnchor().GetAnchorId() ) { nMinWidth = std::max( nMinWidth, - bFly ? rFormat.GetFrameSize().GetWidth() + bFly ? pFormat->GetFrameSize().GetWidth() : pObj->GetObjRect().Width() ); } } diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index 981736de70..da509e2a6b 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -217,7 +217,7 @@ bool IsNextContentFullPage(const SwFrame& rThis) continue; } - const SwFormatSurround& rSurround = pDrawObj->GetFrameFormat().GetSurround(); + const SwFormatSurround& rSurround = pDrawObj->GetFrameFormat()->GetSurround(); if (rSurround.GetSurround() != text::WrapTextMode_NONE) { continue; @@ -379,10 +379,10 @@ sal_uInt8 SwFlowFrame::BwdMoveNecessary( const SwPageFrame *pPage, const SwRect { SwAnchoredObject* pObj = rObjs[i]; - const SwFrameFormat& rFormat = pObj->GetFrameFormat(); + const SwFrameFormat* pFormat = pObj->GetFrameFormat(); const SwRect aRect( pObj->GetObjRect() ); if ( aRect.Overlaps( rRect ) && - rFormat.GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH ) + pFormat->GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH ) { if( m_rThis.IsLayoutFrame() && //Fly Lower of This? Is_Lower_Of( &m_rThis, pObj->GetDrawObj() ) ) @@ -404,10 +404,10 @@ sal_uInt8 SwFlowFrame::BwdMoveNecessary( const SwPageFrame *pPage, const SwRect // flow, because then I wouldn't evade it. if ( ::IsFrameInSameContext( pAnchor, &m_rThis ) ) { - if ( rFormat.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA ) + if ( pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA ) { // The index of the other one can be retrieved using the anchor attribute. - SwNodeOffset nTmpIndex = rFormat.GetAnchor().GetAnchorNode()->GetIndex(); + SwNodeOffset nTmpIndex = pFormat->GetAnchor().GetAnchorNode()->GetIndex(); // Now we're going to check whether the current paragraph before // the anchor of the displacing object sits in the text. If this // is the case, we don't try to evade it. @@ -1224,13 +1224,13 @@ bool SwFlowFrame::IsPrevObjMove() const // text flow to the next layout frame for (SwAnchoredObject* pObj : *pPre->GetDrawObjs()) { - + const SwFrameFormat* pObjFormat = pObj->GetFrameFormat(); // Do not consider hidden objects // i#26945 - do not consider object, which // doesn't follow the text flow. - if ( pObj->GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( + if ( pObjFormat->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( pObj->GetDrawObj()->GetLayer() ) && - pObj->GetFrameFormat().GetFollowTextFlow().GetValue() ) + pObjFormat->GetFollowTextFlow().GetValue() ) { const SwLayoutFrame* pVertPosOrientFrame = pObj->GetVertPosOrientFrame(); if ( pVertPosOrientFrame && diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index d23c30a0aa..db50a42de0 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -43,6 +43,7 @@ #include <svx/svdoashp.hxx> #include <svx/svdpage.hxx> #include <layouter.hxx> +#include <layact.hxx> #include <pagefrm.hxx> #include <rootfrm.hxx> #include <viewimp.hxx> @@ -99,10 +100,10 @@ SwTwips GetFlyAnchorBottom(SwFlyFrame* pFly, const SwFrame& rAnchor) return 0; } - const auto& rFrameFormat = pFly->GetFrameFormat(); - const IDocumentSettingAccess& rIDSA = rFrameFormat.getIDocumentSettingAccess(); + const auto* pFrameFormat = pFly->GetFrameFormat(); + const IDocumentSettingAccess& rIDSA = pFrameFormat->getIDocumentSettingAccess(); // Allow overlap with bottom margin / footer only in case we're relative to the page frame. - bool bVertPageFrame = rFrameFormat.GetVertOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME; + bool bVertPageFrame = pFrameFormat->GetVertOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME; bool bInBody = rAnchor.IsInDocBody(); bool bLegacy = rIDSA.get(DocumentSettingId::TAB_OVER_MARGIN) && (bVertPageFrame || !bInBody); if (bLegacy) @@ -1271,7 +1272,7 @@ void SwFlyFrame::ChgRelPos( const Point &rNewPos ) const SwTextFrame *pAutoFrame = nullptr; // #i34948# - handle also at-page and at-fly anchored // Writer fly frames - const RndStdIds eAnchorType = GetFrameFormat().GetAnchor().GetAnchorId(); + const RndStdIds eAnchorType = GetFrameFormat()->GetAnchor().GetAnchorId(); if ( eAnchorType == RndStdIds::FLY_AT_PAGE ) { aVert.SetVertOrient( text::VertOrientation::NONE ); @@ -1741,6 +1742,10 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl ) if (!SwObjectFormatter::FormatObj(*pAnchoredObj, pAnchorFrame, pAnchorPageFrame, rShell.Imp()->IsAction() ? &rShell.Imp()->GetLayAction() : nullptr)) { + if (rShell.Imp()->IsAction() && rShell.Imp()->GetLayAction().IsAgain()) + { // tdf#159015 will always fail, don't loop + return; + } bRestartLayoutProcess = true; break; } @@ -1759,13 +1764,13 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl ) { OSL_FAIL( "::CalcContent(..) - loop detected, perform attribute changes to avoid the loop" ); // Prevent oscillation - SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - SwFormatSurround aAttr( rFormat.GetSurround() ); + SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + SwFormatSurround aAttr( pFormat->GetSurround() ); if( css::text::WrapTextMode_THROUGH != aAttr.GetSurround() ) { // When on auto position, we can only set it to // flow through - if ((rFormat.GetAnchor().GetAnchorId() == + if ((pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR) && (css::text::WrapTextMode_PARALLEL == aAttr.GetSurround())) @@ -1776,9 +1781,9 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl ) { aAttr.SetSurround( css::text::WrapTextMode_PARALLEL ); } - rFormat.LockModify(); - rFormat.SetFormatAttr( aAttr ); - rFormat.UnlockModify(); + pFormat->LockModify(); + pFormat->SetFormatAttr( aAttr ); + pFormat->UnlockModify(); } } else @@ -2054,7 +2059,7 @@ bool SwFlyFrame::IsShowUnfloatButton(SwWrtShell* pWrtSh) const if (pWrtSh->GetViewOptions()->IsReadonly()) return false; - const SdrObject *pObj = GetFrameFormat().FindRealSdrObject(); + const SdrObject *pObj = GetFrameFormat()->FindRealSdrObject(); if (pObj == nullptr) return false; @@ -2594,12 +2599,15 @@ void SwFrame::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ) { // Notify accessible layout. #if !ENABLE_WASM_STRIP_ACCESSIBILITY - SwViewShell* pSh = getRootFrame()->GetCurrShell(); - if( pSh ) + if (!mbInDtor) { - SwRootFrame* pLayout = getRootFrame(); - if (pLayout && pLayout->IsAnyShellAccessible()) - pSh->Imp()->DisposeAccessibleObj(_rToRemoveObj.GetDrawObj(), false); + SwViewShell* pSh = getRootFrame()->GetCurrShell(); + if (pSh) + { + SwRootFrame* pLayout = getRootFrame(); + if (pLayout && pLayout->IsAnyShellAccessible()) + pSh->Imp()->DisposeAccessibleObj(_rToRemoveObj.GetDrawObj(), false); + } } #endif @@ -2631,7 +2639,7 @@ void SwFrame::InvalidateObjs( const bool _bNoInvaOfAsCharAnchoredObjs ) for (SwAnchoredObject* pAnchoredObj : *GetDrawObjs()) { if ( _bNoInvaOfAsCharAnchoredObjs && - (pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() + (pAnchoredObj->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) ) { continue; @@ -2738,7 +2746,7 @@ void SwLayoutFrame::NotifyLowerObjs( const bool _bUnlockPosOfObjs ) bool isPositionedByHF(false); if (IsHeaderFrame() || IsFooterFrame()) { - auto const nO(pObj->GetFrameFormat().GetVertOrient().GetRelationOrient()); + auto const nO(pObj->GetFrameFormat()->GetVertOrient().GetRelationOrient()); if (nO == text::RelOrientation::PAGE_PRINT_AREA || nO == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM || nO == text::RelOrientation::PAGE_PRINT_AREA_TOP) @@ -3093,17 +3101,17 @@ void SwFlyFrame::InvalidateObjPos() InvalidateObjRectWithSpaces(); } -SwFrameFormat& SwFlyFrame::GetFrameFormat() +SwFrameFormat* SwFlyFrame::GetFrameFormat() { OSL_ENSURE( GetFormat(), "<SwFlyFrame::GetFrameFormat()> - missing frame format -> crash." ); - return *GetFormat(); + return GetFormat(); } -const SwFrameFormat& SwFlyFrame::GetFrameFormat() const +const SwFrameFormat* SwFlyFrame::GetFrameFormat() const { OSL_ENSURE( GetFormat(), "<SwFlyFrame::GetFrameFormat()> - missing frame format -> crash." ); - return *GetFormat(); + return GetFormat(); } SwRect SwFlyFrame::GetObjRect() const diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx index a53b8841f8..2ed6fbf089 100644 --- a/sw/source/core/layout/flycnt.cxx +++ b/sw/source/core/layout/flycnt.cxx @@ -162,13 +162,13 @@ void SwFlyAtContentFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rH // of the given fly frame format is registered. if(bFound && pContent && pContent->GetDrawObjs()) { - SwFrameFormat* pMyFlyFrameFormat(&GetFrameFormat()); + SwFrameFormat* pMyFlyFrameFormat(GetFrameFormat()); SwSortedObjs &rObjs = *pContent->GetDrawObjs(); for(SwAnchoredObject* rObj : rObjs) { SwFlyFrame* pFlyFrame = rObj->DynCastFlyFrame(); if (pFlyFrame && - &(pFlyFrame->GetFrameFormat()) == pMyFlyFrameFormat) + pFlyFrame->GetFrameFormat() == pMyFlyFrameFormat) { bFound = false; break; @@ -330,7 +330,8 @@ bool SwOszControl::ChkOsz() |*/ void SwFlyAtContentFrame::MakeAll(vcl::RenderContext* pRenderContext) { - if ( !GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ) + const SwDoc& rDoc = *(GetFormat()->GetDoc()); + if (!rDoc.getIDocumentDrawModelAccess().IsVisibleLayerId(GetVirtDrawObj()->GetLayer())) { return; } @@ -450,7 +451,6 @@ void SwFlyAtContentFrame::MakeAll(vcl::RenderContext* pRenderContext) SwTextFrame* pAnchorTextFrame( static_cast<SwTextFrame*>(AnchorFrame()) ); bool bInsert( true ); sal_uInt32 nAnchorFrameToPageNum( 0 ); - const SwDoc& rDoc = *(GetFrameFormat().GetDoc()); if ( SwLayouter::FrameMovedFwdByObjPos( rDoc, *pAnchorTextFrame, nAnchorFrameToPageNum ) ) { @@ -518,7 +518,7 @@ void SwFlyAtContentFrame::MakeAll(vcl::RenderContext* pRenderContext) !bConsiderWrapInfluenceDueToOverlapPrevCol && // #i40444# !bConsiderWrapInfluenceDueToMovedFwdAnchor && - GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ); + rDoc.getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ); // #i3317# - instead of attribute change apply // temporarily the 'straightforward positioning process'. diff --git a/sw/source/core/layout/flyincnt.cxx b/sw/source/core/layout/flyincnt.cxx index 7fb8f93f16..36c7837e95 100644 --- a/sw/source/core/layout/flyincnt.cxx +++ b/sw/source/core/layout/flyincnt.cxx @@ -191,7 +191,7 @@ void SwFlyInContentFrame::MakeObjPos() void SwFlyInContentFrame::ActionOnInvalidation( const InvalidationType _nInvalid ) { if ( INVALID_POS == _nInvalid || INVALID_ALL == _nInvalid ) - AnchorFrame()->Prepare( PrepareHint::FlyFrameAttributesChanged, &GetFrameFormat() ); + AnchorFrame()->Prepare( PrepareHint::FlyFrameAttributesChanged, GetFrameFormat() ); } void SwFlyInContentFrame::NotifyBackground( SwPageFrame *, const SwRect& rRect, diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx index 457a0d41bb..7ac95d65e0 100644 --- a/sw/source/core/layout/flylay.cxx +++ b/sw/source/core/layout/flylay.cxx @@ -153,7 +153,7 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) if ( !IsNoMoveOnCheckClip() && !( PositionLocked() && GetAnchorFrame()->IsInFly() && - GetFrameFormat().GetFollowTextFlow().GetValue() ) ) + GetFrameFormat()->GetFollowTextFlow().GetValue() ) ) { setFrameAreaPositionValid(false); } @@ -1100,7 +1100,7 @@ void SwPageFrame::AppendDrawObjToPage( SwAnchoredObject& _rNewObj ) pFlyFrame->GetVirtDrawObj()->SetOrdNum( nNewNum ); } - if ( RndStdIds::FLY_AS_CHAR == _rNewObj.GetFrameFormat().GetAnchor().GetAnchorId() ) + if ( RndStdIds::FLY_AS_CHAR == _rNewObj.GetFrameFormat()->GetAnchor().GetAnchorId() ) { return; } @@ -1140,8 +1140,9 @@ void SwPageFrame::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj ) } if ( GetUpper() ) { - if (RndStdIds::FLY_AS_CHAR != - _rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId()) + const SwFrameFormat* pObjFormat = _rToRemoveObj.GetFrameFormat(); + if (pObjFormat + && RndStdIds::FLY_AS_CHAR != pObjFormat->GetAnchor().GetAnchorId()) { static_cast<SwRootFrame*>(GetUpper())->SetSuperfluous(); InvalidatePage(); @@ -1454,63 +1455,67 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove ) } else { - const SwDrawContact *pC = static_cast<const SwDrawContact*>(GetUserCall(pSdrObj)); - const SwFrameFormat *pFormat = pC->GetFormat(); - const SwFormatAnchor &rAnch = pFormat->GetAnchor(); - if ( RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId() ) + if (const SwDrawContact* pC = static_cast<const SwDrawContact*>(GetUserCall(pSdrObj))) { - const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj ); - if( !pAnchorFrame ) + const SwFrameFormat* pFormat = pC->GetFormat(); + const SwFormatAnchor& rAnch = pFormat->GetAnchor(); + if (RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId()) { - OSL_FAIL( "<::CalcClipRect(..)> - missing anchor frame." ); - const_cast<SwDrawContact*>(pC)->ConnectToLayout(); - pAnchorFrame = pC->GetAnchorFrame(); - } - const SwFrame* pUp = pAnchorFrame->GetUpper(); - rRect = pUp->getFramePrintArea(); - rRect += pUp->getFrameArea().Pos(); - SwRectFnSet aRectFnSet(pAnchorFrame); - tools::Long nHeight = (9*aRectFnSet.GetHeight(rRect))/10; - tools::Long nTop; - const SvxULSpaceItem &rUL = pFormat->GetULSpace(); - SwRect aSnapRect( pSdrObj->GetSnapRect() ); - tools::Long nTmpH = 0; - if( bMove ) - { - nTop = aRectFnSet.YInc( aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().X() : - pSdrObj->GetAnchorPos().Y(), -nHeight ); - tools::Long nWidth = aRectFnSet.GetWidth(aSnapRect); - aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ? - pSdrObj->GetAnchorPos().Y() : - pSdrObj->GetAnchorPos().X(), nWidth ); - } - else - { - // #i26791# - value of <nTmpH> is needed to - // calculate value of <nTop>. - nTmpH = aRectFnSet.IsVert() ? pSdrObj->GetCurrentBoundRect().GetWidth() : - pSdrObj->GetCurrentBoundRect().GetHeight(); - nTop = aRectFnSet.YInc( aRectFnSet.GetTop(aSnapRect), - rUL.GetLower() + nTmpH - nHeight ); - } - nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper(); - aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight ); - } - else - { - // restrict clip rectangle for drawing - // objects in header/footer to the page frame. - // #i26791# - const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj ); - if ( pAnchorFrame && pAnchorFrame->FindFooterOrHeader() ) - { - // clip frame is the page frame the header/footer is on. - const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame(); - rRect = pClipFrame->getFrameArea(); + const SwFrame* pAnchorFrame = pC->GetAnchorFrame(pSdrObj); + if (!pAnchorFrame) + { + OSL_FAIL("<::CalcClipRect(..)> - missing anchor frame."); + const_cast<SwDrawContact*>(pC)->ConnectToLayout(); + pAnchorFrame = pC->GetAnchorFrame(); + } + const SwFrame* pUp = pAnchorFrame->GetUpper(); + rRect = pUp->getFramePrintArea(); + rRect += pUp->getFrameArea().Pos(); + SwRectFnSet aRectFnSet(pAnchorFrame); + tools::Long nHeight = (9 * aRectFnSet.GetHeight(rRect)) / 10; + tools::Long nTop; + const SvxULSpaceItem& rUL = pFormat->GetULSpace(); + SwRect aSnapRect(pSdrObj->GetSnapRect()); + tools::Long nTmpH = 0; + if (bMove) + { + nTop = aRectFnSet.YInc(aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().X() + : pSdrObj->GetAnchorPos().Y(), + -nHeight); + tools::Long nWidth = aRectFnSet.GetWidth(aSnapRect); + aRectFnSet.SetLeftAndWidth(rRect, + aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().Y() + : pSdrObj->GetAnchorPos().X(), + nWidth); + } + else + { + // #i26791# - value of <nTmpH> is needed to + // calculate value of <nTop>. + nTmpH = aRectFnSet.IsVert() ? pSdrObj->GetCurrentBoundRect().GetWidth() + : pSdrObj->GetCurrentBoundRect().GetHeight(); + nTop = aRectFnSet.YInc(aRectFnSet.GetTop(aSnapRect), + rUL.GetLower() + nTmpH - nHeight); + } + nHeight = 2 * nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper(); + aRectFnSet.SetTopAndHeight(rRect, nTop, nHeight); } else { - bRet = false; + // restrict clip rectangle for drawing + // objects in header/footer to the page frame. + // #i26791# + const SwFrame* pAnchorFrame = pC->GetAnchorFrame(pSdrObj); + if (pAnchorFrame && pAnchorFrame->FindFooterOrHeader()) + { + // clip frame is the page frame the header/footer is on. + const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame(); + rRect = pClipFrame->getFrameArea(); + } + else + { + bRet = false; + } } } } diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index c3fa35fcdc..eeab5c60c1 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1025,7 +1025,7 @@ void SwContentNotify::ImplDestroy() SwSortedObjs* pObjs = pMasterFrame->GetDrawObjs(); for (SwAnchoredObject* pAnchoredObj : *pObjs) { - if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() + if ( pAnchoredObj->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR ) { pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrame->IsEmpty() ); @@ -2835,7 +2835,7 @@ static void lcl_RemoveObjsFromPage( SwFrame* _pFrame ) // #115759# - remove also drawing objects from page else if ( auto pDrawObj = dynamic_cast<SwAnchoredDrawObject*>( pObj) ) { - if (pObj->GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) + if (pObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { if (SwPageFrame *pPg = pObj->GetPageFrame()) pPg->RemoveDrawObjFromPage( *pDrawObj ); @@ -2996,7 +2996,7 @@ static void lcl_AddObjsToPage( SwFrame* _pFrame, SwPageFrame* _pPage ) // #115759# - remove also drawing objects from page else if ( dynamic_cast<const SwAnchoredDrawObject*>( pObj) != nullptr ) { - if (pObj->GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) + if (pObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { pObj->InvalidateObjPos(); _pPage->AppendDrawObjToPage( @@ -3404,8 +3404,10 @@ void Notify_Background( const SdrObject* pObj, else { pFlyFrame = nullptr; - pAnchor = const_cast<SwFrame*>( - GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrame() ); + if (SwDrawContact* pC = static_cast<SwDrawContact*>(GetUserCall(pObj))) + pAnchor = const_cast<SwFrame*>(pC->GetAnchoredObj(pObj)->GetAnchorFrame()); + else + return; } if( PrepareHint::FlyFrameLeave != eHint && pAnchor->IsInFly() ) pArea = pAnchor->FindFlyFrame(); @@ -3879,7 +3881,32 @@ SwFrame* GetFrameOfModify(SwRootFrame const*const pLayout, sw::BroadcastingModif } while( bClientIterChanged ); if( pPos && pMinFrame && pMinFrame->IsTextFrame() ) - return static_cast<SwTextFrame*>(pMinFrame)->GetFrameAtPos( *pPos ); + { + SwTextFrame * pAtPos(static_cast<SwTextFrame*>(pMinFrame)->GetFrameAtPos(*pPos)); + if (!pViewPosAndCalcFrame) + { + return pAtPos; + } + TextFrameIndex nPos(pAtPos->MapModelToViewPos(*pPos)); + SwPageFrame const*const pPage(pAtPos->getRootFrame()->GetPageAtPos( + pViewPosAndCalcFrame->first, nullptr, true)); + SwFrame * pOnPage(pAtPos); // if all else fails return first one + ++nPos; // follow field portions are on follow frames that have mnOffset + // already incremented past the field, need to check that index too + while (pAtPos && pAtPos->GetOffset() <= nPos) + { + if (pAtPos->getFrameArea().Contains(pViewPosAndCalcFrame->first)) + { + return pAtPos; + } + if (pAtPos->FindPageFrame() == pPage) + { + pOnPage = pAtPos; + } + pAtPos = pAtPos->GetFollow(); + } + return pOnPage; + } return pMinFrame; } diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx index 747470129c..a705ef2511 100644 --- a/sw/source/core/layout/layact.cxx +++ b/sw/source/core/layout/layact.cxx @@ -1673,7 +1673,7 @@ bool SwLayAction::FormatContent(SwPageFrame *const pPage) assert(pAnchorPage); if (pAnchorPage != pPage && pPage->GetPhyPageNum() < pAnchorPage->GetPhyPageNum() - && pObj->GetFrameFormat().GetAnchor().GetAnchorId() + && pObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { moved.emplace_back(pObj, pAnchorPage); diff --git a/sw/source/core/layout/objectformattertxtfrm.cxx b/sw/source/core/layout/objectformattertxtfrm.cxx index 6b2503d40c..9a44b0df62 100644 --- a/sw/source/core/layout/objectformattertxtfrm.cxx +++ b/sw/source/core/layout/objectformattertxtfrm.cxx @@ -148,7 +148,7 @@ bool SwObjectFormatterTextFrame::DoFormatObj( SwAnchoredObject& _rAnchoredObj, _rAnchoredObj.RestartLayoutProcess() && !( _rAnchoredObj.PositionLocked() && _rAnchoredObj.GetAnchorFrame()->IsInFly() && - _rAnchoredObj.GetFrameFormat().GetFollowTextFlow().GetValue() ); + _rAnchoredObj.GetFrameFormat()->GetFollowTextFlow().GetValue() ); if ( bRestart ) { bSuccess = false; @@ -168,7 +168,7 @@ bool SwObjectFormatterTextFrame::DoFormatObj( SwAnchoredObject& _rAnchoredObj, if ( bSuccess && _rAnchoredObj.ConsiderObjWrapInfluenceOnObjPos() && ( _bCheckForMovedFwd || - _rAnchoredObj.GetFrameFormat().GetWrapInfluenceOnObjPos(). + _rAnchoredObj.GetFrameFormat()->GetWrapInfluenceOnObjPos(). // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE GetWrapInfluenceOnObjPos( true ) == // #i35017# - constant name has changed @@ -481,10 +481,11 @@ bool SwObjectFormatterTextFrame::DoFormatObjs() void SwObjectFormatterTextFrame::InvalidatePrevObjs( SwAnchoredObject& _rAnchoredObj ) { + const SwFrameFormat* pObjFormat = _rAnchoredObj.GetFrameFormat(); // invalidate all previous objects, whose wrapping influence on the object // positioning is <NONE_CONCURRENT_POSITIONED>. // Note: list of objects at anchor frame is sorted by this property. - if ( _rAnchoredObj.GetFrameFormat().GetWrapInfluenceOnObjPos(). + if (pObjFormat->GetWrapInfluenceOnObjPos(). // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE GetWrapInfluenceOnObjPos( true ) != // #i35017# - constant name has changed @@ -501,7 +502,7 @@ void SwObjectFormatterTextFrame::InvalidatePrevObjs( SwAnchoredObject& _rAnchore { --i; SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; - if ( pAnchoredObj->GetFrameFormat().GetWrapInfluenceOnObjPos(). + if (pObjFormat->GetWrapInfluenceOnObjPos(). // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE GetWrapInfluenceOnObjPos( true ) == // #i35017# - constant name has changed @@ -546,7 +547,7 @@ SwAnchoredObject* SwObjectFormatterTextFrame::GetFirstObjWithMovedFwdAnchor( { SwAnchoredObject* pAnchoredObj = GetCollectedObj(i); if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() && - pAnchoredObj->GetFrameFormat().GetWrapInfluenceOnObjPos(). + pAnchoredObj->GetFrameFormat()->GetWrapInfluenceOnObjPos(). // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE GetWrapInfluenceOnObjPos( true ) == _nWrapInfluenceOnPosition ) { @@ -648,8 +649,8 @@ bool SwObjectFormatterTextFrame::CheckMovedFwdCondition( // which will be on the next page. if ( !bAnchorIsMovedForward && _bAnchoredAtMasterBeforeFormatAnchor && - ((_rAnchoredObj.GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR) || - (_rAnchoredObj.GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA))) + ((_rAnchoredObj.GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR) || + (_rAnchoredObj.GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA))) { SwFrame* pAnchorFrame = _rAnchoredObj.GetAnchorFrameContainingAnchPos(); OSL_ENSURE( pAnchorFrame->IsTextFrame(), @@ -703,7 +704,7 @@ bool SwObjectFormatterTextFrame::CheckMovedFwdCondition( if ((pObjAnchorPage == &rFromPageFrame ? _boInFollow // same-page but will move forward : rFromPageFrame.GetPhyPageNum() < pObjAnchorPage->GetPhyPageNum()) - && pObj->GetFrameFormat().GetAnchor().GetAnchorId() + && pObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { if (pPageFrameOfAnchor->GetPhyPageNum() < pObjAnchorPage->GetPhyPageNum()) diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx index e70cb68469..bf4bcc45ea 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -1708,8 +1708,8 @@ void SwRootFrame::AssertPageFlys( SwPageFrame *pPage ) while ( pPage->GetSortedObjs() && i< pPage->GetSortedObjs()->size() ) { // #i28701# - SwFrameFormat& rFormat = (*pPage->GetSortedObjs())[i]->GetFrameFormat(); - const SwFormatAnchor &rAnch = rFormat.GetAnchor(); + SwFrameFormat* pFormat = (*pPage->GetSortedObjs())[i]->GetFrameFormat(); + const SwFormatAnchor &rAnch = pFormat->GetAnchor(); const sal_uInt16 nPg = rAnch.GetPageNum(); if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE) && nPg != pPage->GetPhyPageNum() ) @@ -1722,12 +1722,12 @@ void SwRootFrame::AssertPageFlys( SwPageFrame *pPage ) // It can move by itself. Just send a modify to its anchor attribute. #if OSL_DEBUG_LEVEL > 1 const size_t nCnt = pPage->GetSortedObjs()->size(); - rFormat.CallSwClientNotify(sw::LegacyModifyHint(nullptr, &rAnch)); + pFormat->CallSwClientNotify(sw::LegacyModifyHint(nullptr, &rAnch)); OSL_ENSURE( !pPage->GetSortedObjs() || nCnt != pPage->GetSortedObjs()->size(), "Object couldn't be reattached!" ); #else - rFormat.CallSwClientNotify(sw::LegacyModifyHint(nullptr, &rAnch)); + pFormat->CallSwClientNotify(sw::LegacyModifyHint(nullptr, &rAnch)); #endif // Do not increment index, in this case continue; @@ -1853,19 +1853,19 @@ void SwRootFrame::ImplCalcBrowseWidth() { // #i28701# SwAnchoredObject* pAnchoredObj = (*pFrame->GetDrawObjs())[i]; - const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); const bool bFly = pAnchoredObj->DynCastFlyFrame() != nullptr; if ((bFly && (FAR_AWAY == pAnchoredObj->GetObjRect().Width())) - || rFormat.GetFrameSize().GetWidthPercent()) + || pFormat->GetFrameSize().GetWidthPercent()) { continue; } tools::Long nWidth = 0; - switch ( rFormat.GetAnchor().GetAnchorId() ) + switch ( pFormat->GetAnchor().GetAnchorId() ) { case RndStdIds::FLY_AS_CHAR: - nWidth = bFly ? rFormat.GetFrameSize().GetWidth() : + nWidth = bFly ? pFormat->GetFrameSize().GetWidth() : pAnchoredObj->GetObjRect().Width(); break; case RndStdIds::FLY_AT_PARA: @@ -1877,8 +1877,8 @@ void SwRootFrame::ImplCalcBrowseWidth() // at position FAR_AWAY. if ( bFly ) { - nWidth = rFormat.GetFrameSize().GetWidth(); - const SwFormatHoriOrient &rHori = rFormat.GetHoriOrient(); + nWidth = pFormat->GetFrameSize().GetWidth(); + const SwFormatHoriOrient &rHori = pFormat->GetHoriOrient(); switch ( rHori.GetHoriOrient() ) { case text::HoriOrientation::NONE: @@ -2013,8 +2013,8 @@ static void lcl_MoveAllLowerObjs( SwFrame* pFrame, const Point& rOffset ) for (size_t i = 0; i < pSortedObj->size(); ++i) { SwAnchoredObject *const pAnchoredObj = (*pSortedObj)[i]; - const SwFrameFormat& rObjFormat = pAnchoredObj->GetFrameFormat(); - const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor(); + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatAnchor& rAnchor = pObjFormat->GetAnchor(); // all except from the as character anchored objects are moved // when processing the page frame: @@ -2070,7 +2070,7 @@ static void lcl_MoveAllLowerObjs( SwFrame* pFrame, const Point& rOffset ) pAnchoredDrawObj->SetLastObjRect( pAnchoredDrawObj->GetObjRect().SVRect() ); // clear contour cache - if ( pAnchoredDrawObj->GetFrameFormat().GetSurround().IsContour() ) + if ( pAnchoredDrawObj->GetFrameFormat()->GetSurround().IsContour() ) ClrContourCache( pAnchoredDrawObj->GetDrawObj() ); } // #i92511# diff --git a/sw/source/core/layout/sortedobjs.cxx b/sw/source/core/layout/sortedobjs.cxx index ce581bb663..e0c29d5180 100644 --- a/sw/source/core/layout/sortedobjs.cxx +++ b/sw/source/core/layout/sortedobjs.cxx @@ -78,12 +78,16 @@ struct ObjAnchorOrder const SwAnchoredObject* _pNewAnchoredObj ) { // get attributes of listed object - const SwFrameFormat& rFormatListed = _pListedAnchoredObj->GetFrameFormat(); - const SwFormatAnchor* pAnchorListed = &(rFormatListed.GetAnchor()); + const SwFrameFormat* pFormatListed = _pListedAnchoredObj->GetFrameFormat(); + if (!pFormatListed) + return false; + const SwFormatAnchor* pAnchorListed = &(pFormatListed->GetAnchor()); // get attributes of new object - const SwFrameFormat& rFormatNew = _pNewAnchoredObj->GetFrameFormat(); - const SwFormatAnchor* pAnchorNew = &(rFormatNew.GetAnchor()); + const SwFrameFormat* pFormatNew = _pNewAnchoredObj->GetFrameFormat(); + if (!pFormatNew) + return false; + const SwFormatAnchor* pAnchorNew = &(pFormatNew->GetAnchor()); // check for to-page anchored objects if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_PAGE) && @@ -156,15 +160,15 @@ struct ObjAnchorOrder // objects anchored at the same content and at the same content anchor // node position with the same anchor type // Thus, compare its wrapping style including its layer - const IDocumentDrawModelAccess& rIDDMA = rFormatListed.getIDocumentDrawModelAccess(); + const IDocumentDrawModelAccess& rIDDMA = pFormatListed->getIDocumentDrawModelAccess(); const SdrLayerID nHellId = rIDDMA.GetHellId(); const SdrLayerID nInvisibleHellId = rIDDMA.GetInvisibleHellId(); const bool bWrapThroughOrHellListed = - rFormatListed.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH || + pFormatListed->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH || _pListedAnchoredObj->GetDrawObj()->GetLayer() == nHellId || _pListedAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId; const bool bWrapThroughOrHellNew = - rFormatNew.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH || + pFormatNew->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH || _pNewAnchoredObj->GetDrawObj()->GetLayer() == nHellId || _pNewAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId; if ( bWrapThroughOrHellListed != bWrapThroughOrHellNew ) @@ -179,9 +183,9 @@ struct ObjAnchorOrder // objects anchored at the same content with a set text wrapping // Thus, compare wrap influences on object position const SwFormatWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosListed = - &(rFormatListed.GetWrapInfluenceOnObjPos()); + &(pFormatListed->GetWrapInfluenceOnObjPos()); const SwFormatWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosNew = - &(rFormatNew.GetWrapInfluenceOnObjPos()); + &(pFormatNew->GetWrapInfluenceOnObjPos()); // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true ) != pWrapInfluenceOnObjPosNew->GetWrapInfluenceOnObjPos( true ) ) diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index c1acc0c9e9..f757824561 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -286,12 +286,12 @@ static void lcl_InvalidateLowerObjs( SwLayoutFrame& _rLayoutFrame, // that anchored object is correctly positioned. pAnchoredObj->ClearCharRectAndTopOfLine(); pAnchoredObj->SetCurrRelPos( Point( 0, 0 ) ); - if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() - == RndStdIds::FLY_AS_CHAR ) + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + if (pObjFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) { pAnchoredObj->AnchorFrame() ->Prepare( PrepareHint::FlyFrameAttributesChanged, - &(pAnchoredObj->GetFrameFormat()) ); + pObjFormat ); } if ( pFly != nullptr ) { @@ -1451,7 +1451,102 @@ namespace return true; } -} + + auto IsAllHiddenSection(SwSectionFrame const& rSection) -> bool + { + for (SwFrame const* pFrame = rSection.Lower(); pFrame; pFrame = pFrame->GetNext()) + { + if (pFrame->IsColumnFrame()) + { + return false; // adds some padding + } + else if (pFrame->IsSctFrame()) + { + assert(false); // these aren't nested? + if (!IsAllHiddenSection(*static_cast<SwSectionFrame const*>(pFrame))) + { + return false; + } + } + else if (pFrame->IsTabFrame()) + { + return false; // presumably + } + else if (pFrame->IsTextFrame()) + { + if (!static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()) + { + return false; + } + } + } + return true; + } + + auto IsAllHiddenRow(SwRowFrame const& rRow, SwTabFrame const& rTab) -> bool; + + auto IsAllHiddenCell(SwCellFrame const& rCell, SwRowFrame const& rRow, SwTabFrame const& rTab) -> bool + { + for (SwFrame const* pFrame = rCell.Lower(); pFrame; pFrame = pFrame->GetNext()) + { + if (pFrame->IsRowFrame()) + { + if (!IsAllHiddenRow(*static_cast<SwRowFrame const*>(pFrame), rTab)) + { + return false; + } + } + else if (pFrame->IsSctFrame()) + { + if (!IsAllHiddenSection(*static_cast<SwSectionFrame const*>(pFrame))) + { + return false; + } + } + else if (pFrame->IsTabFrame()) + { + return false; // presumably + } + else if (pFrame->IsTextFrame()) + { + if (!static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()) + { + return false; + } + } + } + if (rTab.IsCollapsingBorders() && !rCell.Lower()->IsRowFrame()) + { + if (rRow.GetTopMarginForLowers() != 0 + || rRow.GetBottomMarginForLowers() != 0) + { + return false; + } + } + else + { + SwBorderAttrAccess border(SwFrame::GetCache(), &rCell); + if (border.Get()->CalcTop() != 0 || border.Get()->CalcBottom() != 0) + { + return false; + } + } + return true; + } + + auto IsAllHiddenRow(SwRowFrame const& rRow, SwTabFrame const& rTab) -> bool + { + for (SwFrame const* pCell = rRow.Lower(); pCell; pCell = pCell->GetNext()) + { + if (!IsAllHiddenCell(*static_cast<SwCellFrame const*>(pCell), rRow, rTab)) + { + return false; + } + } + return true; + } + +} // namespace void SwTabFrame::Join() { @@ -1471,11 +1566,20 @@ void SwTabFrame::Join() SwFrame* pPrv = GetLastLower(); SwTwips nHeight = 0; //Total height of the inserted rows as return value. + bool isAllHidden(true); while ( pRow ) { pNxt = pRow->GetNext(); nHeight += aRectFnSet.GetHeight(pRow->getFrameArea()); + if (nHeight != 0) + { + isAllHidden = false; + } + if (isAllHidden) + { + isAllHidden = IsAllHiddenRow(*static_cast<SwRowFrame *>(pRow), *this); + } pRow->RemoveFromLayout(); pRow->InvalidateAll_(); pRow->InsertBehind( this, pPrv ); @@ -1489,6 +1593,18 @@ void SwTabFrame::Join() SwFrame::DestroyFrame(pFoll); Grow( nHeight ); + + // In case the row does not have a height, Grow(nHeight) did nothing. + // If this is not invalidated, subsequent follows may never be joined. + // Try to guess if the height of the row will be 0. If the document + // was just loaded, it will be 0 in any case, but probably it's not a good + // idea to join *all* follows for a newly loaded document, it would be + // easier not to split the table in the first place; presumably it is split + // because that improves performance. + if (isAllHidden) + { + InvalidateSize_(); + } } static void SwInvalidatePositions( SwFrame *pFrame, tools::Long nBottom ) @@ -3180,6 +3296,7 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper, bool bShiftDown = css::text::WrapTextMode_NONE == nSurround; bool bSplitFly = pFly->IsFlySplitAllowed(); + const SwRect aFlyRectWithoutSpaces = pFly->GetObjRect(); if (!bShiftDown && bAddVerticalFlyOffsets) { if (nSurround == text::WrapTextMode_PARALLEL && isHoriOrientShiftDown) @@ -3194,7 +3311,6 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper, // Ignore spacing when determining the left/right edge of the fly, like // Word does. - const SwRect aFlyRectWithoutSpaces = pFly->GetObjRect(); basegfx::B1DRange aFlyRange(aRectFnSet.GetLeft(aFlyRectWithoutSpaces), aRectFnSet.GetRight(aFlyRectWithoutSpaces)); @@ -3257,9 +3373,16 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper, bool bFlyHoriOrientLeft = text::HoriOrientation::LEFT == rHori.GetHoriOrient(); if (bSplitFly && !bFlyHoriOrientLeft) { - // If a split fly is oriented "from left", we already checked if it has enough space on - // the right, so from-left and left means the same here. - bFlyHoriOrientLeft = rHori.GetHoriOrient() == text::HoriOrientation::NONE; + // Only shift to the right if we don't have enough space on the left. + SwTwips nTabWidth = getFramePrintArea().Width(); + SwTwips nWidthDeadline = aFlyRectWithoutSpaces.Left() + - pFly->GetAnchorFrame()->GetUpper()->getFrameArea().Left(); + if (nTabWidth > nWidthDeadline) + { + // If a split fly is oriented "from left", we already checked if it has enough space on + // the right, so from-left and left means the same here. + bFlyHoriOrientLeft = rHori.GetHoriOrient() == text::HoriOrientation::NONE; + } } if ((css::text::WrapTextMode_RIGHT == nSurround || css::text::WrapTextMode_PARALLEL == nSurround) @@ -4447,8 +4570,8 @@ tools::Long CalcHeightWithFlys( const SwFrame *pFrame ) { // OD 30.09.2003 #i18732# - only objects, which follow // the text flow have to be considered. - const SwFrameFormat& rFrameFormat = pAnchoredObj->GetFrameFormat(); - bool bFollowTextFlow = rFrameFormat.GetFollowTextFlow().GetValue(); + const SwFrameFormat* pFrameFormat = pAnchoredObj->GetFrameFormat(); + bool bFollowTextFlow = pFrameFormat->GetFollowTextFlow().GetValue(); bool bIsFarAway = pAnchoredObj->GetObjRect().Top() != FAR_AWAY; const SwPageFrame* pPageFrm = pTmp->FindPageFrame(); bool bIsAnchoredToTmpFrm = false; @@ -4456,14 +4579,14 @@ tools::Long CalcHeightWithFlys( const SwFrame *pFrame ) bIsAnchoredToTmpFrm = pAnchoredObj->GetPageFrame() == pPageFrm || (pPageFrm->GetFormatPage().GetPhyPageNum() == pAnchoredObj->GetPageFrame()->GetFormatPage().GetPhyPageNum() + 1); const bool bConsiderObj = - (rFrameFormat.GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) && + (pFrameFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) && bIsFarAway && bFollowTextFlow && bIsAnchoredToTmpFrm; - bool bWrapThrough = rFrameFormat.GetSurround().GetValue() == text::WrapTextMode_THROUGH; - bool bInBackground = !rFrameFormat.GetOpaque().GetValue(); + bool bWrapThrough = pFrameFormat->GetSurround().GetValue() == text::WrapTextMode_THROUGH; + bool bInBackground = !pFrameFormat->GetOpaque().GetValue(); // Legacy render requires in-background setting, the new mode does not. bool bConsiderFollowTextFlow = bInBackground - || !rFrameFormat.getIDocumentSettingAccess().get( + || !pFrameFormat->getIDocumentSettingAccess().get( DocumentSettingId::USE_FORMER_TEXT_WRAPPING); if (pFrame->IsInTab() && bFollowTextFlow && bWrapThrough && bConsiderFollowTextFlow) { @@ -4475,7 +4598,7 @@ tools::Long CalcHeightWithFlys( const SwFrame *pFrame ) if ( bConsiderObj ) { - const SwFormatFrameSize &rSz = rFrameFormat.GetFrameSize(); + const SwFormatFrameSize &rSz = pFrameFormat->GetFrameSize(); if( !rSz.GetHeightPercent() ) { const SwTwips nDistOfFlyBottomToAnchorTop = @@ -5428,7 +5551,7 @@ static bool lcl_ArrangeLowers( SwLayoutFrame *pLay, tools::Long lYStart, bool bI // from its anchor frame. bool bVertPosDepOnAnchor( true ); { - SwFormatVertOrient aVert( pAnchoredObj->GetFrameFormat().GetVertOrient() ); + SwFormatVertOrient aVert( pAnchoredObj->GetFrameFormat()->GetVertOrient() ); switch ( aVert.GetRelationOrient() ) { case text::RelOrientation::PAGE_FRAME: @@ -5528,7 +5651,7 @@ static bool lcl_ArrangeLowers( SwLayoutFrame *pLay, tools::Long lYStart, bool bI if ( pTabFrame && !( pTabFrame->IsFollow() && pTabFrame->FindMaster()->IsRebuildLastLine() ) && - (pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() + (pAnchoredObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)) { SwPageFrame* pPageFrame = pAnchoredObj->GetPageFrame(); @@ -5546,7 +5669,7 @@ static bool lcl_ArrangeLowers( SwLayoutFrame *pLay, tools::Long lYStart, bool bI // #i52904# - re-introduce direct move // of drawing objects const bool bDirectMove = - static_cast<const SwDrawFrameFormat&>(pAnchoredObj->GetFrameFormat()).IsPosAttrSet() && + static_cast<const SwDrawFrameFormat*>(pAnchoredObj->GetFrameFormat())->IsPosAttrSet() && bVertPosDepOnAnchor && !pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos(); if ( bDirectMove ) @@ -5804,8 +5927,8 @@ void SwCellFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorder const SwFrame* pAnch = pAnchoredObj->GetAnchorFrame(); if ( (bConsiderWrapOnObjPos && IsAnLower( pAnch )) || (!bConsiderWrapOnObjPos && aTmp.Overlaps( aRect )) ) { - const SwFrameFormat& rAnchoredObjFrameFormat = pAnchoredObj->GetFrameFormat(); - const SwFormatSurround &rSur = rAnchoredObjFrameFormat.GetSurround(); + const SwFrameFormat* pAnchoredObjFrameFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround &rSur = pAnchoredObjFrameFormat->GetSurround(); if ( bConsiderWrapOnObjPos || css::text::WrapTextMode_THROUGH != rSur.GetSurround() ) { @@ -5825,7 +5948,7 @@ void SwCellFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorder if ( bConsiderWrapOnObjPos || !IsAnLower( pAnch ) || pAnchoredObj->IsTmpConsiderWrapInfluence() || - !rAnchoredObjFrameFormat.GetFollowTextFlow().GetValue() ) + !pAnchoredObjFrameFormat->GetFollowTextFlow().GetValue() ) { bVertDir = false; break; diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index 5f8e3aa995..a8445e90dd 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -70,8 +70,9 @@ namespace { const SwVirtFlyDrawObj* pObj = static_cast<const SwVirtFlyDrawObj*>(aIter()); const SwAnchoredObject* pAnchoredObj = GetUserCall( aIter() )->GetAnchoredObj( aIter() ); - const SwFormatSurround& rSurround = pAnchoredObj->GetFrameFormat().GetSurround(); - const SvxOpaqueItem& rOpaque = pAnchoredObj->GetFrameFormat().GetOpaque(); + 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; @@ -2599,40 +2600,49 @@ void SwRootFrame::CalcFrameRects(SwShellCursor const& rCursor, SwRects & rRects, // splitting of portions vertically (causes spurious extra PDF annotations) if (eMode == RectsMode::NoAnchoredFlys) { - assert(pStartFrame == pEndFrame); // link or field all in 1 frame - assert(pStartFrame->IsTextFrame()); - SwTextGridItem const*const pGrid(GetGridItem(pStartFrame->FindPageFrame())); - SwTextPaintInfo info(static_cast<SwTextFrame*>(pStartFrame), pStartFrame->FindPageFrame()->getFrameArea()); - SwTextPainter painter(static_cast<SwTextFrame*>(pStartFrame), &info); - // because nothing outside the start/end has been added, it doesn't - // matter to match exactly the start/end, subtracting outside is no-op - painter.CharToLine(static_cast<SwTextFrame*>(pStartFrame)->MapModelToViewPos(*pStartPos)); - do - { - info.SetPos(painter.GetTopLeft()); - bool const bAdjustBaseLine( - painter.GetLineInfo().HasSpecialAlign(pStartFrame->IsVertical()) - || nullptr != pGrid || painter.GetCurr()->GetHangingBaseline()); - SwTwips nAscent, nHeight; - painter.CalcAscentAndHeight(nAscent, nHeight); - SwTwips const nOldY(info.Y()); - for (SwLinePortion const* pLP = painter.GetCurr()->GetFirstPortion(); - pLP; pLP = pLP->GetNextPortion()) + for (SwContentFrame * pFrame = pStartFrame; ; pFrame = pFrame->GetFollow()) + { + assert(pFrame->IsTextFrame()); + SwTextGridItem const*const pGrid(GetGridItem(pFrame->FindPageFrame())); + SwTextPaintInfo info(static_cast<SwTextFrame*>(pFrame), pFrame->FindPageFrame()->getFrameArea()); + SwTextPainter painter(static_cast<SwTextFrame*>(pFrame), &info); + // because nothing outside the start/end has been added, it doesn't + // matter to match exactly the start/end, subtracting outside is no-op + if (pFrame == pStartFrame) { - if (pLP->IsFlyPortion()) + painter.CharToLine(static_cast<SwTextFrame*>(pFrame)->MapModelToViewPos(*pStartPos)); + } + do + { + info.SetPos(painter.GetTopLeft()); + bool const bAdjustBaseLine( + painter.GetLineInfo().HasSpecialAlign(pFrame->IsVertical()) + || nullptr != pGrid || painter.GetCurr()->GetHangingBaseline()); + SwTwips nAscent, nHeight; + painter.CalcAscentAndHeight(nAscent, nHeight); + SwTwips const nOldY(info.Y()); + for (SwLinePortion const* pLP = painter.GetCurr()->GetFirstPortion(); + pLP; pLP = pLP->GetNextPortion()) { - info.Y(info.Y() + (bAdjustBaseLine - ? painter.AdjustBaseLine(*painter.GetCurr(), pLP) - : nAscent)); - SwRect flyPortion; - info.CalcRect(*pLP, &flyPortion); - Sub(aRegion, flyPortion); - info.Y(nOldY); + if (pLP->IsFlyPortion()) + { + info.Y(info.Y() + (bAdjustBaseLine + ? painter.AdjustBaseLine(*painter.GetCurr(), pLP) + : nAscent)); + SwRect flyPortion; + info.CalcRect(*pLP, &flyPortion); + Sub(aRegion, flyPortion); + info.Y(nOldY); + } + pLP->Move(info); } - pLP->Move(info); + } + while (painter.Next()); + if (pFrame == pEndFrame) + { + break; } } - while (painter.Next()); } else while (pPage) { @@ -2646,7 +2656,7 @@ void SwRootFrame::CalcFrameRects(SwShellCursor const& rCursor, SwRects & rRects, continue; const SwVirtFlyDrawObj* pObj = pFly->GetVirtDrawObj(); const SwFormatSurround &rSur = pFly->GetFormat()->GetSurround(); - SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat().GetAnchor()); + SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat()->GetAnchor()); const SwPosition* anchoredAt = rAnchor.GetContentAnchor(); bool inSelection = ( anchoredAt != nullptr diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index 1cd01d53c6..aa108e16b6 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -2347,8 +2347,8 @@ SwTwips SwContentFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo ) if( aBound.Overlaps( aRect ) ) { - const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - if( css::text::WrapTextMode_THROUGH != rFormat.GetSurround().GetSurround() ) + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + if( css::text::WrapTextMode_THROUGH != pFormat->GetSurround().GetSurround() ) { const SwFrame* pAnchor = pAnchoredObj->GetAnchorFrame(); if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() ) @@ -4327,7 +4327,7 @@ void SwRootFrame::InvalidateAllObjPos() const SwSortedObjs& rObjs = *(pPageFrame->GetSortedObjs()); for (SwAnchoredObject* pAnchoredObj : rObjs) { - const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat()->GetAnchor(); if ((rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA) && (rAnch.GetAnchorId() != RndStdIds::FLY_AT_CHAR)) { diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx b/sw/source/core/objectpositioning/anchoredobjectposition.cxx index e530e36df3..ab35ae7af7 100644 --- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx +++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx @@ -106,7 +106,7 @@ void SwAnchoredObjectPosition::GetInfoAboutObj() // determine format the object belongs to { // #i28701# - mpFrameFormat = &mpAnchoredObj->GetFrameFormat(); + mpFrameFormat = mpAnchoredObj->GetFrameFormat(); assert(mpFrameFormat && "<SwAnchoredObjectPosition::GetInfoAboutObj() - missing frame format."); } diff --git a/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx b/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx index 8e4af98b71..50af106115 100644 --- a/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx +++ b/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx @@ -1241,7 +1241,7 @@ void SwToContentAnchoredObjectPosition::CalcOverlap(const SwTextFrame* pAnchorFr break; } - if (SwTextBoxHelper::isTextBox(&pAnchoredObj->GetFrameFormat(), RES_FLYFRMFMT)) + if (SwTextBoxHelper::isTextBox(pAnchoredObj->GetFrameFormat(), RES_FLYFRMFMT)) { // Overlapping with the frame of a textbox is fine. continue; @@ -1276,7 +1276,7 @@ void SwToContentAnchoredObjectPosition::CalcOverlap(const SwTextFrame* pAnchorFr } } - css::text::WrapTextMode eWrap = pAnchoredObj->GetFrameFormat().GetSurround().GetSurround(); + css::text::WrapTextMode eWrap = pAnchoredObj->GetFrameFormat()->GetSurround().GetSurround(); if (eWrap == css::text::WrapTextMode_THROUGH) { // The other object is wrap through: allowed to overlap. diff --git a/sw/source/core/table/swnewtable.cxx b/sw/source/core/table/swnewtable.cxx index 3cc2e36707..785ef79d3b 100644 --- a/sw/source/core/table/swnewtable.cxx +++ b/sw/source/core/table/swnewtable.cxx @@ -1739,7 +1739,11 @@ void SwTable::CreateSelection( const SwNode* pStartNd, const SwNode* pEndNd, rBoxes.insert( pBox ); if( nFound ) { - nBottom = nRow; + //if box is hiding cells bottom needs to be moved + if (pBox->getRowSpan() > 1) + nBottom = std::max(nBottom, size_t(nRow + pBox->getRowSpan() - 1)); + else + nBottom = std::max(nRow, nBottom); lcl_CheckMinMax( nLowerMin, nLowerMax, *pLine, nCol, true ); ++nFound; break; @@ -1747,6 +1751,9 @@ void SwTable::CreateSelection( const SwNode* pStartNd, const SwNode* pEndNd, else { nTop = nRow; + //if box is hiding cells bottom needs to be moved + if (pBox->getRowSpan() > 1) + nBottom = nRow + pBox->getRowSpan() - 1; lcl_CheckMinMax( nUpperMin, nUpperMax, *pLine, nCol, true ); ++nFound; // If start and end node are identical, we're nearly done... diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx index 499dcc2417..8ff764d92f 100644 --- a/sw/source/core/text/EnhancedPDFExportHelper.cxx +++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx @@ -364,7 +364,10 @@ bool lcl_TryMoveToNonHiddenField(SwEditShell& rShell, const SwTextNode& rNd, con && *pStart <= pos && pos <= *pEnd) { SwRect charRect; - if (rShell.GetCurrFrame(false)->GetCharRect(charRect, pos, &cms, false) + std::pair<Point, bool> const tmp(center, false); + SwContentFrame const*const pFrame( + pos.nNode.GetNode().GetTextNode()->getLayoutFrame(rShell.GetLayout(), &pos, &tmp)); + if (pFrame->GetCharRect(charRect, pos, &cms, false) && rRect.Overlaps(charRect)) { ret.push_back(rRect); @@ -1626,7 +1629,7 @@ void SwTaggedPDFHelper::BeginBlockStructureElements() { const SwFlyFrame* pFly = static_cast<const SwFlyFrame*>(pFrame); if (pFly->GetAnchorFrame()->FindFooterOrHeader() != nullptr - || pFly->GetFrameFormat().GetAttrSet().Get(RES_DECORATIVE).GetValue()) + || pFly->GetFrameFormat()->GetAttrSet().Get(RES_DECORATIVE).GetValue()) { nPDFType = vcl::PDFWriter::NonStructElement; } diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx index 76a1df5621..e19b834a56 100644 --- a/sw/source/core/text/frmform.cxx +++ b/sw/source/core/text/frmform.cxx @@ -1120,7 +1120,7 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine, bool bOnlyContainsAsCharAnchoredObj = !IsFollow() && nStrLen == TextFrameIndex(1) && GetDrawObjs() && GetDrawObjs()->size() == 1 && - (*GetDrawObjs())[0]->GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR; + (*GetDrawObjs())[0]->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR; // Still try split text frame if we have columns. if (FindColFrame()) diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx index 3346fe345a..c3a94187a7 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -585,7 +585,12 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, m_nBreakStart = m_nBreakPos; - bHyph = BreakType::HYPHENATION == aResult.breakType; + bHyph = BreakType::HYPHENATION == aResult.breakType && + // allow hyphenation of the word only if it's not disabled by character formatting + LANGUAGE_NONE != rInf.GetTextFrame()->GetLangOfChar( + TextFrameIndex( sal_Int32(m_nBreakPos) + + aResult.rHyphenatedWord->getHyphenationPos() ), + 1, true, /*bNoneIfNoHyphenation=*/true ); if (bHyph && m_nBreakPos != TextFrameIndex(COMPLETE_STRING)) { diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx index 3d9121ef1e..8eced32e89 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -1426,8 +1426,8 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor, || m_pFrame->GetTextNodeForParaProps()->HasMarkedLabel())) // #i27615# { bDraw = PortionType::Footnote != nWhich || m_pFrame->IsFootnoteAllowed(); + bDraw &= GetOpt().IsHardBlank(); } - bDraw &= GetOpt().IsHardBlank(); break; case PortionType::Bookmark: // no shading diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index 24203ecb53..bb008d24a3 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -1576,7 +1576,7 @@ bool SwTextFrame::IsEmptyWithSplitFly() const } // It has a split fly anchored to it. - if (pFlyFrame->GetFrameFormat().GetVertOrient().GetPos() >= 0) + if (pFlyFrame->GetFrameFormat()->GetVertOrient().GetPos() >= 0) { return false; } diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index c0b4894f8a..6623000c33 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -420,7 +420,7 @@ void SwTextFormatter::BuildPortions( SwTextFormatInfo &rInf ) if (pAnchoredObj->RestartLayoutProcess() && !pAnchoredObj->IsTmpConsiderWrapInfluence()) { - SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat().GetAnchor()); + SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat()->GetAnchor()); assert(rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA); TextFrameIndex const nAnchor(GetTextFrame()->MapModelToViewPos(*rAnchor.GetContentAnchor())); if (pFollow->GetOffset() <= nAnchor @@ -1009,6 +1009,8 @@ bool SwContentControlPortion::DescribePDFControl(const SwTextPaintInfo& rInf) co case SwContentControlType::PLAIN_TEXT: { pDescriptor = std::make_unique<vcl::PDFWriter::EditWidget>(); + auto pEditWidget = static_cast<vcl::PDFWriter::EditWidget*>(pDescriptor.get()); + pEditWidget->MultiLine = true; break; } case SwContentControlType::CHECKBOX: @@ -1016,8 +1018,13 @@ bool SwContentControlPortion::DescribePDFControl(const SwTextPaintInfo& rInf) co pDescriptor = std::make_unique<vcl::PDFWriter::CheckBoxWidget>(); auto pCheckBoxWidget = static_cast<vcl::PDFWriter::CheckBoxWidget*>(pDescriptor.get()); pCheckBoxWidget->Checked = pContentControl->GetChecked(); - pCheckBoxWidget->OnValue = pContentControl->GetCheckedState(); - pCheckBoxWidget->OffValue = pContentControl->GetUncheckedState(); + // If it's checked already, then leave the default "Yes" OnValue unchanged, so the + // appropriate appearance is found by PDF readers. + if (!pCheckBoxWidget->Checked) + { + pCheckBoxWidget->OnValue = pContentControl->GetCheckedState(); + pCheckBoxWidget->OffValue = pContentControl->GetUncheckedState(); + } break; } case SwContentControlType::DROP_DOWN_LIST: diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx index 1a30a4ecd7..d2ae4be00d 100644 --- a/sw/source/core/text/porfld.cxx +++ b/sw/source/core/text/porfld.cxx @@ -402,10 +402,13 @@ bool SwFieldPortion::Format( SwTextFormatInfo &rInf ) // These characters should not be contained in the follow // field portion. They are handled via the HookChar mechanism. const sal_Unicode nNew = !aNew.isEmpty() ? aNew[0] : 0; - auto IsHook = [](const sal_Unicode cNew) -> bool + auto IsHook = [](const sal_Unicode cNew, bool const isSpace = false) -> bool { switch (cNew) { + case ' ': // tdf#159101 this one is not in ScanPortionEnd + // but is required for justified text + return isSpace; case CH_BREAK: case CH_TAB: case CHAR_HARDHYPHEN: // non-breaking hyphen @@ -422,7 +425,7 @@ bool SwFieldPortion::Format( SwTextFormatInfo &rInf ) return false; } }; - if (IsHook(nNew)) + if (IsHook(nNew, true)) { if (nNew == CH_BREAK) { @@ -599,9 +602,12 @@ bool SwNumberPortion::Format( SwTextFormatInfo &rInf ) if ( !mbLabelAlignmentPosAndSpaceModeActive ) { - if (!rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) && + if ((!rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) && // #i32902# - !IsFootnoteNumPortion() ) + !IsFootnoteNumPortion()) || + // tdf#159382 + (IsFootnoteNumPortion() && + rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER))) { nDiff = rInf.Left() + rInf.GetTextFrame()->GetTextNodeForParaProps()-> diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx index 14d1bf6eaa..19ac692cf4 100644 --- a/sw/source/core/text/porfly.cxx +++ b/sw/source/core/text/porfly.cxx @@ -168,7 +168,7 @@ void SwTextFrame::MoveFlyInCnt(SwTextFrame *pNew, { // Consider changed type of <SwSortedList> entries SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; - const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat()->GetAnchor(); if (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR) { const SwPosition* pPos = rAnch.GetContentAnchor(); diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index cae54845be..2ba2fcf75f 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -748,7 +748,7 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf ) { bool bDeleted = false; size_t nAuthor = std::string::npos; - const SwFormatAnchor& rAnchor = pAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rAnchor = pAnchoredObj->GetFrameFormat()->GetAnchor(); if ( rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR ) { SwPosition aAnchor = *rAnchor.GetContentAnchor(); diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx index 029adca753..a4a0d3c713 100644 --- a/sw/source/core/text/porrst.cxx +++ b/sw/source/core/text/porrst.cxx @@ -22,6 +22,7 @@ #include <editeng/escapementitem.hxx> #include <editeng/lrspitem.hxx> #include <editeng/pgrditem.hxx> +#include <editeng/fontitem.hxx> #include <vcl/svapp.hxx> #include <comphelper/scopeguard.hxx> @@ -47,6 +48,7 @@ #include <IDocumentRedlineAccess.hxx> #include <IDocumentSettingAccess.hxx> #include <IDocumentDeviceAccess.hxx> +#include <IDocumentLayoutAccess.hxx> #include <crsrsh.hxx> #include <swtypes.hxx> @@ -74,6 +76,16 @@ void SwTmpEndPortion::Paint( const SwTextPaintInfo &rInf ) const SwFont aFont(*pOldFnt); + const SwDoc& rDoc = rInf.GetTextFrame()->GetDoc(); + if (aFont.IsSymbol(rDoc.getIDocumentLayoutAccess().GetCurrentViewShell())) + { + const SvxFontItem& rFontItem = rDoc.GetDefault(RES_CHRATR_FONT); + aFont.SetName( rFontItem.GetFamilyName(), SwFontScript::Latin ); + aFont.SetStyleName( rFontItem.GetStyleName(), SwFontScript::Latin ); + aFont.SetFamily( rFontItem.GetFamily(), SwFontScript::Latin ); + aFont.SetPitch( rFontItem.GetPitch(), SwFontScript::Latin ); + aFont.SetCharSet( rFontItem.GetCharSet(), SwFontScript::Latin ); + } // Paint strikeout/underline based on redline color and settings // (with an extra pilcrow in the background, because there is // no SetStrikeoutColor(), also SetUnderColor() doesn't work()). diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index 85691ef21e..e58021ef09 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -325,14 +325,20 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf ) // call with an extra space: shrinking can result a new word in the line // and a new space before that, which is also a shrank space - // (except if the line was already broken at a soft hyphen, i.e. inside a word) - if ( aGuess.BreakPos() < TextFrameIndex(rInf.GetText().getLength()) && + // (except if the line was already broken inside a word with hyphenation) + // TODO: handle the case, if the line contains extra amount of spaces + if ( + // no automatic hyphenation + !aGuess.HyphWord().is() && + // no hyphenation at soft hyphen + aGuess.BreakPos() < TextFrameIndex(rInf.GetText().getLength()) && rInf.GetText()[sal_Int32(aGuess.BreakPos())] != CHAR_SOFTHYPHEN ) { ++nSpacesInLine; } - bFull = !aGuess.Guess( *this, rInf, Height(), nSpacesInLine ); + if ( nSpacesInLine > 0 ) + bFull = !aGuess.Guess( *this, rInf, Height(), nSpacesInLine ); } // these are the possible cases: diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx index ff5566f537..7c4d9a2e16 100644 --- a/sw/source/core/text/txtfly.cxx +++ b/sw/source/core/text/txtfly.cxx @@ -162,7 +162,7 @@ SwRect SwContourCache::CalcBoundRect( const SwAnchoredObject* pAnchoredObj, const bool bRight ) { SwRect aRet; - const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat()); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); bool bHandleContour(pFormat->GetSurround().IsContour()); if(!bHandleContour) @@ -594,7 +594,7 @@ void SwTextFly::DrawFlyRect( OutputDevice* pOut, const SwRect &rRect ) if (pFly) { // #i68520# - const SwFormatSurround& rSur = pAnchoredObjTmp->GetFrameFormat().GetSurround(); + const SwFormatSurround& rSur = pAnchoredObjTmp->GetFrameFormat()->GetSurround(); // OD 24.01.2003 #106593# - correct clipping of fly frame area. // Consider that fly frame background/shadow can be transparent @@ -655,8 +655,8 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj, if( ( bInFootnote || bInFooterOrHeader ) && m_bTopRule ) { // #i26945# - const SwFrameFormat& rFrameFormat = _pAnchoredObj->GetFrameFormat(); - const SwFormatAnchor& rNewA = rFrameFormat.GetAnchor(); + const SwFrameFormat* pFrameFormat = _pAnchoredObj->GetFrameFormat(); + const SwFormatAnchor& rNewA = pFrameFormat->GetAnchor(); if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId()) { if ( bInFootnote ) @@ -664,7 +664,7 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj, if ( bInFooterOrHeader ) { - const SwFormatVertOrient& aVert( rFrameFormat.GetVertOrient() ); + const SwFormatVertOrient& aVert(pFrameFormat->GetVertOrient()); bool bVertPrt = aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA || aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA; if( bVertPrt ) @@ -710,13 +710,14 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj, { // Within chained Flys we only avoid Lower // #i68520# - const SwFormatChain &rChain = mpCurrAnchoredObj->GetFrameFormat().GetChain(); + const SwFrameFormat* pCurObjFormat = mpCurrAnchoredObj->GetFrameFormat(); + const SwFormatChain& rChain = pCurObjFormat->GetChain(); if ( !rChain.GetPrev() && !rChain.GetNext() ) { // #i26945# - const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat()->GetAnchor(); // #i68520# - const SwFormatAnchor& rCurrA = mpCurrAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rCurrA = pCurObjFormat->GetAnchor(); // If <mpCurrAnchoredObj> is anchored as character, its content // does not wrap around pNew @@ -768,78 +769,85 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj, if ( bEvade ) { // #i26945# - const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor(); - OSL_ENSURE( RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(), - "Don't call GetTop with a FlyInContentFrame" ); - if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId()) - return true; // We always avoid page anchored ones - - // If Flys anchored at paragraph are caught in a FlyCnt, then - // their influence ends at the borders of the FlyCnt! - // If we are currently formatting the text of the FlyCnt, then - // it has to get out of the way of the Frame anchored at paragraph! - // m_pCurrFrame is the anchor of pNew? - // #i26945# - const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame(); - if (pTmp == m_pCurrFrame) - return true; - if( pTmp->IsTextFrame() && ( pTmp->IsInFly() || pTmp->IsInFootnote() ) ) + if (const SwFrameFormat* pAnchoredObjFormat = _pAnchoredObj->GetFrameFormat()) { + const SwFormatAnchor& rNewA = pAnchoredObjFormat->GetAnchor(); + OSL_ENSURE(RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(), + "Don't call GetTop with a FlyInContentFrame"); + if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId()) + return true; // We always avoid page anchored ones + + // If Flys anchored at paragraph are caught in a FlyCnt, then + // their influence ends at the borders of the FlyCnt! + // If we are currently formatting the text of the FlyCnt, then + // it has to get out of the way of the Frame anchored at paragraph! + // m_pCurrFrame is the anchor of pNew? // #i26945# - Point aPos = _pAnchoredObj->GetObjRect().Pos(); - pTmp = GetVirtualUpper( pTmp, aPos ); - } - // #i26945# - // If <pTmp> is a text frame inside a table, take the upper - // of the anchor frame, which contains the anchor position. - else if ( pTmp->IsTextFrame() && pTmp->IsInTab() ) - { - pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj) - ->GetAnchorFrameContainingAnchPos()->GetUpper(); - } - // #i28701# - consider all objects in same context, - // if wrapping style is considered on object positioning. - // Thus, text will wrap around negative positioned objects. - // #i3317# - remove condition on checking, - // if wrappings style is considered on object positioning. - // Thus, text is wrapping around negative positioned objects. - // #i35640# - no consideration of negative - // positioned objects, if wrapping style isn't considered on - // object position and former text wrapping is applied. - // This condition is typically for documents imported from the - // OpenOffice.org file format. - const IDocumentSettingAccess* pIDSA = &m_pCurrFrame->GetDoc().getIDocumentSettingAccess(); - if ( ( pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) || - !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) ) && - ::FindContext( pTmp, SwFrameType::None ) == ::FindContext(m_pCurrFrame, SwFrameType::None)) - { - return true; - } - - const SwFrame* pHeader = nullptr; - if (m_pCurrFrame->GetNext() != pTmp && - (IsFrameInSameContext( pTmp, m_pCurrFrame ) || - // #i13832#, #i24135# wrap around objects in page header - ( !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) && - nullptr != ( pHeader = pTmp->FindFooterOrHeader() ) && - m_pCurrFrame->IsInDocBody()))) - { - if( pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId() ) + const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame(); + if (pTmp == m_pCurrFrame) return true; - - // Compare indices: - // The Index of the other is retrieved from the anchor attr. - SwNodeOffset nTmpIndex = rNewA.GetAnchorNode()->GetIndex(); - // Now check whether the current paragraph is before the anchor - // of the displaced object in the text, then we don't have to - // get out of its way. - // If possible determine Index via SwFormatAnchor because - // otherwise it's quite expensive. - if (NODE_OFFSET_MAX == m_nCurrFrameNodeIndex) - m_nCurrFrameNodeIndex = m_pCurrFrame->GetTextNodeFirst()->GetIndex(); - - if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) || nTmpIndex < m_nCurrFrameNodeIndex) + if (pTmp->IsTextFrame() && (pTmp->IsInFly() || pTmp->IsInFootnote())) + { + // #i26945# + Point aPos = _pAnchoredObj->GetObjRect().Pos(); + pTmp = GetVirtualUpper(pTmp, aPos); + } + // #i26945# + // If <pTmp> is a text frame inside a table, take the upper + // of the anchor frame, which contains the anchor position. + else if (pTmp->IsTextFrame() && pTmp->IsInTab()) + { + pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj) + ->GetAnchorFrameContainingAnchPos() + ->GetUpper(); + } + // #i28701# - consider all objects in same context, + // if wrapping style is considered on object positioning. + // Thus, text will wrap around negative positioned objects. + // #i3317# - remove condition on checking, + // if wrappings style is considered on object positioning. + // Thus, text is wrapping around negative positioned objects. + // #i35640# - no consideration of negative + // positioned objects, if wrapping style isn't considered on + // object position and former text wrapping is applied. + // This condition is typically for documents imported from the + // OpenOffice.org file format. + const IDocumentSettingAccess* pIDSA + = &m_pCurrFrame->GetDoc().getIDocumentSettingAccess(); + if ((pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) + || !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING)) + && ::FindContext(pTmp, SwFrameType::None) + == ::FindContext(m_pCurrFrame, SwFrameType::None)) + { return true; + } + + const SwFrame* pHeader = nullptr; + if (m_pCurrFrame->GetNext() != pTmp + && (IsFrameInSameContext(pTmp, m_pCurrFrame) || + // #i13832#, #i24135# wrap around objects in page header + (!pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) + && nullptr != (pHeader = pTmp->FindFooterOrHeader()) + && m_pCurrFrame->IsInDocBody()))) + { + if (pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId()) + return true; + + // Compare indices: + // The Index of the other is retrieved from the anchor attr. + SwNodeOffset nTmpIndex = rNewA.GetAnchorNode()->GetIndex(); + // Now check whether the current paragraph is before the anchor + // of the displaced object in the text, then we don't have to + // get out of its way. + // If possible determine Index via SwFormatAnchor because + // otherwise it's quite expensive. + if (NODE_OFFSET_MAX == m_nCurrFrameNodeIndex) + m_nCurrFrameNodeIndex = m_pCurrFrame->GetTextNodeFirst()->GetIndex(); + + if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) + || nTmpIndex < m_nCurrFrameNodeIndex) + return true; + } } } } @@ -919,7 +927,7 @@ SwAnchoredObjList& SwTextFly::InitAnchoredObjList() !pAnchoredObj->ConsiderForTextWrap() || ( mbIgnoreObjsInHeaderFooter && !bFooterHeader && pAnchoredObj->GetAnchorFrame()->FindFooterOrHeader() ) || - ( bAllowCompatWrap && !pAnchoredObj->GetFrameFormat().GetFollowTextFlow().GetValue() ) + ( bAllowCompatWrap && !pAnchoredObj->GetFrameFormat()->GetFollowTextFlow().GetValue() ) ) { continue; @@ -957,13 +965,13 @@ SwAnchoredObjList& SwTextFly::InitAnchoredObjList() mpAnchoredObjList->insert( aInsPosIter, pAnchoredObj ); } - const SwFormatSurround &rFlyFormat = pAnchoredObj->GetFrameFormat().GetSurround(); + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rFlyFormat = pObjFormat->GetSurround(); // #i68520# if ( rFlyFormat.IsAnchorOnly() && pAnchoredObj->GetAnchorFrame() == GetMaster() ) { - const SwFormatVertOrient &rTmpFormat = - pAnchoredObj->GetFrameFormat().GetVertOrient(); + const SwFormatVertOrient &rTmpFormat = pObjFormat->GetVertOrient(); if( text::VertOrientation::BOTTOM != rTmpFormat.GetVertOrient() ) m_nMinBottom = ( aRectFnSet.IsVert() && m_nMinBottom ) ? std::min( m_nMinBottom, aBound.Left() ) : @@ -998,11 +1006,11 @@ SwTwips SwTextFly::CalcMinBottom() const for( size_t i = 0; i < nCount; ++i ) { SwAnchoredObject* pAnchoredObj = (*pDrawObj)[ i ]; - const SwFormatSurround &rFlyFormat = pAnchoredObj->GetFrameFormat().GetSurround(); + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rFlyFormat = pObjFormat->GetSurround(); if( rFlyFormat.IsAnchorOnly() ) { - const SwFormatVertOrient &rTmpFormat = - pAnchoredObj->GetFrameFormat().GetVertOrient(); + const SwFormatVertOrient &rTmpFormat = pObjFormat->GetVertOrient(); if( text::VertOrientation::BOTTOM != rTmpFormat.GetVertOrient() ) { const SwRect& aBound( pAnchoredObj->GetObjRectWithSpaces() ); @@ -1118,7 +1126,7 @@ bool SwTextFly::ForEach( const SwRect &rRect, SwRect* pRect, bool bAvoid ) const if ( mpCurrAnchoredObj != pAnchoredObj && aRect.Overlaps( rRect ) ) { // #i68520# - const SwFormat* pFormat( &(pAnchoredObj->GetFrameFormat()) ); + const SwFormat* pFormat(pAnchoredObj->GetFrameFormat()); const SwFormatSurround &rSur = pFormat->GetSurround(); if( bAvoid ) { @@ -1405,7 +1413,7 @@ SwRect SwTextFly::AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj, css::text::WrapTextMode SwTextFly::GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const { - const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat()); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); const SwFormatSurround &rFlyFormat = pFormat->GetSurround(); css::text::WrapTextMode eSurroundForTextWrap = rFlyFormat.GetSurround(); diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index 18eb78db83..302302a9a2 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -1459,11 +1459,11 @@ SwDoc const& SwTextFrame::GetDoc() const } LanguageType SwTextFrame::GetLangOfChar(TextFrameIndex const nIndex, - sal_uInt16 const nScript, bool const bNoChar) const + sal_uInt16 const nScript, bool const bNoChar, bool const bNoneIfNoHyphenation) const { // a single character can be mapped uniquely! std::pair<SwTextNode const*, sal_Int32> const pos(MapViewToModel(nIndex)); - return pos.first->GetLang(pos.second, bNoChar ? 0 : 1, nScript); + return pos.first->GetLang(pos.second, bNoChar ? 0 : 1, nScript, bNoneIfNoHyphenation); } void SwTextFrame::ResetPreps() @@ -3104,7 +3104,7 @@ bool SwTextFrame::Prepare( const PrepareHint ePrep, const void* pVoid, SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i]; // i#28701 - consider all // to-character anchored objects - if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() + if ( pAnchoredObj->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR ) { bFormat = true; diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 47bff5e08b..77dbe2e029 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -412,12 +412,12 @@ void MoveMergedFlysAndFootnotes(std::vector<SwTextFrame*> const& rFrames, } for (SwAnchoredObject *const pObj : objs) { - SwFrameFormat & rFormat(pObj->GetFrameFormat()); - SwFormatAnchor const& rAnchor(rFormat.GetAnchor()); + SwFrameFormat* pFormat(pObj->GetFrameFormat()); + SwFormatAnchor const& rAnchor(pFormat->GetAnchor()); if (rFirstNode.GetIndex() < rAnchor.GetAnchorNode()->GetIndex()) { // move it to the new frame of "this" - rFormat.CallSwClientNotify(sw::LegacyModifyHint(&rAnchor, &rAnchor)); + pFormat->CallSwClientNotify(sw::LegacyModifyHint(&rAnchor, &rAnchor)); // note pObjs will be deleted if it becomes empty assert(!pFrame->GetDrawObjs() || !pObjs->Contains(*pObj)); } diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 0556facafe..cf5e1ff1cc 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -23,6 +23,7 @@ #include <DocumentContentOperationsManager.hxx> #include <hintids.hxx> #include <editeng/rsiditem.hxx> +#include <editeng/nhypitem.hxx> #include <osl/diagnose.h> #include <svl/whiter.hxx> #include <svl/itemiter.hxx> @@ -3487,7 +3488,7 @@ void SwTextNode::ClearSwpHintsArr( bool bDelFields ) } LanguageType SwTextNode::GetLang( const sal_Int32 nBegin, const sal_Int32 nLen, - sal_uInt16 nScript ) const + sal_uInt16 nScript, bool const bNoneIfNoHyphenation ) const { LanguageType nRet = LANGUAGE_DONTKNOW; @@ -3497,7 +3498,9 @@ LanguageType SwTextNode::GetLang( const sal_Int32 nBegin, const sal_Int32 nLen, } // #i91465# Consider nScript if pSwpHints == 0 - const TypedWhichId<SvxLanguageItem> nWhichId = GetWhichOfScript( RES_CHRATR_LANGUAGE, nScript ); + const sal_uInt16 nWhichId = bNoneIfNoHyphenation + ? RES_CHRATR_NOHYPHEN + : GetWhichOfScript( RES_CHRATR_LANGUAGE, nScript ); if ( HasHints() ) { @@ -3531,8 +3534,18 @@ LanguageType SwTextNode::GetLang( const sal_Int32 nBegin, const sal_Int32 nLen, if( pHt->DontExpand() ? nBegin >= *pEndIdx : nBegin > *pEndIdx) continue; } - const SvxLanguageItem* pItem = CharFormat::GetItem( *pHt, nWhichId ); - const LanguageType nLng = pItem->GetLanguage(); + const SfxPoolItem* pItem = CharFormat::GetItem( *pHt, nWhichId ); + + if ( RES_CHRATR_NOHYPHEN == nWhichId ) + { + // bNoneIfNoHyphenation = true: return with LANGUAGE_NONE, + // if the hyphenation is disabled by character formatting + if ( static_cast<const SvxNoHyphenItem*>(pItem)->GetValue() ) + return LANGUAGE_NONE; + continue; + } + + const LanguageType nLng = static_cast<const SvxLanguageItem*>(pItem)->GetLanguage(); // does the attribute completely cover the range? if( nAttrStart <= nBegin && nEnd <= *pEndIdx ) @@ -3542,9 +3555,9 @@ LanguageType SwTextNode::GetLang( const sal_Int32 nBegin, const sal_Int32 nLen, } } } - if( LANGUAGE_DONTKNOW == nRet ) + if( LANGUAGE_DONTKNOW == nRet && !bNoneIfNoHyphenation ) { - nRet = GetSwAttrSet().Get( nWhichId ).GetLanguage(); + nRet = static_cast<const SvxLanguageItem&>(GetSwAttrSet().Get( nWhichId )).GetLanguage(); if( LANGUAGE_DONTKNOW == nRet ) nRet = GetAppLanguage(); } diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx index 4c199c8ac3..7661b59517 100644 --- a/sw/source/core/undo/undel.cxx +++ b/sw/source/core/undo/undel.cxx @@ -1152,14 +1152,25 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext) SwNode& start(*rDoc.GetNodes()[m_nSttNode + ((m_bDelFullPara || !rDoc.GetNodes()[m_nSttNode]->IsTextNode() || pInsNd) ? 0 : 1)]); - // don't include end node in the range: it may have been merged already - // by the start node, or it may be merged by one of the moved nodes, - // but if it isn't merged, its current frame(s) should be good... - SwNode& end(*rDoc.GetNodes()[ m_bDelFullPara - ? delFullParaEndNode - // tdf#147310 SwDoc::DeleteRowCol() may delete whole table - end must be node following table! - : (m_nEndNode + (rDoc.GetNodes()[m_nSttNode]->IsTableNode() && rDoc.GetNodes()[m_nEndNode]->IsEndNode() ? 1 : 0))]); - ::MakeFrames(&rDoc, start, end); + // tdf#158740 fix crash by checking the end node's index + // I don't know why m_nEndNode is larger than the size of the node + // array, but adjusting m_nEndNode to the last element in the node + // array stops the crashing. + SwNodeOffset nCount(rDoc.GetNodes().Count()); + if (nCount > SwNodeOffset(0)) + { + if (m_nEndNode > nCount - 1) + m_nEndNode = nCount - 1; + + // don't include end node in the range: it may have been merged already + // by the start node, or it may be merged by one of the moved nodes, + // but if it isn't merged, its current frame(s) should be good... + SwNode& end(*rDoc.GetNodes()[ m_bDelFullPara + ? delFullParaEndNode + // tdf#147310 SwDoc::DeleteRowCol() may delete whole table - end must be node following table! + : (m_nEndNode + (rDoc.GetNodes()[m_nSttNode]->IsTableNode() && rDoc.GetNodes()[m_nEndNode]->IsEndNode() ? 1 : 0))]); + ::MakeFrames(&rDoc, start, end); + } } if (pMovedNode) diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx index d73c0b59b3..b3452890e0 100644 --- a/sw/source/core/unocore/unofield.cxx +++ b/sw/source/core/unocore/unofield.cxx @@ -1238,20 +1238,34 @@ SwServiceType SwXTextField::GetServiceId() const it has to be disconnected first and at the end connected to the new instance! */ -void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField) -{ - assert(rField.GetFormatField()->Which() == (rField.GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD)); +void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField, + sal_uInt16 const*const pSubType) +{ +#ifndef NDEBUG + auto const oldWhich( + (pSubType ? (rField.GetSubType() & nsSwGetSetExpType::GSE_STRING) != 0 : rField.GetInputFlag()) + ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD); + auto const newWhich(oldWhich == RES_TXTATR_FIELD ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD); +#endif + assert(rField.GetFormatField()->Which() == oldWhich); rtl::Reference<SwXTextField> const pXField( rField.GetFormatField()->GetXTextField()); if (pXField) pXField->m_pImpl->SetFormatField(nullptr, nullptr); SwTextField *const pOldAttr(rField.GetFormatField()->GetTextField()); SwSetExpField tempField(rField); - tempField.SetInputFlag(!rField.GetInputFlag()); + if (pSubType) + { + tempField.SetSubType(*pSubType); + } + else + { + tempField.SetInputFlag(!rField.GetInputFlag()); + } SwFormatField tempFormat(tempField); assert(tempFormat.GetField() != &rField); assert(tempFormat.GetField() != &tempField); // this copies it again? - assert(tempFormat.Which() == (static_cast<SwSetExpField const*>(tempFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD)); + assert(tempFormat.Which() == newWhich); SwTextNode & rNode(pOldAttr->GetTextNode()); std::shared_ptr<SwPaM> pPamForTextField; IDocumentContentOperations & rIDCO(rNode.GetDoc().getIDocumentContentOperations()); @@ -1266,8 +1280,10 @@ void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField) SwTextField const* pNewAttr(rNode.GetFieldTextAttrAt(nStart, ::sw::GetTextAttrMode::Default)); assert(pNewAttr); SwFormatField const& rNewFormat(pNewAttr->GetFormatField()); - assert(rNewFormat.Which() == (static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD)); - assert(static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() == (dynamic_cast<SwTextInputField const*>(pNewAttr) != nullptr)); + assert(rNewFormat.Which() == newWhich); + assert((dynamic_cast<SwTextInputField const*>(pNewAttr) != nullptr) + == ((static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetSubType() & nsSwGetSetExpType::GSE_STRING) + && static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag())); if (pXField) { pXField->m_pImpl->SetFormatField(const_cast<SwFormatField*>(&rNewFormat), &rNode.GetDoc()); diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx index ee4422a22e..12db464a87 100644 --- a/sw/source/core/unocore/unomap1.cxx +++ b/sw/source/core/unocore/unomap1.cxx @@ -537,6 +537,7 @@ std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetPageStyleP { UNO_NAME_NUMBERING_TYPE, SID_ATTR_PAGE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_PAGE_NUMTYPE }, { UNO_NAME_PAGE_STYLE_LAYOUT, SID_ATTR_PAGE, cppu::UnoType<css::style::PageStyleLayout>::get(), PROPERTY_NONE ,MID_PAGE_LAYOUT }, { UNO_NAME_PRINTER_PAPER_TRAY, RES_PAPER_BIN, cppu::UnoType<OUString>::get(), PROPERTY_NONE , 0 }, + { UNO_NAME_PRINTER_PAPER_TRAY_INDEX, RES_PAPER_BIN, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , 0 }, // { UNO_NAME_REGISTER_MODE_ACTIVE, SID_SWREGISTER_MODE, cppu::UnoType<bool>::get(), PROPERTY_NONE , 0 }, { UNO_NAME_REGISTER_PARAGRAPH_STYLE, SID_SWREGISTER_COLLECTION, cppu::UnoType<OUString>::get(), PROPERTY_NONE , 0 }, { UNO_NAME_SIZE, SID_ATTR_PAGE_SIZE, cppu::UnoType<css::awt::Size>::get(), PROPERTY_NONE, MID_SIZE_SIZE|CONVERT_TWIPS}, diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx index 7614f0a314..5cb73bf7b8 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -121,9 +121,9 @@ struct FrameClientSortListLess return; for(const auto pAnchoredObj : *pObjs) { - SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); + SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); // Filter out textboxes, which are not interesting at a UNO level. - if(SwTextBoxHelper::isTextBox(&rFormat, RES_FLYFRMFMT)) + if(SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT)) continue; if (nAnchorType == RndStdIds::FLY_AT_PARA) @@ -137,11 +137,11 @@ struct FrameClientSortListLess } } - if(rFormat.GetAnchor().GetAnchorId() == nAnchorType) + if(pFormat->GetAnchor().GetAnchorId() == nAnchorType) { - const sal_Int32 nIdx = rFormat.GetAnchor().GetAnchorContentOffset(); - const auto nOrder = rFormat.GetAnchor().GetOrder(); - rFrames.emplace_back(nIdx, nOrder, std::make_unique<sw::FrameClient>(&rFormat)); + const sal_Int32 nIdx = pFormat->GetAnchor().GetAnchorContentOffset(); + const auto nOrder = pFormat->GetAnchor().GetOrder(); + rFrames.emplace_back(nIdx, nOrder, std::make_unique<sw::FrameClient>(pFormat)); } } } diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx index 4b50a72cf5..186b5c5b23 100644 --- a/sw/source/core/unocore/unoportenum.cxx +++ b/sw/source/core/unocore/unoportenum.cxx @@ -133,12 +133,18 @@ namespace void lcl_FillBookmark(sw::mark::IMark* const pBkmk, const SwNode& rOwnNode, SwDoc& rDoc, SwXBookmarkPortion_ImplList& rBkmArr) { bool const hasOther = pBkmk->IsExpanded(); - const SwPosition& rStartPos = pBkmk->GetMarkStart(); - if(rStartPos.GetNode() == rOwnNode) + const SwPosition& rEndPos = pBkmk->GetMarkEnd(); + bool const bStartPosInNode = rStartPos.GetNode() == rOwnNode; + bool const bEndPosInNode = rEndPos.GetNode() == rOwnNode; + sw::mark::CrossRefBookmark* const pCrossRefMark + = !hasOther && (bStartPosInNode || bEndPosInNode) + ? dynamic_cast<sw::mark::CrossRefBookmark*>(pBkmk) + : nullptr; + + if (bStartPosInNode) { // #i109272#: cross reference marks: need special handling! - ::sw::mark::CrossRefBookmark *const pCrossRefMark(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk)); BkmType const nType = (hasOther || pCrossRefMark) ? BkmType::Start : BkmType::StartEnd; rBkmArr.insert(std::make_shared<SwXBookmarkPortion_Impl>( @@ -146,13 +152,11 @@ namespace nType, rStartPos)); } - const SwPosition& rEndPos = pBkmk->GetMarkEnd(); - if(rEndPos.GetNode() != rOwnNode) + if (!bEndPosInNode) return; std::optional<SwPosition> oCrossRefEndPos; const SwPosition* pEndPos = nullptr; - ::sw::mark::CrossRefBookmark *const pCrossRefMark(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk)); if(hasOther) { pEndPos = &rEndPos; diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx index 94219281b5..665c1d2c6a 100644 --- a/sw/source/core/unocore/unostyle.cxx +++ b/sw/source/core/unocore/unostyle.cxx @@ -1669,27 +1669,37 @@ void SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE>(const SfxItemPropertyMapE template<> void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) { - if(!rValue.has<OUString>()) + if (!rValue.has<OUString>() && !rValue.has<sal_Int32>()) throw lang::IllegalArgumentException(); SfxPrinter* pPrinter = m_pDoc->getIDocumentDeviceAccess().getPrinter(true); - OUString sValue(rValue.get<OUString>()); using printeridx_t = decltype(pPrinter->GetPaperBinCount()); printeridx_t nBin = std::numeric_limits<printeridx_t>::max(); - if(sValue == "[From printer settings]") - nBin = std::numeric_limits<printeridx_t>::max()-1; - else if(pPrinter) + if(rValue.has<OUString>()) { - for(sal_uInt16 i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i) + OUString sValue(rValue.get<OUString>()); + if(sValue == "[From printer settings]") + nBin = std::numeric_limits<printeridx_t>::max()-1; + else if(pPrinter) { - if (sValue == pPrinter->GetPaperBinName(i)) + for(printeridx_t i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i) { - nBin = i; - break; + if (sValue == pPrinter->GetPaperBinName(i)) + { + nBin = i; + break; + } } } } + else if (rValue.has<sal_Int32>() && pPrinter) + { + sal_Int32 nValue (rValue.get<sal_Int32>()); + nBin = pPrinter->GetPaperBinBySourceIndex(nValue); + } + if(nBin == std::numeric_limits<printeridx_t>::max()) throw lang::IllegalArgumentException(); + SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID); aSet.SetParent(&rStyleSet); diff --git a/sw/source/filter/writer/writer.cxx b/sw/source/filter/writer/writer.cxx index 1671f27e0b..f59531764e 100644 --- a/sw/source/filter/writer/writer.cxx +++ b/sw/source/filter/writer/writer.cxx @@ -160,9 +160,9 @@ bool Writer::CopyNextPam( SwPaM ** ppPam ) sal_Int32 Writer::FindPos_Bkmk(const SwPosition& rPos) const { const IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess(); - const IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findFirstBookmarkStartsAfter(rPos); - if(ppBkmk != pMarkAccess->getBookmarksEnd()) - return ppBkmk - pMarkAccess->getBookmarksBegin(); + const IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findFirstMarkNotStartsBefore(rPos); + if(ppBkmk != pMarkAccess->getAllMarksEnd()) + return ppBkmk - pMarkAccess->getAllMarksBegin(); return -1; } diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index 0c42d28fc6..5c746f6afe 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -939,6 +939,11 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons relativeFromV = "paragraph"; break; case text::RelOrientation::TEXT_LINE: + relativeFromV = "line"; + // Word's "line" is "below the bottom of the line", our TEXT_LINE is + // "towards top, from the bottom of the line", so invert the vertical position. + aPos.Y *= -1; + break; default: relativeFromV = "line"; break; diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 38fbfb2166..74e9d27c09 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -3517,8 +3517,10 @@ bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec // Generate random number with a seed of time as salt. rtlRandomPool aRandomPool = rtl_random_createPool (); sal_uInt8 pDocId[ 16 ]; - rtl_random_getBytes( aRandomPool, pDocId, 16 ); - + if (rtl_random_getBytes(aRandomPool, pDocId, 16) != rtl_Random_E_None) + { + throw uno::RuntimeException("rtl_random_getBytes failed"); + } rtl_random_destroyPool( aRandomPool ); sal_uInt16 aPassword[16] = {}; diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 9418fa0646..10ccaa4878 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -1912,6 +1912,7 @@ void SwWW8ImplReader::ImportDop() m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::ADD_EXT_LEADING, !m_xWDop->fNoLeading); m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::OLD_NUMBERING, false); m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false); // #i47448# + m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER, true); // tdf#159382 m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, !m_xWDop->fExpShRtn); // #i49277#, #i56856# m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // #i53199# m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::OLD_LINE_SPACING, false); @@ -5663,8 +5664,10 @@ namespace rtlRandomPool aRandomPool = rtl_random_createPool(); sal_uInt8 pDocId[ 16 ]; - rtl_random_getBytes( aRandomPool, pDocId, 16 ); - + if (rtl_random_getBytes(aRandomPool, pDocId, 16) != rtl_Random_E_None) + { + throw uno::RuntimeException("rtl_random_getBytes failed"); + } rtl_random_destroyPool( aRandomPool ); sal_uInt16 pStd97Pass[16] = {}; diff --git a/sw/source/ui/fldui/flddok.cxx b/sw/source/ui/fldui/flddok.cxx index 1a2857bedb..5cb38a38ac 100644 --- a/sw/source/ui/fldui/flddok.cxx +++ b/sw/source/ui/fldui/flddok.cxx @@ -601,7 +601,7 @@ bool SwFieldDokPage::FillItemSet(SfxItemSet* ) } case SwFieldTypesEnum::Chapter: - aVal = OUString::number(m_xLevelED->get_active()); + aVal = m_xLevelED->get_active_text(); break; default: diff --git a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx index 5af09a6adf..869a0fba00 100644 --- a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx +++ b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx @@ -821,6 +821,11 @@ bool SwSpellDialogChildWindow::SpellDrawText_Impl(SwWrtShell& rSh, svx::SpellPor void SwSpellDialogChildWindow::LockFocusNotification(bool bLock) { + if (!m_pSpellState) + { + return; + } + OSL_ENSURE(m_pSpellState->m_bLockFocus != bLock, "invalid locking - no change of state"); m_pSpellState->m_bLockFocus = bLock; } diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 322928eb4e..073b6b5964 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -896,6 +896,25 @@ void SwEditWin::FlushInBuffer() return; SwWrtShell& rSh = m_rView.GetWrtShell(); + uno::Reference<frame::XDispatchRecorder> xRecorder + = m_rView.GetViewFrame().GetBindings().GetRecorder(); + + comphelper::ScopeGuard showTooltipGuard( + [this, &rSh] + { + SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get(); + const bool bAutoTextShown + = rACfg.IsAutoTextTip() && ShowAutoText(rSh.GetChunkForAutoText()); + if (!bAutoTextShown) + { + SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect(); + if (pACorr && pACorr->GetSwFlags().bAutoCompleteWords) + ShowAutoCorrectQuickHelp(rSh.GetPrevAutoCorrWord(*pACorr), *pACorr); + } + }); + if (!m_bMaybeShowTooltipAfterBufferFlush || xRecorder) + showTooltipGuard.dismiss(); + m_bMaybeShowTooltipAfterBufferFlush = false; // generate new sequence input checker if not already done if ( !pCheckIt ) @@ -993,8 +1012,6 @@ void SwEditWin::FlushInBuffer() } } - uno::Reference< frame::XDispatchRecorder > xRecorder = - m_rView.GetViewFrame().GetBindings().GetRecorder(); if ( xRecorder.is() ) { // determine shell @@ -1381,6 +1398,9 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt) } } + // Do not show autotext / word completion tooltips in intermediate flushes + m_bMaybeShowTooltipAfterBufferFlush = false; + sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode(); if (nKey == KEY_ESCAPE) @@ -2821,19 +2841,12 @@ KEYINPUT_CHECKTABLE_INSDEL: if( KEY_UP == nKey || KEY_DOWN == nKey || KEY_PAGEUP == nKey || KEY_PAGEDOWN == nKey ) GetView().GetViewFrame().GetBindings().Update( FN_STAT_PAGE ); + m_bMaybeShowTooltipAfterBufferFlush = bNormalChar; + // in case the buffered characters are inserted if( bFlushBuffer && !m_aInBuffer.isEmpty() ) { FlushInBuffer(); - - // maybe show Tip-Help - if (bNormalChar) - { - const bool bAutoTextShown - = pACfg && pACfg->IsAutoTextTip() && ShowAutoText(rSh.GetChunkForAutoText()); - if (!bAutoTextShown && pACorr && pACorr->GetSwFlags().bAutoCompleteWords) - ShowAutoCorrectQuickHelp(rSh.GetPrevAutoCorrWord(*pACorr), *pACorr); - } } // get the word count dialog to update itself @@ -4662,19 +4675,23 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) SdrObject* pObj = pSdrView ? pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER) : nullptr; if (pObj) { - SwFrameFormat* pFormat = GetUserCall(pObj)->GetFormat(); - SwFrameFormat* pShapeFormat = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT); - if (!pShapeFormat) - { - pSdrView->UnmarkAllObj(); - pSdrView->MarkObj(pObj,pPV); - } - else + if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj))) { - // If the fly frame is a textbox of a shape, then select the shape instead. - SdrObject* pShape = pShapeFormat->FindSdrObject(); - pSdrView->UnmarkAllObj(); - pSdrView->MarkObj(pShape, pPV); + SwFrameFormat* pFormat = pContact->GetFormat(); + SwFrameFormat* pShapeFormat + = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT); + if (!pShapeFormat) + { + pSdrView->UnmarkAllObj(); + pSdrView->MarkObj(pObj, pPV); + } + else + { + // If the fly frame is a textbox of a shape, then select the shape instead. + SdrObject* pShape = pShapeFormat->FindSdrObject(); + pSdrView->UnmarkAllObj(); + pSdrView->MarkObj(pShape, pPV); + } } } } diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx index 714e6bcc3b..ceaa98657f 100644 --- a/sw/source/uibase/inc/edtwin.hxx +++ b/sw/source/uibase/inc/edtwin.hxx @@ -122,7 +122,8 @@ class SW_DLLPUBLIC SwEditWin final : public vcl::DocWindow, selection position depending on what has changed lately */ m_bUseInputLanguage: 1, - m_bObjectSelect : 1; + m_bObjectSelect : 1, + m_bMaybeShowTooltipAfterBufferFlush : 1 = false; sal_uInt16 m_nKS_NUMDOWN_Count; // #i23725# sal_uInt16 m_nKS_NUMINDENTINC_Count; diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx index a5a63a6634..d5eec21320 100644 --- a/sw/source/uibase/shells/drwbassh.cxx +++ b/sw/source/uibase/shells/drwbassh.cxx @@ -836,8 +836,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); SwFrameFormat* pFrameFormat = FindFrameFormat(pObj); - SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); - rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient)); + if (pFrameFormat) + { + SwFormatHoriOrient aHOrient( + pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); + rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient)); + } } if (bVert && !bDisableThis && rMarkList.GetMarkCount() == 1) @@ -860,8 +864,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); SwFrameFormat* pFrameFormat = FindFrameFormat(pObj); - SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); - rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient)); + if (pFrameFormat) + { + SwFormatVertOrient aVOrient( + pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); + rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient)); + } } } break; diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx index 49086fa9a0..c6376910f1 100644 --- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx +++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx @@ -758,12 +758,18 @@ IMPL_LINK(WriterInspectorTextPanel, AttrChangedNotify, LinkParamNone*, pLink, vo if (m_oldLink.IsSet()) m_oldLink.Call(pLink); + if (m_pShell->IsViewLocked()) + { + return; // tdf#142806 avoid slowdown when storing files + } + SwDocShell* pDocSh = m_pShell->GetDoc()->GetDocShell(); std::vector<svx::sidebar::TreeNode> aStore; - SwEditShell* pEditSh = pDocSh ? pDocSh->GetDoc()->GetEditShell() : nullptr; - if (pEditSh && pEditSh->GetCursor()->GetPointNode().GetTextNode()) - UpdateTree(*pDocSh, *pEditSh, aStore, m_nParIdx); + if (m_pShell->GetCursor()->GetPointNode().GetTextNode()) + { + UpdateTree(*pDocSh, *m_pShell, aStore, m_nParIdx); + } updateEntries(aStore, m_nParIdx); } diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx b/sw/source/uibase/uno/SwXDocumentSettings.cxx index 3e40989828..66f3eef7db 100644 --- a/sw/source/uibase/uno/SwXDocumentSettings.cxx +++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx @@ -101,6 +101,7 @@ enum SwDocumentSettingsPropertyHandles HANDLE_CHANGES_PASSWORD, HANDLE_CONSIDER_WRAP_ON_OBJPOS, HANDLE_IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, + HANDLE_NO_GAP_AFTER_NOTE_NUMBER, HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, HANDLE_DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, HANDLE_TABLE_ROW_KEEP, @@ -205,6 +206,7 @@ static rtl::Reference<MasterPropertySetInfo> lcl_createSettingsInfo() { OUString("RedlineProtectionKey"), HANDLE_CHANGES_PASSWORD, cppu::UnoType< cppu::UnoSequenceType<sal_Int8> >::get(), 0}, { OUString("ConsiderTextWrapOnObjPos"), HANDLE_CONSIDER_WRAP_ON_OBJPOS, cppu::UnoType<bool>::get(), 0}, { OUString("IgnoreFirstLineIndentInNumbering"), HANDLE_IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, cppu::UnoType<bool>::get(), 0}, + { u"NoGapAfterNoteNumber"_ustr, HANDLE_NO_GAP_AFTER_NOTE_NUMBER, cppu::UnoType<bool>::get(), 0}, { OUString("DoNotJustifyLinesWithManualBreak"), HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, cppu::UnoType<bool>::get(), 0}, { OUString("DoNotResetParaAttrsForNumFont"), HANDLE_DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, cppu::UnoType<bool>::get(), 0}, { OUString("TableRowKeep"), HANDLE_TABLE_ROW_KEEP, cppu::UnoType<bool>::get(), 0}, @@ -699,6 +701,12 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, bTmp); } break; + case HANDLE_NO_GAP_AFTER_NOTE_NUMBER: + { + bool bTmp = *o3tl::doAccess<bool>(rValue); + mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER, bTmp); + } + break; case HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: { bool bTmp = *o3tl::doAccess<bool>(rValue); @@ -1379,6 +1387,11 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING); } break; + case HANDLE_NO_GAP_AFTER_NOTE_NUMBER: + { + rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER); + } + break; case HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: { rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK); diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 3bf29979dd..4e67041403 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -6085,13 +6085,13 @@ void SwContentTree::BringEntryToAttention(const weld::TreeIter& rEntry) for (auto n = pFormats->size(); 1 < n;) { SwIterator<SwTextINetFormat, SwCharFormat> aIter(*(*pFormats)[--n]); - for (SwTextINetFormat* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() ) + for (SwTextINetFormat* pFnd = aIter.First(); pFnd; pFnd = aIter.Next()) { if (pTextINetFormat == pFnd) { BringURLFieldsToAttention(SwGetINetAttrs {SwGetINetAttr(pCnt->GetName(), *pTextINetFormat)}); - break; + return; } } } |