sw/qa/extras/uiwriter/uiwriter3.cxx | 91 ++++++++++++++++++++++++++++++++++++ sw/source/core/frmedt/fecopy.cxx | 14 +++-- 2 files changed, 100 insertions(+), 5 deletions(-)
New commits: commit f0254aaea7d4a6a261731f76c99cb06f1b5ab2b1 Author: László Németh <nem...@numbertext.org> AuthorDate: Fri Apr 22 20:34:32 2022 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Tue Apr 26 09:25:25 2022 +0200 tdf#141391 sw: don't paste as nested table in first cell paragraph Paste table content overwrote cells of the row(s) only if the text cursor was at the beginning of the table cell, otherwise the table cells on the clipboard were inserted as a nested table. This was a UX regression from commit 7600a2942ce2b9dac66836105bed6620d55abec2 "fdo#37156 insert table copy as nested table in non-starting cell position" especially when the user clicked not exactly at the beginning of a cell, which containing a 1-line text or data. Since commit 1e278d1d0cfb1d5375195aa764739f00633f21e8 "tdf#37156 Writer menu: Paste as Nested table" it's possible to force nesting (but not overwriting yet), this commit revert partially commit 7600a2942ce2b9dac66836105bed6620d55abec2: if the text cursor is there in the first paragraph of the cell, Paste table content overwrites the row, not embedding a nested table in the cell at the cursor position. This change results also better interoperability with the existing document editors. Note: table and text selection were checked with the change, too. Details: Heuristics to allow copying table rows or nesting tables without using Edit -> Paste Special -> Paste as Nested Table: At "table selection" (i.e. when cell(s) completely selected), or if the text selection starts in the first paragraph, or if there is no selection and the text cursor is there in the first paragraph, overwrite content of the cell(s). Otherwise insert a nested table, i.e. if nothing selected and the cursor is not in the first paragraph, or the selected text doesn't contain the first paragraph of the cell. Change-Id: I7746c6a464123bef6fb7dbff415ff0414e48365d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133377 Tested-by: Jenkins Reviewed-by: László Németh <nem...@numbertext.org> (cherry picked from commit b97116791047f89b768ab4aa8126e543df826be3) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133402 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx index 03b2bc92b307..26ca4e8db96f 100644 --- a/sw/qa/extras/uiwriter/uiwriter3.cxx +++ b/sw/qa/extras/uiwriter/uiwriter3.cxx @@ -2176,6 +2176,97 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf148345) assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf141391) +{ + // table insertion in the first paragraph of the cell + // overwrites the row content, instead of inserting a nested table + + // load a 2-row table + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); + CPPUNIT_ASSERT(pDoc); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + + // select the table, and copy it into at paragraph start of cell "A2" + + dispatchCommand(mxComponent, ".uno:SelectTable", {}); + dispatchCommand(mxComponent, ".uno:Copy", {}); + // remove the selection and positionate the cursor at beginning of A2 + pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false); + dispatchCommand(mxComponent, ".uno:Paste", {}); + Scheduler::ProcessEventsToIdle(); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // 3-row, overwriting cells of the second row and inserting a new row + // with the 2-row clipboard table content + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/Text", "Portion", "hello"); + + // Undo + + dispatchCommand(mxComponent, ".uno:Undo", {}); + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + // 2 rows again, no copied text content + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/Text", 0); + + // insert the 2-row table into the second paragraph of cell "A2" as a nested table + // For this it's enough to positionate the text cursor not in the first paragraph + + // insert some text and an empty paragraph + pWrtShell->Insert("Some text..."); + pWrtShell->SplitNode(); + Scheduler::ProcessEventsToIdle(); + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/Text", "Portion", + "Some text..."); + // the empty paragraph in A2 + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[2]/Text", 0); + + // insert the table, as a nested one in cell "A2" + dispatchCommand(mxComponent, ".uno:Paste", {}); + Scheduler::ProcessEventsToIdle(); + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab", 1); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab/row", 2); + + // Undo + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + // 2 rows again, no copied text content + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/Text", "Portion", + "Some text..."); + + // copy the 2-row table into the fist paragraph of cell "A2", + // but not at paragraph start (changed behaviour) + + pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false); + pWrtShell->Insert("and some text again in the first paragraph to be sure..."); + dispatchCommand(mxComponent, ".uno:Paste", {}); + Scheduler::ProcessEventsToIdle(); + + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + + // 3-row, overwriting cells of the second row and inserting a new row + // with the 2-row clipboard table content + + // This was 2 (nested table) + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3); + // This was "Some text..." with a nested table + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/Text", "Portion", "hello"); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf135014) { createSwDoc(); diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx index 7a57c5f4e709..b7a12a828b90 100644 --- a/sw/source/core/frmedt/fecopy.cxx +++ b/sw/source/core/frmedt/fecopy.cxx @@ -966,11 +966,15 @@ bool SwFEShell::Paste(SwDoc& rClpDoc, bool bNestedTable) if (pSrcNd && nullptr != pDestNd && // not a forced nested table insertion !bNestedTable && - // are we at the beginning of the cell? (if not, we will insert a nested table) - // first paragraph of the cell? - rPaM.GetNode().GetIndex() == rPaM.GetNode().FindTableBoxStartNode()->GetIndex()+1 && - // beginning of the paragraph? - !rPaM.GetPoint()->nContent.GetIndex()) + // Heuristics to allow copying table rows or nesting tables without + // using Edit -> Paste Special -> Paste as Nested Table: + // Using table cursor, or if the text selection starts in the + // first paragraph, or if there is no selection and the text cursor + // is there in the first paragraph, overwrite content of the cell(s) + // (else insert a nested table later, i.e. if nothing selected and + // the cursor is not in the first paragraph, or the selected text + // doesn't contain the first paragraph of the cell) + rPaM.GetNode().GetIndex() == rPaM.GetNode().FindTableBoxStartNode()->GetIndex() + 1) { SwPosition aDestPos( *rPaM.GetPoint() );