sw/qa/extras/uiwriter/uiwriter3.cxx |   91 ++++++++++++++++++++++++++++++++++++
 sw/source/core/frmedt/fecopy.cxx    |   14 +++--
 2 files changed, 100 insertions(+), 5 deletions(-)

New commits:
commit b97116791047f89b768ab4aa8126e543df826be3
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Fri Apr 22 20:34:32 2022 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Mon Apr 25 17:43:47 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>

diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx 
b/sw/qa/extras/uiwriter/uiwriter3.cxx
index 30264306668f..ebda542bae0e 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -2535,6 +2535,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 985e9907ee92..6e28597024c9 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() );
 

Reply via email to