summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/uitest/writer_tests4/spellDialog.py36
-rw-r--r--sw/source/core/txtnode/txtedt.cxx59
2 files changed, 87 insertions, 8 deletions
diff --git a/sw/qa/uitest/writer_tests4/spellDialog.py b/sw/qa/uitest/writer_tests4/spellDialog.py
index d4b19132c90c..183a85843ab9 100644
--- a/sw/qa/uitest/writer_tests4/spellDialog.py
+++ b/sw/qa/uitest/writer_tests4/spellDialog.py
@@ -169,4 +169,40 @@ frog, dogg, catt"""
# This was "Baaed HTTP://www.baaad.org baaad baaad" (spelling URLs)
self.assertEqual("Baaed http://www.baaad.org baaed baaad", output_text)
+ def test_tdf45949(self):
+ supported_locale = self.is_supported_locale("en", "US")
+ if not supported_locale:
+ self.skipTest("no dictionary support for en_US available")
+
+ with self.ui_test.create_doc_in_start_center("writer") as document:
+ cursor = document.getCurrentController().getViewCursor()
+ # Inserted text must be en_US, so make sure to set language in current location
+ cursor.CharLocale = Locale("en", "US", "")
+
+ xMainWindow = self.xUITest.getTopFocusWindow()
+ xEdit = xMainWindow.getChild("writer_edit")
+
+ # URL is recognized during typing
+ type_text(xEdit, "baaad http://www.baaad.org baaad")
+
+ # add spaces before and after the word "baaad" within the URL
+ cursor.goLeft(10, False)
+ type_text(xEdit, " ")
+ cursor.goLeft(6, False)
+ type_text(xEdit, " ")
+
+ with self.ui_test.execute_modeless_dialog_through_command(".uno:SpellingAndGrammarDialog", close_button="close") as xDialog:
+ checkgrammar = xDialog.getChild('checkgrammar')
+ if get_state_as_dict(checkgrammar)['Selected'] == 'true':
+ checkgrammar.executeAction('CLICK', ())
+ self.assertTrue(get_state_as_dict(checkgrammar)['Selected'] == 'false')
+
+ change = xDialog.getChild('change')
+ change.executeAction("CLICK", ())
+ change.executeAction("CLICK", ())
+
+ output_text = document.Text.getString()
+ # This was "Baaed HTTP://www. baaad .org baaed" (skipped non-URL words of hypertext)
+ self.assertEqual("Baaed http://www. baaed .org baaad", output_text)
+
# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index b0e0b0d4b6a6..59950ce9e06f 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -112,6 +112,54 @@ static bool lcl_HasComments(const SwTextNode& rNode)
return false;
}
+// possible delimiter characters within URLs for word breaking
+static bool lcl_IsDelim( const sal_Unicode c )
+{
+ return '#' == c || '$' == c || '%' == c || '&' == c || '+' == c ||
+ ',' == c || '-' == c || '.' == c || '/' == c || ':' == c ||
+ ';' == c || '=' == c || '?' == c || '@' == c || '_' == c;
+}
+
+// allow to check normal text with hyperlink by recognizing (parts of) URLs
+static bool lcl_IsURL(std::u16string_view rWord,
+ SwTextNode &rNode, sal_Int32 nBegin, sal_Int32 nLen)
+{
+ // not a text with hyperlink
+ if ( !rNode.GetTextAttrAt(nBegin, RES_TXTATR_INETFMT) )
+ return false;
+
+ // there is a dot in the word, wich is not a period ("example.org")
+ const size_t nPosAt = rWord.find('.');
+ if (nPosAt != std::u16string_view::npos && nPosAt < rWord.length() - 1)
+ return true;
+
+ // an e-mail address ("user@example")
+ if ( rWord.find('@') != std::u16string_view::npos )
+ return true;
+
+ const OUString& rText = rNode.GetText();
+
+ // scheme (e.g. "http" in "http://" or "mailto" in "mailto:address"):
+ // word is followed by 1) ':' + an alphanumeric character; 2) or ':' + a delimiter
+ if ( nBegin + nLen + 2 <= rText.getLength() && ':' == rText[nBegin + nLen] )
+ {
+ sal_Unicode c = rText[nBegin + nLen + 1];
+ if ( u_isalnum(c) || lcl_IsDelim(c) )
+ return true;
+ }
+
+ // path, query, fragment (e.g. "path" in "example.org/path"):
+ // word is preceded by 1) an alphanumeric character + a delimiter; 2) or two delimiters
+ if ( 2 <= nBegin && lcl_IsDelim(rText[nBegin - 1]) )
+ {
+ sal_Unicode c = rText[nBegin - 2];
+ if ( u_isalnum(c) || lcl_IsDelim(c) )
+ return true;
+ }
+
+ return false;
+}
+
/*
* This has basically the same function as SwScriptInfo::MaskHiddenRanges,
* only for deleted redlines
@@ -992,15 +1040,13 @@ bool SwTextNode::Spell(SwSpellArgs* pArgs)
{
const OUString& rWord = aScanner.GetWord();
- // skip URLs
- bool bHyperlink = GetTextAttrAt(aScanner.GetBegin(), RES_TXTATR_INETFMT) ? true: false;
-
// get next language for next word, consider language attributes
// within the word
LanguageType eActLang = aScanner.GetCurrentLanguage();
DetectAndMarkMissingDictionaries( GetTextNode()->GetDoc(), pArgs->xSpeller, eActLang );
- if( rWord.getLength() > 0 && LANGUAGE_NONE != eActLang && !bHyperlink )
+ if( rWord.getLength() > 0 && LANGUAGE_NONE != eActLang &&
+ !lcl_IsURL(rWord, *this, aScanner.GetBegin(), aScanner.GetLen() ) )
{
if (pArgs->xSpeller.is())
{
@@ -1304,11 +1350,8 @@ SwRect SwTextFrame::AutoSpell_(SwTextNode & rNode, sal_Int32 nActPos)
LanguageType eActLang = aScanner.GetCurrentLanguage();
DetectAndMarkMissingDictionaries( rDoc, xSpell, eActLang );
- // skip URLs
- bool bHyperlink = pNode->GetTextAttrAt(nBegin, RES_TXTATR_INETFMT) ? true: false;
-
bool bSpell = xSpell.is() && xSpell->hasLanguage( static_cast<sal_uInt16>(eActLang) );
- if( bSpell && !rWord.isEmpty() && !bHyperlink )
+ if( bSpell && !rWord.isEmpty() && !lcl_IsURL(rWord, *pNode, nBegin, nLen) )
{
// check for: bAlter => xHyphWord.is()
OSL_ENSURE(!bSpell || xSpell.is(), "NULL pointer");