tdf#66043 sw: fix spell checking of word with deletion
Correct words were underlined as spelling mistakes,
if they contained tracked deletions, related to the
unwanted CH_TXTATR_INWORD characters (result of
removing tracked deletions) at calling spell checking
API functions. Fix it by checking the "invalid"
words without CH_TXTATR_INWORD characters, too.
Change-Id: I6d8a8d619a571dfb613991cb8cf67faab57de4c0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106988
Tested-by: László Németh <[email protected]>
Reviewed-by: László Németh <[email protected]>
diff --git a/sw/qa/uitest/data/tdf66043.fodt b/sw/qa/uitest/data/tdf66043.fodt
new file mode 100644
index 0000000..5fcdde7
--- /dev/null
+++ b/sw/qa/uitest/data/tdf66043.fodt
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:officeooo="http://openoffice.org/2009/office" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text" xmlns:dc="http://purl.org/dc/elements/1.1/">
<office:styles>
<style:style style:name="Standard" style:family="paragraph" style:class="text"/>
<style:default-style style:family="paragraph">
<style:text-properties fo:language="en" fo:country="US"/>
</style:default-style>
</office:styles>
<office:body>
<office:text>
<text:tracked-changes>
<text:changed-region xml:id="ct94277392414656" text:id="ct94277392414656">
<text:deletion>
<office:change-info>
<dc:creator>Unknown Author</dc:creator>
<dc:date>2020-12-01T12:49:53</dc:date>
</office:change-info>
<text:p text:style-name="P1">o</text:p>
</text:deletion>
</text:changed-region>
<text:changed-region xml:id="ct94277392490096" text:id="ct94277392490096">
<text:deletion>
<office:change-info>
<dc:creator>Unknown Author</dc:creator>
<dc:date>2020-12-01T12:50:00</dc:date>
</office:change-info>
<text:p text:style-name="P1">a</text:p>
</text:deletion>
</text:changed-region>
</text:tracked-changes>
<text:p text:style-name="P1">goo<text:change text:change-id="ct94277392414656"/>d baa<text:change text:change-id="ct94277392490096"/>d eeend</text:p>
</office:text>
</office:body>
</office:document>
diff --git a/sw/qa/uitest/writer_tests4/spellDialog.py b/sw/qa/uitest/writer_tests4/spellDialog.py
index e678afe..3b9e4c3 100644
--- a/sw/qa/uitest/writer_tests4/spellDialog.py
+++ b/sw/qa/uitest/writer_tests4/spellDialog.py
@@ -5,6 +5,8 @@
#
import re
import org.libreoffice.unotest
import pathlib
from uitest.framework import UITestCase
from uitest.uihelper.common import get_state_as_dict
@@ -12,6 +14,9 @@
from libreoffice.linguistic.linguservice import get_spellchecker
from com.sun.star.lang import Locale
def get_url_for_data_file(file_name):
return pathlib.Path(org.libreoffice.unotest.makeCopyFromTDOC(file_name)).as_uri()
class SpellingAndGrammarDialog(UITestCase):
def is_supported_locale(self, language, country):
@@ -99,4 +104,30 @@
output_text = document.Text.getString().replace('\r\n', '\n')
self.assertTrue(re.match(self.TDF46852_REGEX, output_text))
def test_tdf66043(self):
writer_doc = self.ui_test.load_file(get_url_for_data_file("tdf66043.fodt"))
document = self.ui_test.get_component()
# Step 1: Initiate spellchecking, and make sure "Check grammar" is
# unchecked
spell_dialog = self.launch_dialog()
checkgrammar = spell_dialog.getChild('checkgrammar')
if get_state_as_dict(checkgrammar)['Selected'] == 'true':
checkgrammar.executeAction('CLICK', ())
self.assertTrue(get_state_as_dict(checkgrammar)['Selected'] == 'false')
# Step 2: Click on "Correct all" for each misspelling
# prompt until end of document is reached.
changeall = spell_dialog.getChild('changeall')
changeall.executeAction("CLICK", ())
xCloseBtn = spell_dialog.getChild("close")
xCloseBtn.executeAction("CLICK", tuple())
output_text = document.Text.getString().replace('\r\n', '\n')
# This was "gooodgood baaad eeend" ("goood" is a deletion,
# "good" is an insertion by fixing the first misspelling),
# but now "goood" is not a misspelling because it is accepted
# correctly without the redline containing a deleted "o"
self.assertTrue(output_text == 'goood baaadbaaed eeend')
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 67aae7f..edc0ac2 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1023,7 +1023,12 @@
}
if( pArgs->xSpellAlt.is() )
{
if (IsSymbolAt(aScanner.GetBegin()))
if ( IsSymbolAt(aScanner.GetBegin()) ||
// redlines can leave "in word" character within word,
// we must remove them before spell checking
// to avoid false alarm
( bRestoreString && pArgs->xSpeller->isValid( rWord.replaceAll(OUStringChar(CH_TXTATR_INWORD), ""),
static_cast<sal_uInt16>(eActLang), Sequence< PropertyValue >() ) ) )
{
pArgs->xSpellAlt = nullptr;
}
@@ -1325,8 +1330,12 @@
{
// check for: bAlter => xHyphWord.is()
OSL_ENSURE(!bSpell || xSpell.is(), "NULL pointer");
if( !xSpell->isValid( rWord, static_cast<sal_uInt16>(eActLang), Sequence< PropertyValue >() ) )
if( !xSpell->isValid( rWord, static_cast<sal_uInt16>(eActLang), Sequence< PropertyValue >() ) &&
// redlines can leave "in word" character within word,
// we must remove them before spell checking
// to avoid false alarm
(!bRestoreString || !xSpell->isValid( rWord.replaceAll(OUStringChar(CH_TXTATR_INWORD), ""),
static_cast<sal_uInt16>(eActLang), Sequence< PropertyValue >() ) ) )
{
sal_Int32 nSmartTagStt = nBegin;
sal_Int32 nDummy = 1;