offapi/com/sun/star/text/TextRangeContentProperties.idl | 6 solenv/gbuild/platform/filter-showIncludes.awk | 7 sw/inc/cmdid.h | 1 sw/inc/unoprnms.hxx | 1 sw/qa/extras/odfimport/data/i61225.sxw |binary sw/qa/extras/odfimport/odfimport.cxx | 8 sw/qa/extras/uiwriter/data/i95698.odt |binary sw/qa/extras/uiwriter/data/lines-in-section-in-table.odt |binary sw/qa/extras/uiwriter/data/paragraph-of-text-range.odt |binary sw/qa/extras/uiwriter/data/rhbz739252-3.odt |binary sw/qa/extras/uiwriter/data/table-in-sect.odt |binary sw/qa/extras/uiwriter/data/tdf108524.odt |binary sw/qa/extras/uiwriter/uiwriter.cxx | 126 +++++++++++++++ sw/source/core/inc/cellfrm.hxx | 1 sw/source/core/layout/findfrm.cxx | 20 +- sw/source/core/layout/flowfrm.cxx | 5 sw/source/core/layout/sectfrm.cxx | 66 ++++++- sw/source/core/layout/tabfrm.cxx | 39 ++++ sw/source/core/unocore/unocrsrhelper.cxx | 13 + sw/source/core/unocore/unomapproperties.hxx | 1 sw/source/uibase/inc/unodispatch.hxx | 7 sw/source/uibase/uno/unodispatch.cxx | 10 + 22 files changed, 293 insertions(+), 18 deletions(-)
New commits: commit 3ff777ef14f690946073aa7b48cd6953412e4db1 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Wed Aug 16 17:19:05 2017 +0200 i#95698 sw: fix crash on splitting in-table section containing a nested table Found by crashtesting, ooo95698-1.odt crashed sw layout on load. The intended use-case is splitting section frames inside a table frame, so can just blacklist the non-interesting table-in-section-in-table case that causes the problem here. Reviewed-on: https://gerrit.libreoffice.org/41224 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit 802477ae75b39194442d9c01a1342d068c7b9300) Conflicts: sw/qa/extras/uiwriter/uiwriter.cxx Change-Id: Ic47cd8c46cc71f7eaa36b03ec2c4a5df8ca8051c diff --git a/sw/qa/extras/uiwriter/data/i95698.odt b/sw/qa/extras/uiwriter/data/i95698.odt new file mode 100644 index 000000000000..9fe3ec207648 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/i95698.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 3d566b5df278..c23c0e825d27 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -203,6 +203,7 @@ public: void testTdf108524(); void testTableInSection(); void testTableInNestedSection(); + void testTableInSectionInTable(); void testLinesInSectionInTable(); void testLinesMoveBackwardsInSectionInTable(); @@ -312,6 +313,7 @@ public: CPPUNIT_TEST(testTableInSection); CPPUNIT_TEST(testTableInNestedSection); CPPUNIT_TEST(testLinesInSectionInTable); + CPPUNIT_TEST(testTableInSectionInTable); CPPUNIT_TEST(testLinesMoveBackwardsInSectionInTable); CPPUNIT_TEST_SUITE_END(); @@ -3820,6 +3822,14 @@ void SwUiWriterTest::testTableInNestedSection() assertXPath(pXmlDoc, "//page[2]//section/tab", 1); } +void SwUiWriterTest::testTableInSectionInTable() +{ + // The document has a table, containing a section, containing a nested + // table. + // This crashed the layout. + createDoc("i95698.odt"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index 45282d886929..0c6db983d50d 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -916,9 +916,21 @@ static bool lcl_FindSectionsInRow( const SwRowFrame& rRow ) if (const SwFrame* pSectionLower = pTmpFrame->GetLower()) { if (!pSectionLower->IsColumnFrame()) + { // Section has a single column only, try to // split that. bRet = false; + + for (const SwFrame* pFrame = pSectionLower; pFrame; pFrame = pFrame->GetNext()) + { + if (pFrame->IsTabFrame()) + { + // Section contains a table, no split in that case. + bRet = true; + break; + } + } + } } } } commit b77bf30b9cbf6dc2789610dadf0ae44acd38b586 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Jul 14 16:05:10 2017 +0200 CppunitTest_sw_uiwriter: disable testLinesMoveBackwards... on macOS No idea off the top of my head what is the problem here, seeing Linux and Windows is happy; clang on Linux as well. Change-Id: I56c79b37a5648d9afd02d8e161ea4a279cc89744 (cherry picked from commit 39dd0121f5994dee56f95bc57fae3323bf849a20) diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index bef73ba6eeff..3d566b5df278 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -3769,6 +3769,7 @@ void SwUiWriterTest::testLinesInSectionInTable() void SwUiWriterTest::testLinesMoveBackwardsInSectionInTable() { +#ifndef MACOSX // Assert that paragraph "4" is on page 1 and "5" is on page 2. SwDoc* pDoc = createDoc("lines-in-section-in-table.odt"); xmlDocPtr pXmlDoc = parseLayoutDump(); @@ -3792,6 +3793,7 @@ void SwUiWriterTest::testLinesMoveBackwardsInSectionInTable() sal_uInt32 nPage1LastNode = getXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell[1]/section/txt[last()]", "txtNodeIndex").toUInt32(); // This was "3", paragraph "4" was deleted, but "5" was not moved backwards from page 2. CPPUNIT_ASSERT_EQUAL(OUString("5"), pDoc->GetNodes()[nPage1LastNode]->GetTextNode()->GetText()); +#endif } void SwUiWriterTest::testTableInSection() commit 81b23b435c8add07afb06b01b85afb5aa56d1ff0 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Jul 14 14:20:36 2017 +0200 tdf#108524 sw: handle sections inside tables in SwFrame::GetPrevSctLeaf() This addresses the sub-problem described in comment 12 of the bug, i.e. text frames are now moved to the first page from the second one when text frames are deleted on the first page. Change-Id: Ic0ede45381fb84b13d1ac02e4d1f39d817650616 Reviewed-on: https://gerrit.libreoffice.org/39946 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit 850bf99e7d1abcf2e0cce731b6715f87420d0ee6) diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index d536d1e92f65..bef73ba6eeff 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -204,6 +204,7 @@ public: void testTableInSection(); void testTableInNestedSection(); void testLinesInSectionInTable(); + void testLinesMoveBackwardsInSectionInTable(); CPPUNIT_TEST_SUITE(SwUiWriterTest); CPPUNIT_TEST(testReplaceForward); @@ -311,6 +312,7 @@ public: CPPUNIT_TEST(testTableInSection); CPPUNIT_TEST(testTableInNestedSection); CPPUNIT_TEST(testLinesInSectionInTable); + CPPUNIT_TEST(testLinesMoveBackwardsInSectionInTable); CPPUNIT_TEST_SUITE_END(); private: @@ -3765,6 +3767,33 @@ void SwUiWriterTest::testLinesInSectionInTable() assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell/section", 1); } +void SwUiWriterTest::testLinesMoveBackwardsInSectionInTable() +{ + // Assert that paragraph "4" is on page 1 and "5" is on page 2. + SwDoc* pDoc = createDoc("lines-in-section-in-table.odt"); + xmlDocPtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page", 2); + sal_uInt32 nPara4Node = getXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell[1]/section/txt[last()]", "txtNodeIndex").toUInt32(); + CPPUNIT_ASSERT_EQUAL(OUString("4"), pDoc->GetNodes()[nPara4Node]->GetTextNode()->GetText()); + sal_uInt32 nPara5Node = getXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell[1]/section/txt[1]", "txtNodeIndex").toUInt32(); + CPPUNIT_ASSERT_EQUAL(OUString("5"), pDoc->GetNodes()[nPara5Node]->GetTextNode()->GetText()); + + // Remove paragraph "4". + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + while (pWrtShell->GetCursor()->GetNode().GetIndex() < nPara4Node) + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->EndPara(); + pWrtShell->Up(/*bSelect=*/true); + pWrtShell->DelLeft(); + + // Assert that paragraph "5" is now moved back to page 1 and is the last paragraph there. + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + sal_uInt32 nPage1LastNode = getXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell[1]/section/txt[last()]", "txtNodeIndex").toUInt32(); + // This was "3", paragraph "4" was deleted, but "5" was not moved backwards from page 2. + CPPUNIT_ASSERT_EQUAL(OUString("5"), pDoc->GetNodes()[nPage1LastNode]->GetTextNode()->GetText()); +} + void SwUiWriterTest::testTableInSection() { // The document has a section, containing a table that spans over 2 pages. diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index ed15376a99ef..dcf60c14df3c 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -1726,11 +1726,24 @@ SwLayoutFrame *SwFrame::GetPrevSctLeaf( MakePageType ) if( bJump ) // Did we skip a blank page? SwFlowFrame::SetMoveBwdJump( true ); + SwSectionFrame *pSect = FindSctFrame(); + if (!pCol && pSect && IsInTab() && !IsInTableInSection(this)) + { + // We don't have a previous section yet, and we're in a + // section-in-table. + if (SwFlowFrame* pPrecede = pSect->GetPrecede()) + { + // Our section has a precede, work with that. + if (pPrecede->GetFrame().IsLayoutFrame()) + pCol = static_cast<SwLayoutFrame*>(&pPrecede->GetFrame()); + } + } + // Within sections in tables or section in headers/footers there can // be only one column change be made, one of the above shortcuts should // have applied, also when the section has a pPrev. // Now we even consider an empty column... - OSL_ENSURE( FindSctFrame(), "GetNextSctLeaf: Missing SectionFrame" ); + OSL_ENSURE( pSect, "GetNextSctLeaf: Missing SectionFrame" ); if( ( IsInTab() && !IsTabFrame() ) || FindFooterOrHeader() ) return pCol; @@ -1738,7 +1751,6 @@ SwLayoutFrame *SwFrame::GetPrevSctLeaf( MakePageType ) // Precondition, which needs to be hold, is that the <this> frame can be // inside a table, but then the found section frame <pSect> is also inside // this table. - SwSectionFrame *pSect = FindSctFrame(); // #i95698# // A table cell containing directly a section does not break - see lcl_FindSectionsInRow(..) commit 1b7f65ed1d29608062c3b1136e715b4fd01530b4 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Jul 13 15:54:23 2017 +0200 tdf#108524 sw: allow frames in follow sect-in-tables in SwFlowFrame::MoveBwd() The intention is to filter out text frames directly inside tables; since tables in general reflow by moving all of the content to the first page, then moving not fitting content to the next pages. Section frames are different, there we explicitly move content backwards, similarly to page body frames. Teach SwFlowFrame::MoveFwd() that a text frame inside a section-in-table is the section situation, not the table situation, since what matters here is the direct parent. To be on the safe side allow this for follow section frames only. This is necessary, but not enough to address the sub-problem described in comment 12 of the bug. At least SwFrame::GetPrevSctLeaf() is invoked to consider a precede section frame, though. Change-Id: Ic88602cffefbbc81ecc90e3880be2a098f60fb04 (cherry picked from commit 4908d6d6742e2f0700ea4ccd9d636d91ea281046) diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index 3f708e2c3320..ddf1c6d02def 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -2008,7 +2008,10 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat ) { return false; } - if ( pUpperFrame->IsColumnFrame() && pUpperFrame->IsInSct() ) + // If the text frame is a follow-section-in-table, that can move + // backward as well. + bool bIsFollowSection = pUpperFrame->IsSctFrame() && static_cast<const SwSectionFrame*>(pUpperFrame)->GetPrecede(); + if ( ( pUpperFrame->IsColumnFrame() && pUpperFrame->IsInSct() ) || bIsFollowSection ) { break; } commit 72921a4401706fd674d8a15d8b39a4996b64f9fe Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Wed Jul 12 17:53:40 2017 +0200 tdf#108524 sw: allow frames in growable follow sects in SwFrame::IsMoveable() In general the move of frames inside growable sections is not allowed, so that the behavior is deterministic: either the section grows or content is moved to a follow section frame. But in case of split sections it is necessary to allow the move of text frames inside growable section frames, otherwise it is impossible to move text frames from the last follow of a section frame to the previous one. This is necessary, but not enough to address the sub-problem described in comment 12 of the bug. At least now SwFlowFrame::MoveBwd() is invoked to consider moving the frame backwards, though. Change-Id: I0b79e9db72a4e335701491dd6f7745058901e176 Reviewed-on: https://gerrit.libreoffice.org/39873 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit 5b9edf5d5779b9ce578084250a6c87808ddc5fa8) diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index 3ad50a012d13..116ccd430d63 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -1264,8 +1264,12 @@ static bool lcl_IsInSectionDirectly( const SwFrame *pUp ) if( pUp->IsColumnFrame() ) bSeenColumn = true; else if( pUp->IsSctFrame() ) + { + auto pSection = static_cast<const SwSectionFrame*>(pUp); // Allow move of frame in case our only column is not growable. - return bSeenColumn || !static_cast<const SwSectionFrame*>(pUp)->Growable(); + // Also allow if there is a previous section frame (to move back). + return bSeenColumn || !pSection->Growable() || pSection->GetPrecede(); + } else if( pUp->IsTabFrame() ) return false; pUp = pUp->GetUpper(); commit 8caffe13ad738d759c07b3aa0ea20ce2c170cbbe Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Jul 7 14:04:28 2017 +0200 rhbz#739252 sw: fix crash on split tables inside nested sections Commit b5e0a143308e976b4165ff6181f4dccc3db0bd31 (tdf#108524 sw: attempt to split section frames inside table cells, take two, 2017-07-03) checked for tables in SwFrame::GetNextSctLeaf() when it considered looking up the next "follow" cell frame. But this is too general, in practice it is only necessary to look for follow cell frames in case the frame in question is in a table, but not in a table-in-section. This at the same time avoids a crash with tables inside nested sections, as it happens in the bugdoc. Reviewed-on: https://gerrit.libreoffice.org/39692 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit 652556ec3e9218655a67b4c4de4e26fbe81855de) Conflicts: sw/source/core/layout/sectfrm.cxx Change-Id: If648cb477be5492c7158f89934435ca7021a6a63 diff --git a/sw/qa/extras/uiwriter/data/rhbz739252-3.odt b/sw/qa/extras/uiwriter/data/rhbz739252-3.odt new file mode 100644 index 000000000000..e457c035b662 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/rhbz739252-3.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index f646347a4b30..d536d1e92f65 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -202,6 +202,7 @@ public: void testParagraphOfTextRange(); void testTdf108524(); void testTableInSection(); + void testTableInNestedSection(); void testLinesInSectionInTable(); CPPUNIT_TEST_SUITE(SwUiWriterTest); @@ -308,6 +309,7 @@ public: CPPUNIT_TEST(testTdf108524); CPPUNIT_TEST(testTdf108524); CPPUNIT_TEST(testTableInSection); + CPPUNIT_TEST(testTableInNestedSection); CPPUNIT_TEST(testLinesInSectionInTable); CPPUNIT_TEST_SUITE_END(); @@ -3776,6 +3778,17 @@ void SwUiWriterTest::testTableInSection() assertXPath(pXmlDoc, "/root/page[2]/body/section/tab/row/cell", 2); } +void SwUiWriterTest::testTableInNestedSection() +{ + // The document has a nested section, containing a table that spans over 2 pages. + // This crashed the layout. + createDoc("rhbz739252-3.odt"); + xmlDocPtr pXmlDoc = parseLayoutDump(); + // Make sure the table is inside a section and spans over 2 pages. + assertXPath(pXmlDoc, "//page[1]//section/tab", 1); + assertXPath(pXmlDoc, "//page[2]//section/tab", 1); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 5a11d6bfed66..ed15376a99ef 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -1515,9 +1515,10 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) SwLayoutFrame *pLayLeaf; SwLayoutFrame* pCellLeaf = nullptr; - if (IsInTab()) + if (IsInTab() && !IsInTableInSection(this)) { - // We are in a table, see if there is a follow cell frame created already. + // We are in a table (which is itself not in a section), see if there + // is a follow cell frame created already. pCellLeaf = GetNextCellLeaf(MAKEPAGE_NONE); if (!pCellLeaf) { commit ed7c4c96a999bb2ef5eeced7588da5d3845d2b7d Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Jul 6 14:07:45 2017 +0200 i#61225 sw: fix layout loop with growable single-column sections Commit 6ade80cf142664e78954c7544534e9436ceb90c7 (tdf#108524 sw: allow move of frame inside section without columns, 2017-06-16) relaxed lcl_IsInSectionDirectly() used in SwFrame::IsMoveable() to allow move for all section frame contents if it has a single column. That looked safe, as the multiple column case was already allowed. There is one situation where this still causes a problem: when the section has a single column and the section frame is growable -- as in that case we should grow the section frame, not move the contents. So go back to unconditionally allowing multi-column section contents and allow single-column section contents only in case the section frame is now growable. With this, ooo61225-1.sxw from the crashtesting corpus can be opened again without a layout loop. Reviewed-on: https://gerrit.libreoffice.org/39653 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit 972fbddf80510f7daaf2128dbfda01c0e7535020) Conflicts: sw/qa/extras/odfimport/odfimport.cxx Change-Id: Ib2d3702a33da8e62b9bbf468d558ae16db8aa94b diff --git a/sw/qa/extras/odfimport/data/i61225.sxw b/sw/qa/extras/odfimport/data/i61225.sxw new file mode 100644 index 000000000000..4f43541995c3 Binary files /dev/null and b/sw/qa/extras/odfimport/data/i61225.sxw differ diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx index 065cf787aaa8..a72d6a54c546 100644 --- a/sw/qa/extras/odfimport/odfimport.cxx +++ b/sw/qa/extras/odfimport/odfimport.cxx @@ -637,5 +637,13 @@ DECLARE_ODFIMPORT_TEST(testTdf96113, "tdf96113.odt") CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00ff00), getProperty<sal_Int32>(getShape(1), "BackColor")); } +DECLARE_ODFIMPORT_TEST(testI61225, "i61225.sxw") +{ + // Part of ooo61225-1.sxw from crashtesting. + + // This never returned. + calcLayout(); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index fb5854a80c9c..3ad50a012d13 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -1257,10 +1257,15 @@ void SwFrame::InvalidateNextPrtArea() /// but not if it sits in a table which itself sits in a section. static bool lcl_IsInSectionDirectly( const SwFrame *pUp ) { + bool bSeenColumn = false; + while( pUp ) { - if( pUp->IsSctFrame() ) - return true; + if( pUp->IsColumnFrame() ) + bSeenColumn = true; + else if( pUp->IsSctFrame() ) + // Allow move of frame in case our only column is not growable. + return bSeenColumn || !static_cast<const SwSectionFrame*>(pUp)->Growable(); else if( pUp->IsTabFrame() ) return false; pUp = pUp->GetUpper(); commit ba4c9af309e97338f4e2929d6dba12c92c1a4bfc Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Jul 6 11:16:54 2017 +0200 tdf#108524 sw: split section frames inside table cells, non-split text frames Commit f991b842addddeada6dc45c4054deeca5aa7f17b (tdf#108524 sw: attempt to split section frames inside table cells, 2017-06-19) added initial support for multi-page sections inside a table cell, but turns out this only worked in case at the split point there was a long enough paragraph, so it was split into two (a "master" text frame and a "follow" one), and then the follow was moved to the next page by SwContentFrame::MakeAll(), with the MoveFwd() call in the "If a Follow sits next to its Master and doesn't fit, we know it can be moved right now." block. However, if the section contains lots of one-liner text frames, then all of them are masters, so the above code doesn't move them to the next page; so the section frame is still not split. Fix the problem by allowing the move of frames inside table-in-sections in SwSectionFrame::MoveAllowed(), that way SwTextFrame::AdjustFrame() will not set the text frame as undersized, so at the end SwContentFrame::MakeAll() will call MoveFwd() in the "If a column section can't find any space for its first ContentFrame" block. With this the split of text frames in section-in-table frames is consistent regardless if they are of multiple or single lines. Change-Id: Ief9d62da3fd8a5c707e1f9489a92f7a81e7b38ac Reviewed-on: https://gerrit.libreoffice.org/39623 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit f8a76d218305a56d15b82b9dac4fafa558872780) diff --git a/sw/qa/extras/uiwriter/data/lines-in-section-in-table.odt b/sw/qa/extras/uiwriter/data/lines-in-section-in-table.odt new file mode 100644 index 000000000000..4f0abd6e5e88 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/lines-in-section-in-table.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 47011654e117..f646347a4b30 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -202,6 +202,7 @@ public: void testParagraphOfTextRange(); void testTdf108524(); void testTableInSection(); + void testLinesInSectionInTable(); CPPUNIT_TEST_SUITE(SwUiWriterTest); CPPUNIT_TEST(testReplaceForward); @@ -307,6 +308,7 @@ public: CPPUNIT_TEST(testTdf108524); CPPUNIT_TEST(testTdf108524); CPPUNIT_TEST(testTableInSection); + CPPUNIT_TEST(testLinesInSectionInTable); CPPUNIT_TEST_SUITE_END(); private: @@ -3745,6 +3747,22 @@ void SwUiWriterTest::testTdf108524() assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell/section", 1); } +void SwUiWriterTest::testLinesInSectionInTable() +{ + // This is similar to testTdf108524(), but the page boundary now is not in + // the middle of a multi-line paragraph: the section only contains oneliner + // paragraphs instead. + createDoc("lines-in-section-in-table.odt"); + xmlDocPtr pXmlDoc = parseLayoutDump(); + // In total we expect two cells containing a section. + assertXPath(pXmlDoc, "/root/page/body/tab/row/cell/section", 2); + + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/section", 1); + // This was 0, section wasn't split, instead it was only on the first page + // and it was cut off. + assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell/section", 1); +} + void SwUiWriterTest::testTableInSection() { // The document has a section, containing a table that spans over 2 pages. diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 69dba7ed0438..5a11d6bfed66 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -590,7 +590,7 @@ namespace } /// Checks if pFrame is in a table, which itself is in a section. - bool IsInTableInSection(SwFrame* pFrame) + bool IsInTableInSection(const SwFrame* pFrame) { if (!pFrame->IsInTab()) return false; @@ -2161,8 +2161,8 @@ bool SwSectionFrame::MoveAllowed( const SwFrame* pFrame) const return false; // Now it has to be examined whether there is a layout sheet wherein // a section Follow can be created - if( IsInTab() || ( !IsInDocBody() && FindFooterOrHeader() ) ) - return false; // It doesn't work in tables/headers/footers + if( IsInTableInSection(this) || ( !IsInDocBody() && FindFooterOrHeader() ) ) + return false; // It doesn't work in table-in-sections/headers/footers if( IsInFly() ) // In column based or chained frames return nullptr != const_cast<SwFrame*>(static_cast<SwFrame const *>(GetUpper()))->GetNextLeaf( MAKEPAGE_NONE ); return true; commit 1bfa44ffaded1694722f4d91abd7d7c30d9bce26 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Mon Jul 3 13:53:28 2017 +0200 tdf#108524 sw: attempt to split section frames inside table cells, take two Tables-in-sections were already split across multiple pages, but not secions-in-tables. To be safe still don't allow sections-in-tables-in-sections, so you can combine these in both orders now, but not recursively. To achieve this, relax two "not in table" conditions to just require "not in a table that is already in a section", and define that in case a section-in-table is to be split, the follow section frame should be inserted under the follow of its cell. With this, finally the section frame in the bugdoc is split into two, and the second section frame is moved to the second page as expected. This restores commit f991b842addddeada6dc45c4054deeca5aa7f17b, but this second take makes sure that we do not crash while laying out ooo61225-1.sxw. GetNextSctLeaf() used to assume that SwTableFrame::Split() created the follow cell frames; and when that wasn't the case, it crashed. Still don't attempt to create the cell frame in GetNextSctLeaf(), but handle when the cell follow frame is missing, and return early, as it used to be the case before this commit. Reviewed-on: https://gerrit.libreoffice.org/39471 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit b5e0a143308e976b4165ff6181f4dccc3db0bd31) Conflicts: sw/qa/extras/uiwriter/uiwriter.cxx Change-Id: I9dcc76b4c61b39b9d23b140b84420e89cf274cf3 diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index a027a80b5f44..47011654e117 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -200,9 +200,7 @@ public: void testTdf84695(); void testTdf84695NormalChar(); void testParagraphOfTextRange(); -#if 0 void testTdf108524(); -#endif void testTableInSection(); CPPUNIT_TEST_SUITE(SwUiWriterTest); @@ -307,9 +305,7 @@ public: CPPUNIT_TEST(testTdf84695NormalChar); CPPUNIT_TEST(testParagraphOfTextRange); CPPUNIT_TEST(testTdf108524); -#if 0 CPPUNIT_TEST(testTdf108524); -#endif CPPUNIT_TEST(testTableInSection); CPPUNIT_TEST_SUITE_END(); @@ -3736,7 +3732,6 @@ void SwUiWriterTest::testParagraphOfTextRange() CPPUNIT_ASSERT_EQUAL(OUString("In section"), xParagraph->getString()); } -#if 0 void SwUiWriterTest::testTdf108524() { createDoc("tdf108524.odt"); @@ -3749,7 +3744,6 @@ void SwUiWriterTest::testTdf108524() // and it was cut off. assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell/section", 1); } -#endif void SwUiWriterTest::testTableInSection() { diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 86dac9e92664..69dba7ed0438 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -22,6 +22,7 @@ #include <fmtftn.hxx> #include <fmtclbl.hxx> #include "sectfrm.hxx" +#include "cellfrm.hxx" #include "section.hxx" #include <IDocumentSettingAccess.hxx> #include "rootfrm.hxx" @@ -587,6 +588,16 @@ namespace return pLayFrame->GetNextLayoutLeaf(); return pLayFrame; } + + /// Checks if pFrame is in a table, which itself is in a section. + bool IsInTableInSection(SwFrame* pFrame) + { + if (!pFrame->IsInTab()) + return false; + + // The frame is in a table, see if the table is in a section. + return pFrame->FindTabFrame()->IsInSct(); + } } void SwSectionFrame::MoveContentAndDelete( SwSectionFrame* pDel, bool bSave ) @@ -1439,9 +1450,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetNext())->Lower()); if( GetUpper()->IsColBodyFrame() && GetUpper()->GetUpper()->GetNext() ) return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetUpper()->GetNext())->Lower()); - // Inside a section, in tables, or sections of headers/footers, there can be only + // Inside a table-in-section, or sections of headers/footers, there can be only // one column shift be made, one of the above shortcuts should have applied! - if( GetUpper()->IsInTab() || FindFooterOrHeader() ) + if( IsInTableInSection(GetUpper()) || FindFooterOrHeader() ) return nullptr; SwSectionFrame *pSect = FindSctFrame(); @@ -1498,7 +1509,23 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) const bool bBody = IsInDocBody(); const bool bFootnotePage = FindPageFrame()->IsFootnotePage(); + // The "pLayLeaf is in a table" case is rejected by default, so that it + // can't happen that we try to move a table to one of its own cells. + bool bLayLeafTableAllowed = false; SwLayoutFrame *pLayLeaf; + + SwLayoutFrame* pCellLeaf = nullptr; + if (IsInTab()) + { + // We are in a table, see if there is a follow cell frame created already. + pCellLeaf = GetNextCellLeaf(MAKEPAGE_NONE); + if (!pCellLeaf) + { + SAL_WARN("sw.layout", "section is in table, but the table is not split"); + return nullptr; + } + } + // A shortcut for TabFrames such that not all cells need to be visited if( bWrongPage ) pLayLeaf = nullptr; @@ -1507,6 +1534,16 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) SwContentFrame* pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContent(); pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr; } + else if (pCellLeaf && !IsInTableInSection(this)) + { + // This frame is in a table-not-in-section, its follow should be + // inserted under the follow of the frame's cell. + pLayLeaf = pCellLeaf; + if (pLayLeaf->FindTabFrame() == FindTabFrame()) + SAL_WARN("sw.layout", "my table frame and my follow's table frame is the same"); + // In this case pLayLeaf pointing to an in-table frame is OK. + bLayLeafTableAllowed = true; + } else { pLayLeaf = GetNextLayoutLeaf(); @@ -1534,10 +1571,10 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) pLayLeaf = nullptr; continue; } - // Once inBody always inBody, don't step into tables and not into other sections + // Once inBody always inBody, don't step into tables-in-sections and not into other sections if ( (bBody && !pLayLeaf->IsInDocBody()) || (IsInFootnote() != pLayLeaf->IsInFootnote() ) || - pLayLeaf->IsInTab() || + (pLayLeaf->IsInTab() && !bLayLeafTableAllowed) || ( pLayLeaf->IsInSct() && ( !pSect->HasFollow() || pSect->GetFollow() != pLayLeaf->FindSctFrame() ) ) ) { commit 369dd545ddb19f1995d3c1792f2f937a3300dddc Author: Stephan Bergmann <sberg...@redhat.com> Date: Mon Jun 26 17:31:36 2017 +0200 Avoid loplugin:unreffun ...after 272d5a02a3de2350f8af7a93281b651316b24ae5 "Revert 'tdf#108524 sw: attempt to split section frames inside table cells'" (cherry picked from commit 12ca907139c05ded23cb22aab2e03a52645adfa0) Conflicts: sw/qa/extras/uiwriter/uiwriter.cxx Change-Id: Ic1ec8cd3284e2ba98630552c80d99b5d67fc7efd diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index e2001dc3ef81..a027a80b5f44 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -200,7 +200,9 @@ public: void testTdf84695(); void testTdf84695NormalChar(); void testParagraphOfTextRange(); +#if 0 void testTdf108524(); +#endif void testTableInSection(); CPPUNIT_TEST_SUITE(SwUiWriterTest); @@ -305,7 +307,9 @@ public: CPPUNIT_TEST(testTdf84695NormalChar); CPPUNIT_TEST(testParagraphOfTextRange); CPPUNIT_TEST(testTdf108524); -// CPPUNIT_TEST(testTdf108524); +#if 0 + CPPUNIT_TEST(testTdf108524); +#endif CPPUNIT_TEST(testTableInSection); CPPUNIT_TEST_SUITE_END(); @@ -3732,6 +3736,7 @@ void SwUiWriterTest::testParagraphOfTextRange() CPPUNIT_ASSERT_EQUAL(OUString("In section"), xParagraph->getString()); } +#if 0 void SwUiWriterTest::testTdf108524() { createDoc("tdf108524.odt"); @@ -3744,6 +3749,7 @@ void SwUiWriterTest::testTdf108524() // and it was cut off. assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell/section", 1); } +#endif void SwUiWriterTest::testTableInSection() { commit 5a70acd99f557d84bb5b3766d749b52b1774b9ff Author: Michael Stahl <mst...@redhat.com> Date: Mon Jun 26 15:01:36 2017 +0200 Revert "tdf#108524 sw: attempt to split section frames inside table cells" This reverts commit f991b842addddeada6dc45c4054deeca5aa7f17b. It doesn't really work and crashes on ooo61225-1.sxw in 1 in SwFrame::FindTabFrame() (this=0x0) at sw/source/core/inc/frame.hxx:913 2 in SwFrame::GetNextSctLeaf(MakePageType) (this=0x3137130, eMakePage=MAKEPAGE_INSERT) at sw/source/core/layout/sectfrm.cxx:1529 3 in SwFrame::GetLeaf(MakePageType, bool) (this=0x3137130, eMakePage=MAKEPAGE_INSERT, bFwd=true) at sw/source/core/layout/flowfrm.cxx:805 4 in SwFlowFrame::MoveFwd(bool, bool, bool) (this=0x31371d8, bMakePage=true, bPageBreak=false, bMoveAlways=false) at sw/source/core/layout/flowfrm.cxx:1861 The code added in GetNextSctLeaf() looks unfinished to me: it assumes that something else has added a follow-frame for the SwCellFrame containing the SwSectionFrame already, but AFAICT the GetNextSctLeaf() function is responsible for creating that SwCellFrame follow. The caller (in GetLeaf()) specifically checks for this condition and avoids calling GetNextCellLeaf(). (cherry picked from commit 272d5a02a3de2350f8af7a93281b651316b24ae5) Conflicts: sw/qa/extras/uiwriter/uiwriter.cxx Change-Id: I51875830771f07f5d2fec293f6063c73fc68d468 diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 7cd2dd41c39b..e2001dc3ef81 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -305,6 +305,7 @@ public: CPPUNIT_TEST(testTdf84695NormalChar); CPPUNIT_TEST(testParagraphOfTextRange); CPPUNIT_TEST(testTdf108524); +// CPPUNIT_TEST(testTdf108524); CPPUNIT_TEST(testTableInSection); CPPUNIT_TEST_SUITE_END(); diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 37bc0c08f09c..df85c55ae326 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -42,7 +42,6 @@ class SwFootnoteFrame; class SwFootnoteBossFrame; class SwTabFrame; class SwRowFrame; -class SwCellFrame; class SwFlowFrame; class SwContentFrame; class SfxPoolItem; @@ -228,7 +227,6 @@ class SW_DLLPUBLIC SwFrame: public SwClient, public SfxBroadcaster const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const; SwPageFrame* ImplFindPageFrame(); - SwCellFrame* ImplFindCellFrame(); protected: SwSortedObjs* mpDrawObjs; // draw objects, can be 0 @@ -772,12 +770,6 @@ public: virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const; void dumpChildrenAsXml(xmlTextWriterPtr writer) const; bool IsCollapse() const; - - /// Find the nearest table cell frame that contains us, if any. - SwCellFrame* FindCellFrame() - { - return IsInTab() ? ImplFindCellFrame() : nullptr; - } }; inline bool SwFrame::IsInDocBody() const diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index d0981628b2eb..fb5854a80c9c 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -459,18 +459,6 @@ SwTabFrame* SwFrame::ImplFindTabFrame() return static_cast<SwTabFrame*>(pRet); } -SwCellFrame* SwFrame::ImplFindCellFrame() -{ - SwFrame *pRet = this; - while (!pRet->IsCellFrame()) - { - pRet = pRet->GetUpper(); - if (!pRet) - return nullptr; - } - return static_cast<SwCellFrame*>(pRet); -} - SwSectionFrame* SwFrame::ImplFindSctFrame() { SwFrame *pRet = this; diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index f23a93c3ebd3..86dac9e92664 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -22,7 +22,6 @@ #include <fmtftn.hxx> #include <fmtclbl.hxx> #include "sectfrm.hxx" -#include "cellfrm.hxx" #include "section.hxx" #include <IDocumentSettingAccess.hxx> #include "rootfrm.hxx" @@ -588,16 +587,6 @@ namespace return pLayFrame->GetNextLayoutLeaf(); return pLayFrame; } - - /// Checks if pFrame is in a table, which itself is in a section. - bool IsInTableInSection(SwFrame* pFrame) - { - if (!pFrame->IsInTab()) - return false; - - // The frame is in a table, see if the table is in a section. - return pFrame->FindTabFrame()->IsInSct(); - } } void SwSectionFrame::MoveContentAndDelete( SwSectionFrame* pDel, bool bSave ) @@ -1450,9 +1439,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetNext())->Lower()); if( GetUpper()->IsColBodyFrame() && GetUpper()->GetUpper()->GetNext() ) return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetUpper()->GetNext())->Lower()); - // Inside a table-in-section, or sections of headers/footers, there can be only + // Inside a section, in tables, or sections of headers/footers, there can be only // one column shift be made, one of the above shortcuts should have applied! - if( IsInTableInSection(GetUpper()) || FindFooterOrHeader() ) + if( GetUpper()->IsInTab() || FindFooterOrHeader() ) return nullptr; SwSectionFrame *pSect = FindSctFrame(); @@ -1509,9 +1498,6 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) const bool bBody = IsInDocBody(); const bool bFootnotePage = FindPageFrame()->IsFootnotePage(); - // The "pLayLeaf is in a table" case is rejected by default, so that it - // can't happen that we try to move a table to one of its own cells. - bool bLayLeafTableAllowed = false; SwLayoutFrame *pLayLeaf; // A shortcut for TabFrames such that not all cells need to be visited if( bWrongPage ) @@ -1521,16 +1507,6 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) SwContentFrame* pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContent(); pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr; } - else if (IsInTab() && !IsInTableInSection(this)) - { - // This frame is in a table-not-in-section, its follow should be - // inserted under the follow of the frame's cell. - pLayLeaf = FindCellFrame()->GetFollowCell(); - if (pLayLeaf->FindTabFrame() == FindTabFrame()) - SAL_WARN("sw.layout", "my table frame and my follow's table frame is the same"); - // In this case pLayLeaf pointing to an in-table frame is OK. - bLayLeafTableAllowed = true; - } else { pLayLeaf = GetNextLayoutLeaf(); @@ -1558,10 +1534,10 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) pLayLeaf = nullptr; continue; } - // Once inBody always inBody, don't step into tables-in-sections and not into other sections + // Once inBody always inBody, don't step into tables and not into other sections if ( (bBody && !pLayLeaf->IsInDocBody()) || (IsInFootnote() != pLayLeaf->IsInFootnote() ) || - (pLayLeaf->IsInTab() && !bLayLeafTableAllowed) || + pLayLeaf->IsInTab() || ( pLayLeaf->IsInSct() && ( !pSect->HasFollow() || pSect->GetFollow() != pLayLeaf->FindSctFrame() ) ) ) { commit 85590ae2389aa81ebaec360b03134a2758ae02e6 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Jun 20 09:21:10 2017 +0200 tdf#108524 sw: add split section in table testcase And if we're at it, test the other way around as well, I almost broke it. Reviewed-on: https://gerrit.libreoffice.org/38999 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit e9d2016648c7fdfc57932ac0793547cf099749be) Conflicts: sw/qa/extras/uiwriter/uiwriter.cxx Change-Id: Ia81e46f218336e5db13dafdbad7b896d8dadaf46 diff --git a/sw/qa/extras/uiwriter/data/table-in-sect.odt b/sw/qa/extras/uiwriter/data/table-in-sect.odt new file mode 100644 index 000000000000..f439edef997e Binary files /dev/null and b/sw/qa/extras/uiwriter/data/table-in-sect.odt differ diff --git a/sw/qa/extras/uiwriter/data/tdf108524.odt b/sw/qa/extras/uiwriter/data/tdf108524.odt new file mode 100644 index 000000000000..d8978b269cab Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf108524.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 0e37981b4b58..7cd2dd41c39b 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -200,6 +200,8 @@ public: void testTdf84695(); void testTdf84695NormalChar(); void testParagraphOfTextRange(); + void testTdf108524(); + void testTableInSection(); CPPUNIT_TEST_SUITE(SwUiWriterTest); CPPUNIT_TEST(testReplaceForward); @@ -302,6 +304,8 @@ public: CPPUNIT_TEST(testTdf84695); CPPUNIT_TEST(testTdf84695NormalChar); CPPUNIT_TEST(testParagraphOfTextRange); + CPPUNIT_TEST(testTdf108524); + CPPUNIT_TEST(testTableInSection); CPPUNIT_TEST_SUITE_END(); private: @@ -3727,6 +3731,32 @@ void SwUiWriterTest::testParagraphOfTextRange() CPPUNIT_ASSERT_EQUAL(OUString("In section"), xParagraph->getString()); } +void SwUiWriterTest::testTdf108524() +{ + createDoc("tdf108524.odt"); + xmlDocPtr pXmlDoc = parseLayoutDump(); + // In total we expect two cells containing a section. + assertXPath(pXmlDoc, "/root/page/body/tab/row/cell/section", 2); + + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/section", 1); + // This was 0, section wasn't split, instead it was only on the first page + // and it was cut off. + assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell/section", 1); +} + +void SwUiWriterTest::testTableInSection() +{ + // The document has a section, containing a table that spans over 2 pages. + createDoc("table-in-sect.odt"); + xmlDocPtr pXmlDoc = parseLayoutDump(); + // In total we expect 4 cells. + assertXPath(pXmlDoc, "/root/page/body/section/tab/row/cell", 4); + + // Assert that on both pages the section contains 2 cells. + assertXPath(pXmlDoc, "/root/page[1]/body/section/tab/row/cell", 2); + assertXPath(pXmlDoc, "/root/page[2]/body/section/tab/row/cell", 2); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest); CPPUNIT_PLUGIN_IMPLEMENT(); commit 3d0240c93a2edf27eff849e622a1cd2a8020198c Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Mon Jun 19 15:24:12 2017 +0200 tdf#108524 sw: attempt to split section frames inside table cells Tables-in-sections were already split across multiple pages, but not secions-in-tables. To be safe still don't allow sections-in-tables-in-sections, so you can combine these in both orders now, but not recursively. To achieve this, relax two "not in table" conditions to just require "not in a table that is already in a section", and define that in case a section-in-table is to be split, the follow section frame should be inserted under the follow of its cell. With this, finally the section frame in the bugdoc is split into two, and the second section frame is moved to the second page as expected. Change-Id: I16ebb2d30870b145a2378d46603324ab267b0dd3 Reviewed-on: https://gerrit.libreoffice.org/38965 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit f991b842addddeada6dc45c4054deeca5aa7f17b) diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index df85c55ae326..37bc0c08f09c 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -42,6 +42,7 @@ class SwFootnoteFrame; class SwFootnoteBossFrame; class SwTabFrame; class SwRowFrame; +class SwCellFrame; class SwFlowFrame; class SwContentFrame; class SfxPoolItem; @@ -227,6 +228,7 @@ class SW_DLLPUBLIC SwFrame: public SwClient, public SfxBroadcaster const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const; SwPageFrame* ImplFindPageFrame(); + SwCellFrame* ImplFindCellFrame(); protected: SwSortedObjs* mpDrawObjs; // draw objects, can be 0 @@ -770,6 +772,12 @@ public: virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const; void dumpChildrenAsXml(xmlTextWriterPtr writer) const; bool IsCollapse() const; + + /// Find the nearest table cell frame that contains us, if any. + SwCellFrame* FindCellFrame() + { + return IsInTab() ? ImplFindCellFrame() : nullptr; + } }; inline bool SwFrame::IsInDocBody() const diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index fb5854a80c9c..d0981628b2eb 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -459,6 +459,18 @@ SwTabFrame* SwFrame::ImplFindTabFrame() return static_cast<SwTabFrame*>(pRet); } +SwCellFrame* SwFrame::ImplFindCellFrame() +{ + SwFrame *pRet = this; + while (!pRet->IsCellFrame()) + { + pRet = pRet->GetUpper(); + if (!pRet) + return nullptr; + } + return static_cast<SwCellFrame*>(pRet); +} + SwSectionFrame* SwFrame::ImplFindSctFrame() { SwFrame *pRet = this; diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 86dac9e92664..f23a93c3ebd3 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -22,6 +22,7 @@ #include <fmtftn.hxx> #include <fmtclbl.hxx> #include "sectfrm.hxx" +#include "cellfrm.hxx" #include "section.hxx" #include <IDocumentSettingAccess.hxx> #include "rootfrm.hxx" @@ -587,6 +588,16 @@ namespace return pLayFrame->GetNextLayoutLeaf(); return pLayFrame; } + + /// Checks if pFrame is in a table, which itself is in a section. + bool IsInTableInSection(SwFrame* pFrame) + { + if (!pFrame->IsInTab()) + return false; + + // The frame is in a table, see if the table is in a section. + return pFrame->FindTabFrame()->IsInSct(); + } } void SwSectionFrame::MoveContentAndDelete( SwSectionFrame* pDel, bool bSave ) @@ -1439,9 +1450,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetNext())->Lower()); if( GetUpper()->IsColBodyFrame() && GetUpper()->GetUpper()->GetNext() ) return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetUpper()->GetNext())->Lower()); - // Inside a section, in tables, or sections of headers/footers, there can be only + // Inside a table-in-section, or sections of headers/footers, there can be only // one column shift be made, one of the above shortcuts should have applied! - if( GetUpper()->IsInTab() || FindFooterOrHeader() ) + if( IsInTableInSection(GetUpper()) || FindFooterOrHeader() ) return nullptr; SwSectionFrame *pSect = FindSctFrame(); @@ -1498,6 +1509,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) const bool bBody = IsInDocBody(); const bool bFootnotePage = FindPageFrame()->IsFootnotePage(); + // The "pLayLeaf is in a table" case is rejected by default, so that it + // can't happen that we try to move a table to one of its own cells. + bool bLayLeafTableAllowed = false; SwLayoutFrame *pLayLeaf; // A shortcut for TabFrames such that not all cells need to be visited if( bWrongPage ) @@ -1507,6 +1521,16 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) SwContentFrame* pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContent(); pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr; } + else if (IsInTab() && !IsInTableInSection(this)) + { + // This frame is in a table-not-in-section, its follow should be + // inserted under the follow of the frame's cell. + pLayLeaf = FindCellFrame()->GetFollowCell(); + if (pLayLeaf->FindTabFrame() == FindTabFrame()) + SAL_WARN("sw.layout", "my table frame and my follow's table frame is the same"); + // In this case pLayLeaf pointing to an in-table frame is OK. + bLayLeafTableAllowed = true; + } else { pLayLeaf = GetNextLayoutLeaf(); @@ -1534,10 +1558,10 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) pLayLeaf = nullptr; continue; } - // Once inBody always inBody, don't step into tables and not into other sections + // Once inBody always inBody, don't step into tables-in-sections and not into other sections if ( (bBody && !pLayLeaf->IsInDocBody()) || (IsInFootnote() != pLayLeaf->IsInFootnote() ) || - pLayLeaf->IsInTab() || + (pLayLeaf->IsInTab() && !bLayLeafTableAllowed) || ( pLayLeaf->IsInSct() && ( !pSect->HasFollow() || pSect->GetFollow() != pLayLeaf->FindSctFrame() ) ) ) { commit a679189743f3a2d1a15a4dad3557d6fa8975ef0e Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Jun 16 08:35:05 2017 +0200 tdf#108524 sw: allow move of frame inside section without columns The intention here is to deny the move of a frame that's inside a table inside a section. But the code also checked if there a column frame in-between, so it allowed the move for a frame in a section with 2 cols, but not without columns (which does not sound intentional, since that's a simpler case). So drop the requirement to have a column frame between the argument and the section frame, just check that there is no table frame in between. This is needed, but not enough to split the section in the bugdoc (but at least now the content of the section is marked as movable). Change-Id: I9155b291a19c692efc30f01f8e206fac5f1ccf81 Reviewed-on: https://gerrit.libreoffice.org/38858 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> (cherry picked from commit 6ade80cf142664e78954c7544534e9436ceb90c7) diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index 89cf31663e2c..fb5854a80c9c 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -1253,17 +1253,14 @@ void SwFrame::InvalidateNextPrtArea() } } -/// @returns true if the frame _directly_ sits in a section with columns -/// but not if it sits in a table which itself sits in a section with columns. -static bool lcl_IsInColSct( const SwFrame *pUp ) +/// @returns true if the frame _directly_ sits in a section +/// but not if it sits in a table which itself sits in a section. +static bool lcl_IsInSectionDirectly( const SwFrame *pUp ) { - bool bRet = false; while( pUp ) { - if( pUp->IsColumnFrame() ) - bRet = true; - else if( pUp->IsSctFrame() ) - return bRet; + if( pUp->IsSctFrame() ) + return true; else if( pUp->IsTabFrame() ) return false; pUp = pUp->GetUpper(); @@ -1290,7 +1287,7 @@ bool SwFrame::IsMoveable( const SwLayoutFrame* _pLayoutFrame ) const if ( _pLayoutFrame && IsFlowFrame() ) { - if ( _pLayoutFrame->IsInSct() && lcl_IsInColSct( _pLayoutFrame ) ) + if ( _pLayoutFrame->IsInSct() && lcl_IsInSectionDirectly( _pLayoutFrame ) ) { bRetVal = true; } commit 17824b7c49d87062a0ffeaebcb194b604936f126 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Jun 15 12:18:31 2017 +0200 tdf#108524 sw: try to split rows that contain 1-col sections We used to not even attempt to split a row that contains sections. Relax this condition and try to split the row in case the table itself is not in a section (to avoid recursion) and the section has no columns. This is needed, but not enough to split the section in the bugdoc. Change-Id: I6ad0d6eb18611f108ae29e4feea7101ffe552c48 Reviewed-on: https://gerrit.libreoffice.org/38824 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> (cherry picked from commit 336ec28195da1917c22494a24dbaf10b846d3141) diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index 2230a4920e14..45282d886929 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -906,7 +906,22 @@ static bool lcl_FindSectionsInRow( const SwRowFrame& rRow ) else { // #i26945# - search only for sections - bRet = pTmpFrame->IsSctFrame(); + if (pTmpFrame->IsSctFrame()) + { + bRet = true; + + if (!rRow.IsInSct()) + { + // This row is not in a section. + if (const SwFrame* pSectionLower = pTmpFrame->GetLower()) + { + if (!pSectionLower->IsColumnFrame()) + // Section has a single column only, try to + // split that. + bRet = false; + } + } + } } if ( bRet ) commit 871c9e19ef5c2286e1de9321c736541d3f93ceac Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Jun 15 11:08:48 2017 +0200 Related: tdf#108524 sw: dump follow/precede of cell frames in layout xml dump These point to the other cell frame on the previous/next page (in case the cell frame is split across multiple pages). Change-Id: Ic03cf9a194a49320d84dbdb5176fa737e5d6520d Reviewed-on: https://gerrit.libreoffice.org/38818 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit 835c1586f60e6bc03e045e8210e38876e0fe1abc) diff --git a/sw/source/core/inc/cellfrm.hxx b/sw/source/core/inc/cellfrm.hxx index 8ddc89ffd404..ba2ae774519d 100644 --- a/sw/source/core/inc/cellfrm.hxx +++ b/sw/source/core/inc/cellfrm.hxx @@ -60,6 +60,7 @@ public: const SwCellFrame& FindStartEndOfRowSpanCell( bool bStart ) const; long GetLayoutRowSpan() const; + void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override; DECL_FIXEDMEMPOOL_NEWDEL(SwCellFrame) }; diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index 138fa1a2ff95..2230a4920e14 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -5028,6 +5028,16 @@ long SwCellFrame::GetLayoutRowSpan() const return nRet; } +void SwCellFrame::dumpAsXmlAttributes(xmlTextWriterPtr pWriter) const +{ + SwFrame::dumpAsXmlAttributes(pWriter); + if (SwCellFrame* pFollow = GetFollowCell()) + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("follow"), "%" SAL_PRIuUINT32, pFollow->GetFrameId()); + + if (SwCellFrame* pPrevious = GetPreviousCell()) + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("precede"), "%" SAL_PRIuUINT32, pPrevious->GetFrameId()); +} + // #i103961# void SwCellFrame::Cut() { commit f8f9c0f50c99ec554584014a10e30b69d50b0fc8 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Jul 27 13:59:01 2017 +0200 sw: add new TextParagraph property to XTextRange A text range represents a selection or cursor position, so similar to sections or tables, it makes sense to expose the containing paragraph as well. This new property does exactly that. Reviewed-on: https://gerrit.libreoffice.org/40483 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> (cherry picked from commit 7ed402ba648dd0f3de3b0dadebc13403b2c0a620) Conflicts: sw/qa/extras/uiwriter/uiwriter.cxx Change-Id: If92a3b5e61f13c7c14ca52bc8593a2b286a596cc diff --git a/offapi/com/sun/star/text/TextRangeContentProperties.idl b/offapi/com/sun/star/text/TextRangeContentProperties.idl index 042b4d5b3736..9daad2e139dc 100644 --- a/offapi/com/sun/star/text/TextRangeContentProperties.idl +++ b/offapi/com/sun/star/text/TextRangeContentProperties.idl @@ -81,6 +81,12 @@ service TextRangeContentProperties [optional, readonly, property] com::sun::star::text::XTextContent NestedTextContent; + /** Paragraph for the start of this range. + + @since LibreOffice 6.0 + */ + [optional, readonly, property] com::sun::star::text::XTextContent TextParagraph; + }; diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index 09cd1f48513c..6f1ec12ee124 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -544,6 +544,7 @@ #define FN_UNO_FOOTER (FN_EXTRA2 + 38) #define FN_UNO_FOOTER_LEFT (FN_EXTRA2 + 39) #define FN_UNO_FOOTER_RIGHT (FN_EXTRA2 + 40) +#define FN_UNO_TEXT_PARAGRAPH (FN_EXTRA2 + 41) #define FN_UNO_FOLLOW_STYLE (FN_EXTRA2 + 59) #define FN_API_CALL (FN_EXTRA2 + 60) diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 63589f273ce5..1c1371222bc6 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -384,6 +384,7 @@ #define UNO_NAME_FOOTER_BODY_DISTANCE "FooterBodyDistance" #define UNO_NAME_FOOTER_IS_DYNAMIC_HEIGHT "FooterIsDynamicHeight" #define UNO_NAME_FOOTER_IS_SHARED "FooterIsShared" +#define UNO_NAME_TEXT_PARAGRAPH "TextParagraph" #define UNO_NAME_FOOTER_HEIGHT "FooterHeight" #define UNO_NAME_FOOTER_IS_ON "FooterIsOn" diff --git a/sw/qa/extras/uiwriter/data/paragraph-of-text-range.odt b/sw/qa/extras/uiwriter/data/paragraph-of-text-range.odt new file mode 100644 index 000000000000..52cdb0be1ff2 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/paragraph-of-text-range.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 57d53fc8f4d0..0e37981b4b58 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -199,6 +199,7 @@ public: void testTdf99004(); void testTdf84695(); void testTdf84695NormalChar(); + void testParagraphOfTextRange(); CPPUNIT_TEST_SUITE(SwUiWriterTest); CPPUNIT_TEST(testReplaceForward); @@ -300,6 +301,7 @@ public: CPPUNIT_TEST(testTdf99004); CPPUNIT_TEST(testTdf84695); CPPUNIT_TEST(testTdf84695NormalChar); + CPPUNIT_TEST(testParagraphOfTextRange); CPPUNIT_TEST_SUITE_END(); private: @@ -3704,6 +3706,27 @@ void SwUiWriterTest::testTdf84695NormalChar() CPPUNIT_ASSERT_EQUAL(OUString("a"), xShape->getString()); } +void SwUiWriterTest::testParagraphOfTextRange() +{ + SwDoc* pDoc = createDoc("paragraph-of-text-range.odt"); + + // Enter the table. + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->Down(/*bSelect=*/false); + CPPUNIT_ASSERT(pWrtShell->IsCursorInTable()); + // Enter the section. + pWrtShell->Down(/*bSelect=*/false); + CPPUNIT_ASSERT(pWrtShell->IsDirectlyInSection()); + + // Assert that we get the right paragraph object. + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextViewCursorSupplier> xController(xModel->getCurrentController(), uno::UNO_QUERY); + uno::Reference<text::XTextRange> xViewCursor(xController->getViewCursor(), uno::UNO_QUERY); + // This failed as there were no TextParagraph property. + auto xParagraph = getProperty< uno::Reference<text::XTextRange> >(xViewCursor->getStart(), "TextParagraph"); + CPPUNIT_ASSERT_EQUAL(OUString("In section"), xParagraph->getString()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx index 22b41fed67fc..83646a892b97 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -85,6 +85,7 @@ #include <SwNodeNum.hxx> #include <fmtmeta.hxx> #include <txtfld.hxx> +#include <unoparagraph.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -592,6 +593,18 @@ bool getCursorPropertyValue(const SfxItemPropertySimpleEntry& rEntry eNewState = PropertyState_DEFAULT_VALUE; } break; + case FN_UNO_TEXT_PARAGRAPH: + { + SwTextNode* pTextNode = rPam.GetPoint()->nNode.GetNode().GetTextNode(); + if (pTextNode) + { + uno::Reference<text::XTextContent> xParagraph = SwXParagraph::CreateXParagraph(*pTextNode->GetDoc(), pTextNode); + *pAny <<= xParagraph; + } + else + eNewState = PropertyState_DEFAULT_VALUE; + } + break; case FN_UNO_ENDNOTE: case FN_UNO_FOOTNOTE: { diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx index 1f528f0ba596..8580ba0c8805 100644 --- a/sw/source/core/unocore/unomapproperties.hxx +++ b/sw/source/core/unocore/unomapproperties.hxx @@ -87,6 +87,7 @@ { OUString(UNO_NAME_CELL), FN_UNO_CELL, cppu::UnoType<css::table::XCell>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \ { OUString(UNO_NAME_TEXT_FRAME), FN_UNO_TEXT_FRAME, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \ { OUString(UNO_NAME_TEXT_SECTION), FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \ + { OUString(UNO_NAME_TEXT_PARAGRAPH), FN_UNO_TEXT_PARAGRAPH, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \ { OUString(UNO_NAME_PARA_CHAPTER_NUMBERING_LEVEL), FN_UNO_PARA_CHAPTER_NUMBERING_LEVEL,cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, 0}, \ { OUString(UNO_NAME_PARA_CONDITIONAL_STYLE_NAME), FN_UNO_PARA_CONDITIONAL_STYLE_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0}, \ { OUString(UNO_NAME_LIST_ID), FN_UNO_LIST_ID, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0}, \ commit 98525094d44ceff0794cfb36c5494a7bd50c26a0 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Wed Jul 26 15:50:09 2017 +0200 gbuild: strip away unexpected CR char at the end of Windows filenames As reported at e.g. <https://ask.libreoffice.org/en/question/90346/building-libreoffice-in-cygwin-leads-to-infinite-loop/>, sometimes MSVC (seen with 2013 on libreoffice-5-2, but there is no indication that 2015 on master would be different) emits CR characters at the end of filenames, resulting in unnecessary rebuilds at per-module builds, and actually to an infinite loop when doing toplevel make. Given that CR characters are unexpected in any filenames, it should be safe to just strip those away unconditionally. Change-Id: I3d56670b4d930a32489f889085711bfd436de82a Reviewed-on: https://gerrit.libreoffice.org/40452 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> (cherry picked from commit e9b9a456221b4b0660f90efa1ee092ea00c2c728) diff --git a/solenv/gbuild/platform/filter-showIncludes.awk b/solenv/gbuild/platform/filter-showIncludes.awk index 21a458521308..05a9a2c8d5ec 100755 --- a/solenv/gbuild/platform/filter-showIncludes.awk +++ b/solenv/gbuild/platform/filter-showIncludes.awk @@ -44,6 +44,13 @@ BEGIN { if (index($0, showincludes_prefix) == 1) { $0 = substr($0, length(showincludes_prefix) + 1) sub(/^ */, "") + + # The output from MSVC may contain a carriage return character at the + # end of filenames, in which case the translation unit will depend on a + # non-existing header, resulting in constant rebuild of all files, + # prevent that. + sub(/ /, "") + gsub(/\\/, "/") gsub(/ /, "\\ ") if ($0 ~ whitelist) { # filter out system headers commit 31d4bf625f88e2fc9b2057ad7bb7bd943d1c7871 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Mon Jun 6 12:34:08 2016 +0200 SwXDispatchProviderInterceptor: implement frame::XInterceptorInfo With this, framework::InterceptionHelper can make a better decision what interceptor to call: it can avoid calling SwXDispatchProviderInterceptor when the sw code would just call the previous interceptor anyway. Change-Id: I92897f2c8baa264dc9ccbc11b63f415da30a910d Reviewed-on: https://gerrit.libreoffice.org/25961 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> (cherry picked from commit b0d819ac5667a07f629f2acb5d3c542fa76d348b) diff --git a/sw/source/uibase/inc/unodispatch.hxx b/sw/source/uibase/inc/unodispatch.hxx index b115f7e49744..f5408d724fc4 100644 --- a/sw/source/uibase/inc/unodispatch.hxx +++ b/sw/source/uibase/inc/unodispatch.hxx @@ -24,6 +24,7 @@ #include <com/sun/star/view/XSelectionChangeListener.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XInterceptorInfo.hpp> #include <cppuhelper/implbase.hxx> #include <list> #include <vcl/svapp.hxx> @@ -35,7 +36,8 @@ class SwXDispatchProviderInterceptor : public cppu::WeakImplHelper < css::frame::XDispatchProviderInterceptor, css::lang::XEventListener, - css::lang::XUnoTunnel + css::lang::XUnoTunnel, + css::frame::XInterceptorInfo > { class DispatchMutexLock_Impl @@ -83,6 +85,9 @@ public: static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId(); virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) throw(css::uno::RuntimeException, std::exception) override; + // XInterceptorInfo + virtual css::uno::Sequence<OUString> SAL_CALL getInterceptedURLs() throw (css::uno::RuntimeException, std::exception) override; + // view destroyed void Invalidate(); }; diff --git a/sw/source/uibase/uno/unodispatch.cxx b/sw/source/uibase/uno/unodispatch.cxx index 985f28387e2b..3335eebc4dfd 100644 --- a/sw/source/uibase/uno/unodispatch.cxx +++ b/sw/source/uibase/uno/unodispatch.cxx @@ -88,6 +88,16 @@ uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch return xResult; } +uno::Sequence<OUString> SAL_CALL SwXDispatchProviderInterceptor::getInterceptedURLs() throw (uno::RuntimeException, std::exception) +{ + uno::Sequence<OUString> aRet = + { + OUString(".uno:DataSourceBrowser/*") + }; + + return aRet; +} + uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches( const uno::Sequence< frame::DispatchDescriptor >& aDescripts ) throw(uno::RuntimeException, std::exception) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits