[Libreoffice-commits] core.git: Branch 'distro/vector/vector-5.4' - sw/qa sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Dec 12 08:31:18 UTC 2018


 sw/qa/extras/unowriter/unowriter.cxx |   42 +++++++++++++++++++++++++++++++++++
 sw/source/core/unocore/unoobj2.cxx   |   30 +++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

New commits:
commit e619f76c21fdf1840797820b3e82a25300f12f1d
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Dec 11 16:42:54 2018 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Dec 12 09:24:39 2018 +0100

    sw: fix paragraph enumeration going past a selected table
    
    Writer has the internal invariant that if a text (non-table) selection
    starts outside a table, it should end outside a table as well.  This
    means if you start your selection before a table and you try to select
    till the end of the table, your selection will end at the start of the
    next non-table node in fact.
    
    This is especially confusing if you turn the selection into a paragraph
    enumeration, where the last paragraph's 0 -> 0 character range is
    "selected" (i.e. none of the paragraph content is selected) and still
    the paragraph is included in the paragraph enumeration.
    
    Special-case the "selection ending at para start after a table"
    situation when it comes to turning this selection into a paragraph
    enumeration to avoid the unexpected empty paragraph at the end.
    
    Reviewed-on: https://gerrit.libreoffice.org/64972
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 42dffe7b135c0680a8e20e4170a5f1176afc908e)
    
    Conflicts:
            sw/qa/extras/unowriter/unowriter.cxx
    
    Change-Id: I51432dee9e5d76971533c8059edab1cd9683434b

diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index de5cba1cd13d..f76dad1c5b71 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -27,10 +27,12 @@ class SwUnoWriter : public SwModelTestBase
 public:
     void testDefaultCharStyle();
     void testSelectionInTableEnum();
+    void testSelectionInTableEnumEnd();
 
     CPPUNIT_TEST_SUITE(SwUnoWriter);
     CPPUNIT_TEST(testDefaultCharStyle);
     CPPUNIT_TEST(testSelectionInTableEnum);
+    CPPUNIT_TEST(testSelectionInTableEnumEnd);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -95,6 +97,46 @@ void SwUnoWriter::testSelectionInTableEnum()
     CPPUNIT_ASSERT(!xEnum->hasMoreElements());
 }
 
+void SwUnoWriter::testSelectionInTableEnumEnd()
+{
+    load(DATA_DIRECTORY, "selection-in-table-enum.odt");
+
+    // Select from "Before" till the table end.
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+    SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell);
+    pWrtShell->Down(/*bSelect=*/true);
+
+    // Access the selection.
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xModel.is());
+    uno::Reference<container::XIndexAccess> xSelections(xModel->getCurrentSelection(),
+                                                        uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xSelections.is());
+    uno::Reference<text::XTextRange> xSelection(xSelections->getByIndex(0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xSelection.is());
+    OUString aExpectedSelection
+        = "Before" SAL_NEWLINE_STRING "A1" SAL_NEWLINE_STRING "B1" SAL_NEWLINE_STRING
+          "C2" SAL_NEWLINE_STRING "A2" SAL_NEWLINE_STRING "B2" SAL_NEWLINE_STRING
+          "C2" SAL_NEWLINE_STRING;
+    CPPUNIT_ASSERT_EQUAL(aExpectedSelection, xSelection->getString());
+
+    // Enumerate paragraphs in the selection.
+    uno::Reference<container::XEnumerationAccess> xCursor(
+        xSelection->getText()->createTextCursorByRange(xSelection), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xCursor.is());
+    uno::Reference<container::XEnumeration> xEnum = xCursor->createEnumeration();
+    // Before.
+    xEnum->nextElement();
+    // Table.
+    xEnum->nextElement();
+    // Without the accompanying fix in place, this test would have failed: i.e.
+    // the enumeration contained the paragraph after the table, but no part of
+    // that paragraph was part of the selection.
+    CPPUNIT_ASSERT(!xEnum->hasMoreElements());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUnoWriter);
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index 7ffe23aad386..4ca338e11b63 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -511,6 +511,12 @@ struct SwXParagraphEnumerationImpl final : public SwXParagraphEnumeration
     /// @throws lang::WrappedTargetException
     /// @throws uno::RuntimeException
     uno::Reference< text::XTextContent > NextElement_Impl();
+
+    /**
+     * Determines if the last element in the enumeration should be ignored or
+     * not.
+     */
+    bool IgnoreLastElement(SwUnoCursor& rCursor, bool bMovedFromTable);
 };
 
 SwXParagraphEnumeration* SwXParagraphEnumeration::Create(
@@ -564,6 +570,23 @@ lcl_CursorIsInSection(
     return bRes;
 }
 
+bool SwXParagraphEnumerationImpl::IgnoreLastElement(SwUnoCursor& rCursor, bool bMovedFromTable)
+{
+    // Ignore the last element of a selection enumeration if this is a stub
+    // paragraph (directly after table, selection ends at paragaph start).
+
+    if (rCursor.Start()->nNode.GetIndex() != m_nEndIndex)
+        return false;
+
+    if (m_eCursorType != CursorType::Selection)
+        return false;
+
+    if (!bMovedFromTable)
+        return false;
+
+    return m_nLastParaEnd == 0;
+}
+
 uno::Reference< text::XTextContent >
 SwXParagraphEnumerationImpl::NextElement_Impl()
 {
@@ -586,11 +609,13 @@ SwXParagraphEnumerationImpl::NextElement_Impl()
         // os 2005-01-14: This part is only necessary to detect movements out
         // of a selection; if there is no selection we don't have to care
         SwTableNode *const pTableNode = aNewCursor->GetNode().FindTableNode();
+        bool bMovedFromTable = false;
         if (((CursorType::TableText != m_eCursorType) &&
             (CursorType::SelectionInTable != m_eCursorType)) && pTableNode)
         {
             aNewCursor->GetPoint()->nNode = pTableNode->EndOfSectionIndex();
             aNewCursor->Move(fnMoveForward, GoInNode);
+            bMovedFromTable = true;
         }
         else
         {
@@ -600,6 +625,11 @@ SwXParagraphEnumerationImpl::NextElement_Impl()
         {
             return nullptr;
         }
+
+        if (IgnoreLastElement(*aNewCursor, bMovedFromTable))
+        {
+            return nullptr;
+        }
     }
 
     bool bInTable = false;


More information about the Libreoffice-commits mailing list