1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-10-31 00:07:48 +02:00

Desktop: Add support for multi-language spell check (#6617)

This commit is contained in:
Anton Tuchkov
2022-08-27 16:05:44 +05:00
committed by GitHub
parent 8b06cbf04e
commit 0356cbbfab
8 changed files with 111 additions and 58 deletions

View File

@@ -35,23 +35,33 @@ export default class SpellCheckerService {
}
private async addLatestSelectedLanguage(language: string) {
// This function will add selected languages to the history. History size will be capped at languagesHistorySizeMax,
// but it can be bigger. Enabled languages will always be in the history, even if it count greater then
// languagesHistorySizeMax, in such case if one of the languages will be disabled it will disappear from history.
const languagesHistorySizeMax = 5;
const languages = this.latestSelectedLanguages_.slice();
if (languages.length > 5) languages.splice(0, 1);
if (languages.includes(language)) {
languages.splice(languages.indexOf(language), 1);
if (!languages.includes(language)) {
languages.push(language);
}
languages.splice(0, 0, language);
if (languages.length > languagesHistorySizeMax) {
this.latestSelectedLanguages_.forEach(l => {
if (!this.languages.includes(l) && languages.length > languagesHistorySizeMax) languages.splice(languages.indexOf(l), 1);
});
}
this.latestSelectedLanguages_ = languages;
await KvStore.instance().setValue('spellCheckerService.latestSelectedLanguages', JSON.stringify(this.latestSelectedLanguages_));
}
public setupDefaultLanguage() {
if (!Setting.value('spellChecker.language')) {
if (Setting.value('spellChecker.languages').length === 0) {
const l = this.driver_.language;
this.setLanguage(l ? l : this.defaultLanguage);
if (this.availableLanguages.includes(l)) {
this.setLanguage(l);
} else {
this.setLanguage(this.defaultLanguage);
}
}
}
@@ -60,17 +70,23 @@ export default class SpellCheckerService {
}
private applyStateToDriver() {
this.driver_.setLanguage(this.enabled ? this.language : '');
this.driver_.setLanguages(this.enabled ? this.languages : []);
}
public setLanguage(language: string) {
Setting.setValue('spellChecker.language', language);
let enabledLanguages: string[] = [...this.languages];
if (enabledLanguages.includes(language)) {
enabledLanguages = enabledLanguages.filter(obj => obj !== language);
} else {
enabledLanguages.push(language);
}
Setting.setValue('spellChecker.languages', enabledLanguages);
this.applyStateToDriver();
void this.addLatestSelectedLanguage(language);
}
public get language(): string {
return Setting.value('spellChecker.language');
public get languages(): string[] {
return Setting.value('spellChecker.languages');
}
public get enabled(): boolean {
@@ -115,7 +131,7 @@ export default class SpellCheckerService {
output.push({
label: _('Add to dictionary'),
click: () => {
void this.addToDictionary(this.language, misspelledWord);
void this.addToDictionary(this.languages[0], misspelledWord);
},
});
@@ -125,7 +141,7 @@ export default class SpellCheckerService {
private changeLanguageMenuItem(language: string, enabled: boolean, checked: boolean) {
return {
label: countryDisplayName(language),
type: 'radio',
type: 'checkbox',
checked: checked,
enabled: enabled,
click: () => {
@@ -134,11 +150,11 @@ export default class SpellCheckerService {
};
}
private changeLanguageMenuItems(selectedLanguage: string, enabled: boolean) {
private changeLanguageMenuItems(selectedLanguages: string[], enabled: boolean) {
const languageMenuItems = [];
for (const locale of this.driver_.availableLanguages) {
languageMenuItems.push(this.changeLanguageMenuItem(locale, enabled, locale === selectedLanguage));
languageMenuItems.push(this.changeLanguageMenuItem(locale, enabled, selectedLanguages.includes(locale)));
}
languageMenuItems.sort((a: any, b: any) => {
@@ -148,9 +164,9 @@ export default class SpellCheckerService {
return languageMenuItems;
}
public spellCheckerConfigMenuItems(selectedLanguage: string, useSpellChecker: boolean) {
public spellCheckerConfigMenuItems(selectedLanguages: string[], useSpellChecker: boolean) {
const latestLanguageItems = this.latestSelectedLanguages_.map((language: string) => {
return this.changeLanguageMenuItem(language, true, language === selectedLanguage);
return this.changeLanguageMenuItem(language, true, selectedLanguages.includes(language));
});
if (latestLanguageItems.length) latestLanguageItems.splice(0, 0, { type: 'separator' } as any);
@@ -187,15 +203,15 @@ export default class SpellCheckerService {
{
label: _('Change language'),
submenu: this.changeLanguageMenuItems(selectedLanguage, useSpellChecker),
submenu: this.changeLanguageMenuItems(selectedLanguages, useSpellChecker),
},
];
}
public spellCheckerConfigMenuItem(selectedLanguage: string, useSpellChecker: boolean) {
public spellCheckerConfigMenuItem(selectedLanguages: string[], useSpellChecker: boolean) {
return {
label: _('Spell checker'),
submenu: this.spellCheckerConfigMenuItems(selectedLanguage, useSpellChecker),
submenu: this.spellCheckerConfigMenuItems(selectedLanguages, useSpellChecker),
};
}

View File

@@ -4,7 +4,7 @@ export default class SpellCheckerServiceDriverBase {
throw new Error('Not implemented');
}
public setLanguage(_v: string) {
public setLanguages(_v: string[]) {
throw new Error('Not implemented');
}