diff --git a/autotests/test_highlighter.cpp b/autotests/test_highlighter.cpp --- a/autotests/test_highlighter.cpp +++ b/autotests/test_highlighter.cpp @@ -24,6 +24,7 @@ void testEnglish(); void testFrench(); void testMultipleLanguages(); + void testForceLanguage(); }; void HighlighterTest::initTestCase() @@ -95,6 +96,30 @@ QVERIFY2(suggestionsForDict.contains(QLatin1String("dictionnaire")), qPrintable(suggestionsForDict.join(QLatin1Char(',')))); } +void HighlighterTest::testForceLanguage() +{ + // GIVEN + QPlainTextEdit textEdit; + textEdit.setPlainText(QString::fromLatin1(s_frenchSentence)); + Sonnet::Highlighter highlighter(&textEdit); + highlighter.setCurrentLanguage(QStringLiteral("en")); + QVERIFY(highlighter.spellCheckerFound()); + QVERIFY(highlighter.autoDetectLanguageDisabled()); + highlighter.rehighlight(); + QCOMPARE(highlighter.currentLanguage(), QStringLiteral("en")); + QTextCursor cursor(textEdit.document()); + + // WHEN + cursor.setPosition(0); + const QStringList suggestionsForBnjour = highlighter.suggestionsForWord(QStringLiteral("Bnjour"), cursor); + cursor.setPosition(37); + const QStringList suggestionsForDict = highlighter.suggestionsForWord(QStringLiteral("dictionnare"), cursor); + + // THEN + QVERIFY2(!suggestionsForBnjour.contains(QLatin1String("Bonjour")), qPrintable(suggestionsForBnjour.join(QLatin1Char(',')))); + QVERIFY2(!suggestionsForDict.contains(QLatin1String("dictionnaire")), qPrintable(suggestionsForDict.join(QLatin1Char(',')))); +} + void HighlighterTest::testMultipleLanguages() { // GIVEN diff --git a/src/core/backgroundchecker.h b/src/core/backgroundchecker.h --- a/src/core/backgroundchecker.h +++ b/src/core/backgroundchecker.h @@ -72,6 +72,25 @@ */ bool addWordToSession(const QString &word); + /** + * Returns whether the automatic language detection is disabled, + * overriding the Sonnet settings. + * + * @return true if the automatic language detection is disabled + * @since 5.71 + */ + bool autoDetectLanguageDisabled() const; + + /** + * Sets whether to disable the automatic language detection. + * + * @param autoDetectDisabled if true, the language will not be + * detected automatically by the spell checker, even if the option + * is enabled in the Sonnet settings. + * @since 5.71 + */ + void setAutoDetectLanguageDisabled(bool autoDetectDisabled); + public Q_SLOTS: virtual void start(); virtual void stop(); diff --git a/src/core/backgroundchecker.cpp b/src/core/backgroundchecker.cpp --- a/src/core/backgroundchecker.cpp +++ b/src/core/backgroundchecker.cpp @@ -48,7 +48,7 @@ const bool ignoreUpperCase = !currentDict.testAttribute(Speller::CheckUppercase); while (mainTokenizer.hasNext()) { QStringRef sentence = mainTokenizer.next(); - if (autodetectLanguage) { + if (autodetectLanguage && !autoDetectLanguageDisabled) { if (!mainTokenizer.isSpellcheckable()) { continue; } @@ -119,8 +119,19 @@ { } +bool BackgroundChecker::autoDetectLanguageDisabled() const +{ + return d->autoDetectLanguageDisabled; +} + +void BackgroundChecker::setAutoDetectLanguageDisabled(bool autoDetectDisabled) +{ + d->autoDetectLanguageDisabled = autoDetectDisabled; +} + void BackgroundChecker::setSpeller(const Speller &speller) { + d->autoDetectLanguageDisabled = true; d->currentDict = speller; } @@ -152,6 +163,7 @@ void BackgroundChecker::changeLanguage(const QString &lang) { // this sets language only for current sentence + d->autoDetectLanguageDisabled = true; d->currentDict.setLanguage(lang); } diff --git a/src/core/backgroundchecker_p.h b/src/core/backgroundchecker_p.h --- a/src/core/backgroundchecker_p.h +++ b/src/core/backgroundchecker_p.h @@ -23,6 +23,7 @@ BackgroundCheckerPrivate() : mainTokenizer(new SentenceTokenizer) , sentenceOffset(-1) { + autoDetectLanguageDisabled = false; } void start(); @@ -33,6 +34,7 @@ QStringRef lastMisspelled; Speller currentDict; int sentenceOffset; + bool autoDetectLanguageDisabled; private Q_SLOTS: void checkNext(); diff --git a/src/ui/highlighter.h b/src/ui/highlighter.h --- a/src/ui/highlighter.h +++ b/src/ui/highlighter.h @@ -90,6 +90,25 @@ */ void setAutomatic(bool automatic); + /** + * Returns whether the automatic language detection is disabled, + * overriding the Sonnet settings. + * + * @return true if the automatic language detection is disabled + * @since 5.71 + */ + bool autoDetectLanguageDisabled() const; + + /** + * Sets whether to disable the automatic language detection. + * + * @param autoDetectDisabled if true, the language will not be + * detected automatically by the spell checker, even if the option + * is enabled in the Sonnet settings. + * @since 5.71 + */ + void setAutoDetectLanguageDisabled(bool autoDetectDisabled); + /** * Adds the given word permanently to the dictionary. It will never * be marked as misspelled again, even after restarting the application. diff --git a/src/ui/highlighter.cpp b/src/ui/highlighter.cpp --- a/src/ui/highlighter.cpp +++ b/src/ui/highlighter.cpp @@ -79,6 +79,7 @@ tokenizer = new WordTokenizer(); active = true; automatic = false; + autoDetectLanguageDisabled = false; connected = false; wordCount = 0; errorCount = 0; @@ -118,6 +119,7 @@ QPlainTextEdit *plainTextEdit = nullptr; bool active; bool automatic; + bool autoDetectLanguageDisabled; bool completeRehighlightRequired; bool intraWordEditing; bool spellCheckerFound; //cached d->dict->isValid() value @@ -195,6 +197,11 @@ return d->automatic; } +bool Highlighter::autoDetectLanguageDisabled() const +{ + return d->autoDetectLanguageDisabled; +} + bool Highlighter::intraWordEditing() const { return d->intraWordEditing; @@ -217,6 +224,11 @@ } } +void Highlighter::setAutoDetectLanguageDisabled(bool autoDetectDisabled) +{ + d->autoDetectLanguageDisabled = autoDetectDisabled; +} + void Highlighter::slotAutoDetection() { bool savedActive = d->active; @@ -326,7 +338,7 @@ const bool autodetectLanguage = d->spellchecker->testAttribute(Speller::AutoDetectLanguage); while (d->languageFilter->hasNext()) { QStringRef sentence = d->languageFilter->next(); - if (autodetectLanguage) { + if (autodetectLanguage && !d->autoDetectLanguageDisabled) { QString lang; QPair spos = QPair(sentence.position(), sentence.length()); // try cache first @@ -383,6 +395,7 @@ d->spellchecker->setLanguage(prevLang); return; } + d->autoDetectLanguageDisabled = true; d->wordCount = 0; d->errorCount = 0; if (d->automatic || d->active) {