sw/qa/core/data/html/fail/ofz5909-1.html | 1 sw/source/core/doc/htmltbl.cxx | 7 sw/source/filter/html/htmlftn.cxx | 31 +-- sw/source/filter/html/htmlnumreader.cxx | 14 + sw/source/filter/html/htmlsect.cxx | 6 sw/source/filter/html/htmltab.cxx | 245 ++++++++++++++++++++++++++++--- sw/source/filter/html/swhtml.cxx | 6 sw/source/filter/html/swhtml.hxx | 42 +++++ sw/source/filter/html/wrthtml.hxx | 4 9 files changed, 297 insertions(+), 59 deletions(-)
New commits: commit 2a2436c34ff70a99c803eac503f6495dcdeffc2d Author: Caolán McNamara <caol...@redhat.com> Date: Mon Jan 1 16:12:21 2018 +0000 ofz#4767 Bad-cast Reviewed-on: https://gerrit.libreoffice.org/47235 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 5670a9619b77a6a9e53b0cf20c059ea66ca5f450) Change-Id: Ibf8285efae7c570452954feb41a1a36bf44504a4 ofz: avoid deleting the table still being processed Change-Id: Ia92d469fd0e280bdc6470e780ab12b00366f0f8d Reviewed-on: https://gerrit.libreoffice.org/46902 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit f297b0d043e0767d85f00aa1e4cae5b036b0ac51) ofz#4753 Bad-cast, check all open tables Reviewed-on: https://gerrit.libreoffice.org/47199 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 80fc91db239869b513f47866f45d8a43fb98fe16) Change-Id: Ie6e2fb9f2e16e021a4719c418f52ce074c359904 CurrentTableInPaM->PendingTableInPaM Change-Id: Ic8b48d3b3e3f87e9ac3e8a6bb832f8e8dfe8ab7d (cherry picked from commit 2ed6eba4f99681fe717741ddc1534ed3ccc15e82) ofz#4848 Null-dereference READ Change-Id: I632aca7e3f59b7edf48c8c35eff4abf1946af652 (cherry picked from commit d4d0b1a2b9f11fb7629559e08c345697ba129c04) ofz#4817 Bad-cast Change-Id: I5dc9c66ce17f6401fbc9683cf8b10bf62755a166 Reviewed-on: https://gerrit.libreoffice.org/47236 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 9e269ef68e33fc9da154f6694be7cbcd5e3b4bfc) ofz#4872 Null-dereference READ we're going to need a bigger boat Reviewed-on: https://gerrit.libreoffice.org/47269 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit dfc72242e5bf67bdd5127bf38ed2ad5b3e49cea3) Change-Id: Ie4ee3ae1ac9f906ca3faec412bbafc0c6a911aaf ofz#4971 Bad-cast Reviewed-on: https://gerrit.libreoffice.org/47466 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit c75c3b2fdab5614664215e52d85657472ec86f05) Change-Id: Icf66aa82e72a2b9f24f590b84bb0441ebf09463f ofz#5007 Null-dereference READ Reviewed-on: https://gerrit.libreoffice.org/47537 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 6d05e0945054459ed04d50ae16731f933be48664) Change-Id: I830483071ce481fd14b0d1227c90e492e125f35e ofz#5235 Bad-cast Change-Id: I041f09f37941a92ccee3f0ebf9e5a950dee0c52f Reviewed-on: https://gerrit.libreoffice.org/47747 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 710cf469bf0e43a021fc1a24a80745bc602368ef) ofz#5909 Null-dereference READ Reviewed-on: https://gerrit.libreoffice.org/49218 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 5090d575117fbe6ced75dc45c514f8d990523251) Change-Id: I830d3e8bda517e7681cea7481c32457486ced693 ofz#6064 clear footnotes from tobe-deleted paragraph Change-Id: I33f75adab35d43a4bbf51e33a0abcb5daeca93a3 ofz: Null-deref Change-Id: I9992191fe5b4cfd771cc36a61d0ebaa8a9e6e9db Reviewed-on: https://gerrit.libreoffice.org/46743 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit e867b393ef95cb9bec7f68787771dfa329b00bea) ofz#4728 Null-deref Reviewed-on: https://gerrit.libreoffice.org/47000 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit f2e0c18cd44fff1e1b79924f582ced400fb00dad) Change-Id: Ide91a63424f864e2913b8268c4eca7961ba54572 Reviewed-on: https://gerrit.libreoffice.org/49357 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Michael Stahl <mst...@redhat.com> diff --git a/sw/qa/core/data/html/fail/ofz5909-1.html b/sw/qa/core/data/html/fail/ofz5909-1.html new file mode 100644 index 000000000000..9511b2bc1eac --- /dev/null +++ b/sw/qa/core/data/html/fail/ofz5909-1.html @@ -0,0 +1 @@ +<table><td><a class="sdfootnoteanc"href=" sdfootnote1 "></a><div id="sdfootnote1"><table><td> \ No newline at end of file diff --git a/sw/source/core/doc/htmltbl.cxx b/sw/source/core/doc/htmltbl.cxx index 9408d76aa681..92e156322230 100644 --- a/sw/source/core/doc/htmltbl.cxx +++ b/sw/source/core/doc/htmltbl.cxx @@ -559,10 +559,9 @@ void SwHTMLTableLayout::AutoLayoutPass1() nIdx++; } } - else + else if (SwHTMLTableLayout *pChild = pCnts->GetTable()) { OSL_ENSURE( false, "Sub tables in HTML import?" ); - SwHTMLTableLayout *pChild = pCnts->GetTable(); pChild->AutoLayoutPass1(); sal_uLong nMaxTableCnts = pChild->m_nMax; sal_uLong nAbsMinTableCnts = pChild->m_nMin; @@ -1606,7 +1605,7 @@ void SwHTMLTableLayout::SetWidths( bool bCallPass2, sal_uInt16 nAbsAvail, { SetBoxWidth( pBox, j, pCell->GetColSpan() ); } - else + else if (SwHTMLTableLayout *pTable = pContents->GetTable()) { sal_uInt16 nAbs = 0, nRel = 0, nLSpace = 0, nRSpace = 0, nInhSpace = 0; @@ -1618,7 +1617,7 @@ void SwHTMLTableLayout::SetWidths( bool bCallPass2, sal_uInt16 nAbsAvail, nRSpace = GetRightCellSpace( j, nColSpan ); nInhSpace = GetInhCellSpace( j, nColSpan ); } - pContents->GetTable()->SetWidths( bCallPass2, nAbs, nRel, + pTable->SetWidths( bCallPass2, nAbs, nRel, nLSpace, nRSpace, nInhSpace ); } diff --git a/sw/source/filter/html/htmlftn.cxx b/sw/source/filter/html/htmlftn.cxx index ef384761f2b3..749b01dcf142 100644 --- a/sw/source/filter/html/htmlftn.cxx +++ b/sw/source/filter/html/htmlftn.cxx @@ -31,17 +31,6 @@ #include "swhtml.hxx" #include "wrthtml.hxx" -struct SwHTMLFootEndNote_Impl -{ - SwHTMLTextFootnotes aTextFootnotes; - std::vector<OUString> aNames; - - OUString sName; - OUString sContent; // information for the last footnote - bool bEndNote; - bool bFixed; -}; - sal_Int32 lcl_html_getNextPart( OUString& rPart, const OUString& rContent, sal_Int32 nPos ) { @@ -209,11 +198,8 @@ void SwHTMLParser::FinishFootEndNote() m_pPam->GetNode().GetTextNode()->GetTextAttrForCharAt( m_pPam->GetPoint()->nContent.GetIndex() - 1, RES_TXTATR_FTN ) ); // In header and footer no footnotes can be inserted. - if( pTextFootnote ) - { - m_pFootEndNoteImpl->aTextFootnotes.push_back( pTextFootnote ); - m_pFootEndNoteImpl->aNames.push_back(m_pFootEndNoteImpl->sName); - } + if (pTextFootnote) + m_pFootEndNoteImpl->aTextFootnotes.push_back(SwHTMLTextFootnote(m_pFootEndNoteImpl->sName,pTextFootnote)); m_pFootEndNoteImpl->sName = aEmptyOUStr; m_pFootEndNoteImpl->sContent = aEmptyOUStr; m_pFootEndNoteImpl->bFixed = false; @@ -235,19 +221,18 @@ SwNodeIndex *SwHTMLParser::GetFootEndNoteSection( const OUString& rName ) { SwNodeIndex *pStartNodeIdx = nullptr; - if( m_pFootEndNoteImpl ) + if (m_pFootEndNoteImpl) { OUString aName(rName.toAsciiUpperCase()); - size_t nCount = m_pFootEndNoteImpl->aNames.size(); + size_t nCount = m_pFootEndNoteImpl->aTextFootnotes.size(); for(size_t i = 0; i < nCount; ++i) { - if(m_pFootEndNoteImpl->aNames[i] == aName) + if (m_pFootEndNoteImpl->aTextFootnotes[i].sName == aName) { - pStartNodeIdx = m_pFootEndNoteImpl->aTextFootnotes[i]->GetStartNode(); - m_pFootEndNoteImpl->aNames.erase(m_pFootEndNoteImpl->aNames.begin() + i); + pStartNodeIdx = m_pFootEndNoteImpl->aTextFootnotes[i].pTextFootnote->GetStartNode(); m_pFootEndNoteImpl->aTextFootnotes.erase( m_pFootEndNoteImpl->aTextFootnotes.begin() + i ); - if(m_pFootEndNoteImpl->aNames.empty()) + if (m_pFootEndNoteImpl->aTextFootnotes.empty()) { delete m_pFootEndNoteImpl; m_pFootEndNoteImpl = nullptr; @@ -288,7 +273,7 @@ Writer& OutHTML_SwFormatFootnote( Writer& rWrt, const SfxPoolItem& rHt ) } if( !rHTMLWrt.m_pFootEndNotes ) - rHTMLWrt.m_pFootEndNotes = new SwHTMLTextFootnotes; + rHTMLWrt.m_pFootEndNotes = new std::vector<SwTextFootnote*>; rHTMLWrt.m_pFootEndNotes->insert( rHTMLWrt.m_pFootEndNotes->begin() + nPos, pTextFootnote ); OStringBuffer sOut; diff --git a/sw/source/filter/html/htmlnumreader.cxx b/sw/source/filter/html/htmlnumreader.cxx index fbda0537a119..80b61b86f2d9 100644 --- a/sw/source/filter/html/htmlnumreader.cxx +++ b/sw/source/filter/html/htmlnumreader.cxx @@ -470,6 +470,13 @@ void SwHTMLParser::NewNumBulListItem( HtmlTokenId nToken ) AppendTextNode( AM_NOSPACE, false ); m_bNoParSpace = false; // no space in <LI>! + SwTextNode* pTextNode = m_pPam->GetNode().GetTextNode(); + if (!pTextNode) + { + SAL_WARN("sw.html", "No Text-Node at PaM-Position"); + return; + } + const bool bCountedInList = nToken != HtmlTokenId::LISTHEADER_ON; HTMLAttrContext *pCntxt = new HTMLAttrContext( nToken ); @@ -505,7 +512,6 @@ void SwHTMLParser::NewNumBulListItem( HtmlTokenId nToken ) m_nOpenParaToken = nToken; } - SwTextNode* pTextNode = m_pPam->GetNode().GetTextNode(); static_cast<SwContentNode *>(pTextNode)->SetAttr( SwNumRuleItem(aNumRuleName) ); pTextNode->SetAttrListLevel(nLevel); // #i57656# - <IsCounted()> state of text node has to be adjusted accordingly. @@ -599,7 +605,11 @@ void SwHTMLParser::EndNumBulListItem( HtmlTokenId nToken, bool bSetColl ) void SwHTMLParser::SetNodeNum( sal_uInt8 nLevel ) { SwTextNode* pTextNode = m_pPam->GetNode().GetTextNode(); - OSL_ENSURE( pTextNode, "No Text-Node at PaM-Position" ); + if (!pTextNode) + { + SAL_WARN("sw.html", "No Text-Node at PaM-Position"); + return; + } OSL_ENSURE( GetNumInfo().GetNumRule(), "No numbering rule" ); const OUString& rName = GetNumInfo().GetNumRule()->GetName(); diff --git a/sw/source/filter/html/htmlsect.cxx b/sw/source/filter/html/htmlsect.cxx index a63b788137fb..195de88cfd9d 100644 --- a/sw/source/filter/html/htmlsect.cxx +++ b/sw/source/filter/html/htmlsect.cxx @@ -198,7 +198,11 @@ void SwHTMLParser::NewDivision( HtmlTokenId nToken ) static_cast<const SwStartNode *>( &rContentStIdx.GetNode() ); aDelPam.GetPoint()->nNode = pStNd->EndOfSectionIndex() - 1; - m_xDoc->getIDocumentContentOperations().DelFullPara( aDelPam ); + if (!PendingObjectsInPaM(aDelPam)) + { + ClearFootnotesInRange(aDelPam.GetMark()->nNode, aDelPam.GetPoint()->nNode); + m_xDoc->getIDocumentContentOperations().DelFullPara(aDelPam); + } // update page style for( size_t i=0; i < m_xDoc->GetPageDescCnt(); i++ ) diff --git a/sw/source/filter/html/htmltab.cxx b/sw/source/filter/html/htmltab.cxx index b3f7ca1e663f..f3a96c5e9278 100644 --- a/sw/source/filter/html/htmltab.cxx +++ b/sw/source/filter/html/htmltab.cxx @@ -35,6 +35,7 @@ #include <svl/urihelper.hxx> #include <o3tl/make_unique.hxx> +#include <dcontact.hxx> #include <fmtornt.hxx> #include <frmfmt.hxx> #include <fmtfsize.hxx> @@ -58,6 +59,7 @@ #include "swhtml.hxx" #include "swcss1.hxx" #include <numrule.hxx> +#include <txtftn.hxx> #define NETSCAPE_DFLT_BORDER 1 #define NETSCAPE_DFLT_CELLSPACING 2 @@ -617,6 +619,8 @@ public: void IncBoxCount() { m_nBoxes++; } bool IsOverflowing() const { return m_nBoxes > 64000; } + + bool PendingDrawObjectsInPaM(SwPaM& rPam) const; }; void HTMLTableCnts::InitCtor() @@ -1068,10 +1072,14 @@ HTMLTable::HTMLTable( SwHTMLParser* pPars, HTMLTable *pTopTab, for( sal_uInt16 i=0; i<m_nCols; i++ ) m_pColumns->push_back(o3tl::make_unique<HTMLTableColumn>()); + + m_pParser->RegisterHTMLTable(this); } HTMLTable::~HTMLTable() { + m_pParser->DeregisterHTMLTable(this); + delete m_pResizeDrawObjects; delete m_pDrawObjectPrcWidths; @@ -1704,9 +1712,9 @@ SwTableBox *HTMLTable::MakeTableBox( SwTableLine *pUpper, pBox = NewTableBox( pCnts->GetStartNode(), pUpper ); pCnts->SetTableBox( pBox ); } - else + else if (HTMLTable* pTable = pCnts->GetTable()) { - pCnts->GetTable()->InheritVertBorders( this, nLeftCol, + pTable->InheritVertBorders( this, nLeftCol, nRightCol-nLeftCol ); // ... that's a table. We'll build a new box and put the rows of the table // in the rows of the box @@ -1719,6 +1727,10 @@ SwTableBox *HTMLTable::MakeTableBox( SwTableLine *pUpper, pCnts->GetTable()->MakeTable( pBox, nAbs, nRel, nLSpace, nRSpace, nInhSpace ); } + else + { + return nullptr; + } } else { @@ -2398,6 +2410,12 @@ void HTMLTable::MakeTable( SwTableBox *pBox, sal_uInt16 nAbsAvail, break; } + if (!m_pSwTable) + { + SAL_WARN("sw.html", "no table"); + return; + } + // get the table format and adapt it SwFrameFormat *pFrameFormat = m_pSwTable->GetFrameFormat(); pFrameFormat->SetFormatAttr( SwFormatHoriOrient(0,eHoriOri) ); @@ -3588,6 +3606,7 @@ void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, bool bReadOptions, const SwTable* pSwTable = m_xDoc->InsertTable( SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ), *m_pPam->GetPoint(), 1, 1, text::HoriOrientation::LEFT ); + SwFrameFormat *pFrameFormat = pSwTable ? pSwTable->GetFrameFormat() : nullptr; if( bForceFrame ) { @@ -3597,22 +3616,20 @@ void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, bool bReadOptions, } else { - if( bStyleParsed ) + if (bStyleParsed && pFrameFormat) { m_pCSS1Parser->SetFormatBreak( aItemSet, aPropInfo ); - pSwTable->GetFrameFormat()->SetFormatAttr( aItemSet ); + pFrameFormat->SetFormatAttr( aItemSet ); } m_pPam->Move( fnMoveBackward ); } SwNode const*const pNd = & m_pPam->GetPoint()->nNode.GetNode(); - if( !bAppended && !bForceFrame ) - { - SwTextNode *const pOldTextNd = - pSavePos->nNode.GetNode().GetTextNode(); - OSL_ENSURE( pOldTextNd, "Why we aren't in a text node?" ); - SwFrameFormat *pFrameFormat = pSwTable->GetFrameFormat(); + SwTextNode *const pOldTextNd = (!bAppended && !bForceFrame) ? + pSavePos->nNode.GetNode().GetTextNode() : nullptr; + if (pFrameFormat && pOldTextNd) + { const SfxPoolItem* pItem2; if( SfxItemState::SET == pOldTextNd->GetSwAttrSet() .GetItemState( RES_PAGEDESC, false, &pItem2 ) && @@ -3925,15 +3942,21 @@ void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, bool bReadOptions, InsertTableSection( static_cast< sal_uInt16 >(pSaveStruct->IsHeaderCell() ? RES_POOLCOLL_TABLE_HDLN : RES_POOLCOLL_TABLE )); - const SwEndNode *pEndNd = pStNd->EndOfSectionNode(); - SwContentNode *pCNd = m_xDoc->GetNodes()[pEndNd->GetIndex()-1] ->GetContentNode(); - //Added defaults to CJK and CTL - SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE ); - pCNd->SetAttr( aFontHeight ); - SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE ); - pCNd->SetAttr( aFontHeightCJK ); - SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE ); - pCNd->SetAttr( aFontHeightCTL ); + + if (!pStNd) + eState = SvParserState::Error; + else + { + const SwEndNode *pEndNd = pStNd->EndOfSectionNode(); + SwContentNode *pCNd = m_xDoc->GetNodes()[pEndNd->GetIndex()-1] ->GetContentNode(); + //Added defaults to CJK and CTL + SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE ); + pCNd->SetAttr( aFontHeight ); + SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE ); + pCNd->SetAttr( aFontHeightCJK ); + SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE ); + pCNd->SetAttr( aFontHeightCTL ); + } pSaveStruct->AddContents( new HTMLTableCnts(pStNd) ); pSaveStruct->ClearIsInSection(); @@ -4966,6 +4989,134 @@ HTMLTableOptions::HTMLTableOptions( const HTMLOptions& rOptions, } } +namespace +{ + class FrameDeleteWatch : public SwClient + { + SwFrameFormat* m_pObjectFormat; + bool m_bDeleted; + public: + FrameDeleteWatch(SwFrameFormat* pObjectFormat) + : m_pObjectFormat(pObjectFormat) + , m_bDeleted(false) + { + if (m_pObjectFormat) + m_pObjectFormat->Add(this); + + } + + virtual void SwClientNotify(const SwModify& rModify, const SfxHint& rHint) override + { + SwClient::SwClientNotify(rModify, rHint); + if (auto pDrawFrameFormatHint = dynamic_cast<const sw::DrawFrameFormatHint*>(&rHint)) + { + if (pDrawFrameFormatHint->m_eId == sw::DrawFrameFormatHintId::DYING) + { + m_pObjectFormat->Remove(this); + m_bDeleted = true; + } + } + } + + bool WasDeleted() const + { + return m_bDeleted; + } + + virtual ~FrameDeleteWatch() override + { + if (!m_bDeleted && m_pObjectFormat) + m_pObjectFormat->Remove(this); + } + }; + + class IndexInRange + { + private: + SwNodeIndex maStart; + SwNodeIndex maEnd; + public: + explicit IndexInRange(const SwNodeIndex& rStart, const SwNodeIndex& rEnd) + : maStart(rStart) + , maEnd(rEnd) + { + } + bool operator()(const SwHTMLTextFootnote& rTextFootnote) const + { + const SwNodeIndex aTextIdx(rTextFootnote.pTextFootnote->GetTextNode()); + return aTextIdx >= maStart && aTextIdx <= maEnd; + } + }; +} + +void SwHTMLParser::ClearFootnotesInRange(const SwNodeIndex& rMkNdIdx, const SwNodeIndex& rPtNdIdx) +{ + //similarly for footnotes + if (m_pFootEndNoteImpl) + { + m_pFootEndNoteImpl->aTextFootnotes.erase(std::remove_if(m_pFootEndNoteImpl->aTextFootnotes.begin(), + m_pFootEndNoteImpl->aTextFootnotes.end(), IndexInRange(rMkNdIdx, rPtNdIdx)), m_pFootEndNoteImpl->aTextFootnotes.end()); + if (m_pFootEndNoteImpl->aTextFootnotes.empty()) + { + delete m_pFootEndNoteImpl; + m_pFootEndNoteImpl = nullptr; + } + } + + //follow DelFlyInRange pattern here + const bool bDelFwrd = rMkNdIdx.GetIndex() <= rPtNdIdx.GetIndex(); + + SwDoc* pDoc = rMkNdIdx.GetNode().GetDoc(); + SwFrameFormats& rTable = *pDoc->GetSpzFrameFormats(); + for ( auto i = rTable.size(); i; ) + { + SwFrameFormat *pFormat = rTable[--i]; + const SwFormatAnchor &rAnch = pFormat->GetAnchor(); + SwPosition const*const pAPos = rAnch.GetContentAnchor(); + if (pAPos && + ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA) || + (rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR)) && + ( bDelFwrd + ? rMkNdIdx < pAPos->nNode && pAPos->nNode <= rPtNdIdx + : rPtNdIdx <= pAPos->nNode && pAPos->nNode < rMkNdIdx )) + { + if( rPtNdIdx != pAPos->nNode ) + { + // If the Fly is deleted, all Flys in its content have to be deleted too. + const SwFormatContent &rContent = pFormat->GetContent(); + // But only fly formats own their content, not draw formats. + if (rContent.GetContentIdx() && pFormat->Which() == RES_FLYFRMFMT) + { + ClearFootnotesInRange(*rContent.GetContentIdx(), + SwNodeIndex(*rContent.GetContentIdx()->GetNode().EndOfSectionNode())); + } + } + } + } +} + +void SwHTMLParser::DeleteSection(SwStartNode* pSttNd) +{ + //if section to be deleted contains a pending m_pMarquee, it will be deleted + //so clear m_pMarquee pointer if that's the case + SwFrameFormat* pObjectFormat = m_pMarquee ? ::FindFrameFormat(m_pMarquee) : nullptr; + FrameDeleteWatch aWatch(pObjectFormat); + + //similarly for footnotes + SwNodeIndex aSttIdx(*pSttNd), aEndIdx(*pSttNd->EndOfSectionNode()); + ClearFootnotesInRange(aSttIdx, aEndIdx); + + m_xDoc->getIDocumentContentOperations().DeleteSection(pSttNd); + + if (pObjectFormat) + { + if (aWatch.WasDeleted()) + m_pMarquee = nullptr; + else + pObjectFormat->Remove(&aWatch); + } +} + HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust, bool bIsParentHead, bool bHasParentSection, @@ -5180,7 +5331,7 @@ HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust, // The section isn't needed anymore m_pPam->SetMark(); m_pPam->DeleteMark(); - m_xDoc->getIDocumentContentOperations().DeleteSection( const_cast<SwStartNode *>(pCapStNd) ); + DeleteSection(const_cast<SwStartNode*>(pCapStNd)); m_pTable->SetCaption( nullptr, false ); } @@ -5199,8 +5350,9 @@ HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust, m_bUpperSpace = true; SetTextCollAttrs(); - m_nParaCnt = m_nParaCnt - std::min(m_nParaCnt, - pTCntxt->GetTableNode()->GetTable().GetTabSortBoxes().size()); + SwTableNode* pTableNode = pTCntxt->GetTableNode(); + size_t nTableBoxSize = pTableNode ? pTableNode->GetTable().GetTabSortBoxes().size() : 0; + m_nParaCnt = m_nParaCnt - std::min(m_nParaCnt, nTableBoxSize); // Jump to a table if needed if( JUMPTO_TABLE == m_eJumpTo && m_pTable->GetSwTable() && @@ -5229,7 +5381,7 @@ HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust, { m_pPam->SetMark(); m_pPam->DeleteMark(); - m_xDoc->getIDocumentContentOperations().DeleteSection( const_cast<SwStartNode *>(pCapStNd) ); + DeleteSection(const_cast<SwStartNode*>(pCapStNd)); pCurTable->SetCaption( nullptr, false ); } } @@ -5247,4 +5399,51 @@ HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust, return pRetTable; } +bool HTMLTable::PendingDrawObjectsInPaM(SwPaM& rPam) const +{ + if (!m_pResizeDrawObjects) + return false; + + bool bRet = false; + + sal_uInt16 nCount = m_pResizeDrawObjects->size(); + for (sal_uInt16 i = 0; i < nCount && !bRet; ++i) + { + SdrObject *pObj = (*m_pResizeDrawObjects)[i]; + SwFrameFormat* pObjectFormat = ::FindFrameFormat(pObj); + if (!pObjectFormat) + continue; + const SwFormatAnchor& rAnch = pObjectFormat->GetAnchor(); + if (const SwPosition* pPos = rAnch.GetContentAnchor()) + { + SwNodeIndex aObjNodeIndex(pPos->nNode); + bRet = (aObjNodeIndex >= rPam.Start()->nNode && aObjNodeIndex <= rPam.End()->nNode); + } + } + + return bRet; +} + +bool SwHTMLParser::PendingObjectsInPaM(SwPaM& rPam) const +{ + bool bRet = false; + for (const auto& a : m_aTables) + { + bRet = a->PendingDrawObjectsInPaM(rPam); + if (bRet) + break; + const SwTable *pTable = a->GetSwTable(); + if (!pTable) + continue; + const SwTableNode* pTableNode = pTable->GetTableNode(); + if (!pTableNode) + continue; + SwNodeIndex aTableNodeIndex(*pTableNode); + bRet = (aTableNodeIndex >= rPam.Start()->nNode && aTableNodeIndex <= rPam.End()->nNode); + if (bRet) + break; + } + return bRet; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx index e483f926ee04..01f15c570a30 100644 --- a/sw/source/filter/html/swhtml.cxx +++ b/sw/source/filter/html/swhtml.cxx @@ -1452,10 +1452,10 @@ void SwHTMLParser::NextToken( HtmlTokenId nToken ) if( !aToken.isEmpty() && ' '==aToken[0] && !IsReadPRE() ) { sal_Int32 nPos = m_pPam->GetPoint()->nContent.GetIndex(); - if( nPos ) + const SwTextNode* pTextNode = nPos ? m_pPam->GetPoint()->nNode.GetNode().GetTextNode() : nullptr; + if (pTextNode) { - const OUString& rText = - m_pPam->GetPoint()->nNode.GetNode().GetTextNode()->GetText(); + const OUString& rText = pTextNode->GetText(); sal_Unicode cLast = rText[--nPos]; if( ' ' == cLast || '\x0a' == cLast) aToken = aToken.copy(1); diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx index 6e84380cdfe1..5ca8ec1d9ab6 100644 --- a/sw/source/filter/html/swhtml.hxx +++ b/sw/source/filter/html/swhtml.hxx @@ -408,6 +408,7 @@ class SwHTMLParser : public SfxHTMLParser, public SwClient SwNodeIndex *m_pSttNdIdx; HTMLTable *m_pTable; // current "outermost" table + std::vector<HTMLTable*> m_aTables; SwHTMLForm_Impl *m_pFormImpl; // current form SdrObject *m_pMarquee; // current marquee SwField *m_pField; // current field @@ -647,6 +648,10 @@ class SwHTMLParser : public SfxHTMLParser, public SwClient // tags realized via character styles void NewCharFormat( HtmlTokenId nToken ); + void ClearFootnotesInRange(const SwNodeIndex& rSttIdx, const SwNodeIndex& rEndIdx); + + void DeleteSection(SwStartNode* pSttNd); + // <SDFIELD> public: static SvxNumType GetNumType( const OUString& rStr, SvxNumType eDfltType ); @@ -861,6 +866,8 @@ private: bool HasCurrentParaFlys( bool bNoSurroundOnly = false, bool bSurroundOnly = false ) const; + bool PendingObjectsInPaM(SwPaM& rPam) const; + public: // used in tables // Create brush item (with new) or 0 @@ -898,6 +905,18 @@ public: virtual bool ParseMetaOptions( const css::uno::Reference<css::document::XDocumentProperties>&, SvKeyValueIterator* ) override; + + + void RegisterHTMLTable(HTMLTable* pNew) + { + m_aTables.push_back(pNew); + } + + void DeregisterHTMLTable(HTMLTable* pOld) + { + m_aTables.erase(std::remove(m_aTables.begin(), m_aTables.end(), pOld)); + } + }; struct SwPendingStackData @@ -977,6 +996,29 @@ inline void SwHTMLParser::PushContext( HTMLAttrContext *pCntxt ) m_aContexts.push_back( pCntxt ); } +class SwTextFootnote; + +struct SwHTMLTextFootnote +{ + OUString sName; + SwTextFootnote* pTextFootnote; + SwHTMLTextFootnote(const OUString &rName, SwTextFootnote* pInTextFootnote) + : sName(rName) + , pTextFootnote(pInTextFootnote) + { + } +}; + +struct SwHTMLFootEndNote_Impl +{ + std::vector<SwHTMLTextFootnote> aTextFootnotes; + + OUString sName; + OUString sContent; // information for the last footnote + bool bEndNote; + bool bFixed; +}; + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx index bacea748f300..8b3ee66e163c 100644 --- a/sw/source/filter/html/wrthtml.hxx +++ b/sw/source/filter/html/wrthtml.hxx @@ -59,8 +59,6 @@ class SwHTMLPosFlyFrames; class SwTextFootnote; enum class HtmlPosition; -typedef std::vector<SwTextFootnote*> SwHTMLTextFootnotes; - extern SwAttrFnTab aHTMLAttrFnTab; #define HTML_PARSPACE (MM50) @@ -286,7 +284,7 @@ public: SwHTMLFormatInfos m_CharFormatInfos; SwHTMLFormatInfos m_TextCollInfos; std::vector<SwFormatINetFormat*> m_aINetFormats; // the "open" INet attributes - SwHTMLTextFootnotes *m_pFootEndNotes; + std::vector<SwTextFootnote*> *m_pFootEndNotes; OUString m_aCSS1Selector; // style selector OUString m_aNonConvertableCharacters; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits