[Libreoffice-commits] core.git: sw/qa sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Tue Dec 11 19:15:51 UTC 2018
sw/qa/extras/unowriter/unowriter.cxx | 38 +++++++++++++++++++++++++++++++++++
sw/source/core/unocore/unoobj2.cxx | 30 +++++++++++++++++++++++++++
2 files changed, 68 insertions(+)
New commits:
commit 42dffe7b135c0680a8e20e4170a5f1176afc908e
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Dec 11 16:42:54 2018 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Dec 11 20:15:30 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.
Change-Id: I51432dee9e5d76971533c8059edab1cd9683434b
Reviewed-on: https://gerrit.libreoffice.org/64972
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
Tested-by: Jenkins
diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index 4bff617f62ef..8cba987a7c63 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -380,6 +380,44 @@ DECLARE_UNOAPI_TEST_FILE(testSelectionInTableEnum, "selection-in-table-enum.odt"
CPPUNIT_ASSERT(!xEnum->hasMoreElements());
}
+DECLARE_UNOAPI_TEST_FILE(testSelectionInTableEnumEnd, "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_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index 98a6b079a69c..788d4508feb0 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -513,6 +513,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(
@@ -566,6 +572,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()
{
@@ -588,11 +611,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
{
@@ -602,6 +627,11 @@ SwXParagraphEnumerationImpl::NextElement_Impl()
{
return nullptr;
}
+
+ if (IgnoreLastElement(*aNewCursor, bMovedFromTable))
+ {
+ return nullptr;
+ }
}
bool bInTable = false;
More information about the Libreoffice-commits
mailing list