1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-07-01 14:15:24 +02:00

spellchecker: fix codec segfault

Fix the segfault happening when a codec is not properly loaded by
only activated spellcheck when a dictionnary has been successfully
loaded, initializing a default codec and adding error handling.

GitLab: #2063

Change-Id: I48339ce6d13120cfbae3c6c7eb6f40e87f16f084
This commit is contained in:
pmagnier-slimani 2025-06-13 15:12:46 -04:00 committed by François-Simon Fauteux-Chapleau
parent e76bcbd555
commit b15d692a0e
5 changed files with 29 additions and 10 deletions

View file

@ -113,9 +113,7 @@ JamiFlickable {
}
}
readonly property bool spellCheckEnabled:
AppSettingsManager.getValue(Settings.EnableSpellCheck) &&
AppSettingsManager.getValue(Settings.SpellLang) !== ""
property bool spellCheckEnabled: AppSettingsManager.getValue(Settings.EnableSpellCheck) && AppSettingsManager.getValue(Settings.SpellLang) !== ""
// Spell check is active under the following conditions:
// 1. Spell check is enabled in settings
@ -192,7 +190,7 @@ JamiFlickable {
onReleased: function (event) {
if (event.button === Qt.RightButton) {
if (spellCheckActive) {
if (spellCheckActive && SpellCheckAdapter.hasLoadedDictionary) {
var position = textArea.positionAt(event.x, event.y);
textArea.moveCursorSelection(position, TextInput.SelectWords);
textArea.selectWord();
@ -254,7 +252,7 @@ JamiFlickable {
function updateSpellCorrection() {
clearUnderlines();
// We iterate over the whole text to find words to check and underline them if needed
if (spellCheckActive) {
if (spellCheckActive && SpellCheckAdapter.hasLoadedDictionary) {
var text = textArea.text;
var words = SpellCheckAdapter.findWords(text);
if (!words)

View file

@ -134,6 +134,9 @@ SpellCheckAdapter::setDictionary(const QString& locale)
auto localPath = dictionaryListModel_->pathForLocale(locale);
if (spellChecker_.replaceDictionary(localPath)) {
settingsManager_->setValue(Settings::Key::SpellLang, locale);
set_hasLoadedDictionary(true);
Q_EMIT dictionaryChanged();
} else {
qWarning() << "Failed to set dictionary for locale:" << locale;
}
}

View file

@ -33,6 +33,7 @@ class SpellCheckAdapter final : public QObject
QML_SINGLETON
QML_RO_PROPERTY(int, installedDictionaryCount)
QML_RO_PROPERTY(bool, hasLoadedDictionary)
public:
static SpellCheckAdapter* create(QQmlEngine* engine, QJSEngine*)

View file

@ -31,7 +31,10 @@
SpellChecker::SpellChecker()
: hunspell_(new Hunspell("", ""))
{}
{
// Initialize with default UTF-8 codec
codec_ = QTextCodec::codecForName("UTF-8");
}
bool
SpellChecker::spell(const QString& word)
@ -75,11 +78,26 @@ SpellChecker::replaceDictionary(const QString& dictionaryPath)
QString dictFile = dictionaryPath + ".dic";
QString affixFile = dictionaryPath + ".aff";
// Check if dictionary files exist
if (!QFile::exists(dictFile) || !QFile::exists(affixFile)) {
qWarning() << "Dictionary files not found:" << dictFile << affixFile;
return false;
}
QByteArray dictFilePath = dictFile.toLocal8Bit();
QByteArray affixFilePath = affixFile.toLocal8Bit();
hunspell_.reset(new Hunspell(affixFilePath.constData(), dictFilePath.constData()));
encoding_ =hunspell_->get_dic_encoding();
codec_ = QTextCodec::codecForName(this->encoding_.toLatin1().constData());
std::unique_ptr<Hunspell> hunspell(
new Hunspell(affixFilePath.constData(), dictFilePath.constData()));
auto encoding = hunspell->get_dic_encoding();
auto codec = QTextCodec::codecForName(encoding);
if (!codec) {
return false;
}
hunspell_ = std::move(hunspell);
codec_ = codec;
currentDictionaryPath_ = dictionaryPath;
return true;
}

View file

@ -57,6 +57,5 @@ private:
std::unique_ptr<Hunspell> hunspell_;
QString currentDictionaryPath_;
QString encoding_;
QTextCodec* codec_;
};