diff --git a/FAQ.md b/FAQ.md
index ce79384b83..1424e4f023 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -4843,6 +4843,8 @@ Templates can have the following options:
**(180) How do I use LanguageTool?**
+LanguageTool need to be enabled in the miscellaneous settings.
+
After writing some text, you can long press on the save draft button to perform a grammar, style, and spell check via [LanguageTool](https://languagetool.org/).
Texts with suggestions will be marked and if you tap on a marked suggestion,
it will be shown by the keyboard if the keyboard supports this,
diff --git a/app/src/main/java/eu/faircode/email/ApplicationEx.java b/app/src/main/java/eu/faircode/email/ApplicationEx.java
index 1894b4afbe..0459d798e3 100644
--- a/app/src/main/java/eu/faircode/email/ApplicationEx.java
+++ b/app/src/main/java/eu/faircode/email/ApplicationEx.java
@@ -636,6 +636,8 @@ public class ApplicationEx extends Application
editor.putBoolean("auto_identity", true);
} else if (version < 1931)
editor.remove("button_force_light").remove("fake_dark");
+ else if (version < 1933)
+ editor.putBoolean("lt_enabled", true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !BuildConfig.DEBUG)
editor.remove("background_service");
diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java
index 00f592413d..6739271f93 100644
--- a/app/src/main/java/eu/faircode/email/FragmentCompose.java
+++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java
@@ -1871,9 +1871,12 @@ public class FragmentCompose extends FragmentBase {
bottom_navigation.findViewById(R.id.action_save).setOnLongClickListener(new View.OnLongClickListener() {
@Override
- public boolean onLongClick(View view) {
- onLanguageTool();
- return true;
+ public boolean onLongClick(View v) {
+ if (LanguageTool.isEnabled(v.getContext())) {
+ onLanguageTool();
+ return true;
+ } else
+ return false;
}
});
diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java
index 6d8eeba482..410158fb94 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java
@@ -37,6 +37,7 @@ import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.fonts.Font;
import android.graphics.fonts.SystemFonts;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
@@ -111,6 +112,9 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private TextView tvFtsIndexed;
private TextView tvFtsPro;
private Spinner spLanguage;
+ private SwitchCompat swLanguageTool;
+ private TextView tvLanguageToolPrivacy;
+ private ImageButton ibLanguageTool;
private SwitchCompat swDeepL;
private ImageButton ibDeepL;
private TextView tvSdcard;
@@ -212,7 +216,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private final static String[] RESET_OPTIONS = new String[]{
"sort_answers", "shortcuts", "fts",
"classification", "class_min_probability", "class_min_difference",
- "language", "deepl_enabled",
+ "language", "lt_enabled", "deepl_enabled",
"updates", "weekly", "show_changelog",
"crash_reports", "cleanup_attachments",
"watchdog", "experiments", "main_log", "protocol", "log_level", "debug", "leak_canary", "test1",
@@ -293,6 +297,9 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
tvFtsIndexed = view.findViewById(R.id.tvFtsIndexed);
tvFtsPro = view.findViewById(R.id.tvFtsPro);
spLanguage = view.findViewById(R.id.spLanguage);
+ swLanguageTool = view.findViewById(R.id.swLanguageTool);
+ tvLanguageToolPrivacy = view.findViewById(R.id.tvLanguageToolPrivacy);
+ ibLanguageTool = view.findViewById(R.id.ibLanguageTool);
swDeepL = view.findViewById(R.id.swDeepL);
ibDeepL = view.findViewById(R.id.ibDeepL);
tvSdcard = view.findViewById(R.id.tvSdcard);
@@ -579,6 +586,28 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
}
});
+ swLanguageTool.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ prefs.edit().putBoolean("lt_enabled", checked).apply();
+ }
+ });
+
+ tvLanguageToolPrivacy.getPaint().setUnderlineText(true);
+ tvLanguageToolPrivacy.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Helper.view(v.getContext(), Uri.parse(Helper.LT_PRIVACY_URI), true);
+ }
+ });
+
+ ibLanguageTool.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Helper.viewFAQ(v.getContext(), 180);
+ }
+ });
+
swDeepL.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
@@ -1750,6 +1779,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
if (selected >= 0)
spLanguage.setSelection(selected);
+ swLanguageTool.setChecked(prefs.getBoolean("lt_enabled", false));
swDeepL.setChecked(prefs.getBoolean("deepl_enabled", false));
swUpdates.setChecked(prefs.getBoolean("updates", true));
swCheckWeekly.setChecked(prefs.getBoolean("weekly", Helper.hasPlayStore(getContext())));
diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java
index e349c4d73b..0132b87e27 100644
--- a/app/src/main/java/eu/faircode/email/Helper.java
+++ b/app/src/main/java/eu/faircode/email/Helper.java
@@ -193,6 +193,7 @@ public class Helper {
static final String SUPPORT_URI = "https://contact.faircode.eu/";
static final String TEST_URI = "https://play.google.com/apps/testing/" + BuildConfig.APPLICATION_ID;
static final String BIMI_PRIVACY_URI = "https://datatracker.ietf.org/doc/html/draft-brotman-ietf-bimi-guidance-03#section-7.4";
+ static final String LT_PRIVACY_URI = "https://languagetool.org/legal/privacy";
static final String ID_COMMAND_URI = "https://datatracker.ietf.org/doc/html/rfc2971#section-3.1";
static final String AUTH_RESULTS_URI = "https://datatracker.ietf.org/doc/html/rfc7601";
static final String FAVICON_PRIVACY_URI = "https://en.wikipedia.org/wiki/Favicon";
diff --git a/app/src/main/java/eu/faircode/email/LanguageTool.java b/app/src/main/java/eu/faircode/email/LanguageTool.java
index a841d8b099..1c6bd8ea24 100644
--- a/app/src/main/java/eu/faircode/email/LanguageTool.java
+++ b/app/src/main/java/eu/faircode/email/LanguageTool.java
@@ -20,6 +20,9 @@ package eu.faircode.email;
*/
import android.content.Context;
+import android.content.SharedPreferences;
+
+import androidx.preference.PreferenceManager;
import org.json.JSONArray;
import org.json.JSONException;
@@ -41,6 +44,11 @@ public class LanguageTool {
private static final String LT_URI = "https://api.languagetool.org/v2/";
private static final int LT_TIMEOUT = 20; // seconds
+ static boolean isEnabled(Context context) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ return prefs.getBoolean("lt_enabled", false);
+ }
+
static List getSuggestions(Context context, CharSequence text) throws IOException, JSONException {
// https://languagetool.org/http-api/swagger-ui/#!/default/post_check
String request =
diff --git a/app/src/main/res/layout/fragment_options_misc.xml b/app/src/main/res/layout/fragment_options_misc.xml
index 760c8a6720..46efc0342e 100644
--- a/app/src/main/res/layout/fragment_options_misc.xml
+++ b/app/src/main/res/layout/fragment_options_misc.xml
@@ -306,6 +306,54 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spLanguage" />
+
+
+
+
+
+
+
+
Minimum class difference: %1$s %%
Language
System
+ LanguageTool integration
DeepL integration
I want to use an sdcard
Periodically check if FairEmail is still active