added a new screen, in the Settings, for deleting added words
This commit is contained in:
parent
5a43fba3d5
commit
322774ab45
30 changed files with 477 additions and 26 deletions
|
|
@ -170,8 +170,8 @@ public class DictionaryLoader {
|
||||||
logLoadingStep("Indexes dropped", language, start);
|
logLoadingStep("Indexes dropped", language, start);
|
||||||
|
|
||||||
start = System.currentTimeMillis();
|
start = System.currentTimeMillis();
|
||||||
DeleteOps.delete(sqlite, language.getId());
|
DeleteOps.delete(sqlite.getDb(), language.getId());
|
||||||
DeleteOps.delete(sqlite, new EmojiLanguage().getId());
|
DeleteOps.delete(sqlite.getDb(), new EmojiLanguage().getId());
|
||||||
sendProgressMessage(language, ++progress, SettingsStore.DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME);
|
sendProgressMessage(language, ++progress, SettingsStore.DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME);
|
||||||
logLoadingStep("Storage cleared", language, start);
|
logLoadingStep("Storage cleared", language, start);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ public class WordStore {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sequence == null || sequence.length() == 0) {
|
if (sequence == null || sequence.isEmpty()) {
|
||||||
Logger.w(LOG_TAG, "Attempting to get words for an empty sequence.");
|
Logger.w(LOG_TAG, "Attempting to get words for an empty sequence.");
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
@ -91,6 +91,11 @@ public class WordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NonNull public ArrayList<String> getSimilarCustom(Language language, String wordFilter) {
|
||||||
|
return language != null && checkOrNotify() ? readOps.getCustomWords(sqlite.getDb(), language, wordFilter) : new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@NonNull public String getLanguageFileHash(Language language) {
|
@NonNull public String getLanguageFileHash(Language language) {
|
||||||
return language != null && checkOrNotify() ? readOps.getLanguageFileHash(sqlite.getDb(), language.getId()) : "";
|
return language != null && checkOrNotify() ? readOps.getLanguageFileHash(sqlite.getDb(), language.getId()) : "";
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +116,7 @@ public class WordStore {
|
||||||
sqlite.beginTransaction();
|
sqlite.beginTransaction();
|
||||||
for (int langId : languageIds) {
|
for (int langId : languageIds) {
|
||||||
if (readOps.exists(sqlite.getDb(), langId)) {
|
if (readOps.exists(sqlite.getDb(), langId)) {
|
||||||
DeleteOps.delete(sqlite, langId);
|
DeleteOps.delete(sqlite.getDb(), langId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite.finishTransaction();
|
sqlite.finishTransaction();
|
||||||
|
|
@ -124,6 +129,23 @@ public class WordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void removeCustomWord(Language language, String word) {
|
||||||
|
if (language == null || !checkOrNotify()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
sqlite.beginTransaction();
|
||||||
|
DeleteOps.deleteCustomWord(sqlite.getDb(), language.getId(), word);
|
||||||
|
sqlite.finishTransaction();
|
||||||
|
} catch (Exception e) {
|
||||||
|
sqlite.failTransaction();
|
||||||
|
Logger.e(LOG_TAG, "Failed deleting custom word: '" + word + "' for language: " + language.getId() + ". " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public int put(Language language, String word) {
|
public int put(Language language, String word) {
|
||||||
if (word == null || word.isEmpty()) {
|
if (word == null || word.isEmpty()) {
|
||||||
return AddWordDialog.CODE_BLANK_WORD;
|
return AddWordDialog.CODE_BLANK_WORD;
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,19 @@ public class WordStoreAsync {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void areThereWords(ConsumerCompat<Boolean> notification, Language language) {
|
|
||||||
new Thread(() -> notification.accept(getStore().exists(language))).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void getLastLanguageUpdateTime(ConsumerCompat<String> notification, Language language) {
|
public static void getLastLanguageUpdateTime(ConsumerCompat<String> notification, Language language) {
|
||||||
new Thread(() -> notification.accept(getStore().getLanguageFileHash(language))).start();
|
new Thread(() -> notification.accept(getStore().getLanguageFileHash(language))).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void deleteCustomWord(Runnable notification, Language language, String word) {
|
||||||
|
new Thread(() -> {
|
||||||
|
getStore().removeCustomWord(language, word);
|
||||||
|
notification.run();
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void deleteWords(Runnable notification, @NonNull ArrayList<Integer> languageIds) {
|
public static void deleteWords(Runnable notification, @NonNull ArrayList<Integer> languageIds) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
getStore().remove(languageIds);
|
getStore().remove(languageIds);
|
||||||
|
|
@ -67,4 +71,11 @@ public class WordStoreAsync {
|
||||||
getStore().getSimilar(language, sequence, filter, minWords, maxWords)))
|
getStore().getSimilar(language, sequence, filter, minWords, maxWords)))
|
||||||
).start();
|
).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void getCustomWords(ConsumerCompat<ArrayList<String>> dataHandler, Language language, String wordFilter) {
|
||||||
|
new Thread(() -> asyncHandler.post(() -> dataHandler.accept(
|
||||||
|
getStore().getSimilarCustom(language, wordFilter)))
|
||||||
|
).start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,17 @@
|
||||||
package io.github.sspanak.tt9.db.sqlite;
|
package io.github.sspanak.tt9.db.sqlite;
|
||||||
|
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
public class DeleteOps {
|
public class DeleteOps {
|
||||||
public static void delete(@NonNull SQLiteOpener sqlite, int languageId) {
|
public static void delete(@NonNull SQLiteDatabase db, int languageId) {
|
||||||
sqlite.getDb().delete(Tables.getWords(languageId), null, null);
|
db.delete(Tables.getWords(languageId), null, null);
|
||||||
sqlite.getDb().delete(Tables.getWordPositions(languageId), null, null);
|
db.delete(Tables.getWordPositions(languageId), null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteCustomWord(@NonNull SQLiteDatabase db, int languageId, String word) {
|
||||||
|
db.delete(Tables.getWords(languageId), "word = ?", new String[] { word });
|
||||||
|
db.delete(Tables.CUSTOM_WORDS, "word = ?", new String[] { word });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,13 @@ import android.database.sqlite.SQLiteStatement;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import io.github.sspanak.tt9.Logger;
|
import io.github.sspanak.tt9.Logger;
|
||||||
import io.github.sspanak.tt9.db.SlowQueryStats;
|
import io.github.sspanak.tt9.db.SlowQueryStats;
|
||||||
import io.github.sspanak.tt9.db.entities.WordList;
|
import io.github.sspanak.tt9.db.entities.WordList;
|
||||||
import io.github.sspanak.tt9.db.entities.WordPositionsStringBuilder;
|
import io.github.sspanak.tt9.db.entities.WordPositionsStringBuilder;
|
||||||
|
import io.github.sspanak.tt9.languages.EmojiLanguage;
|
||||||
import io.github.sspanak.tt9.languages.Language;
|
import io.github.sspanak.tt9.languages.Language;
|
||||||
|
|
||||||
public class ReadOps {
|
public class ReadOps {
|
||||||
|
|
@ -62,6 +65,27 @@ public class ReadOps {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ArrayList<String> getCustomWords(@NonNull SQLiteDatabase db, @NonNull Language language, @NonNull String wordFilter) {
|
||||||
|
ArrayList<String> words = new ArrayList<>();
|
||||||
|
|
||||||
|
String[] select = new String[]{"word"};
|
||||||
|
String where = "word LIKE ? AND (langId = ? OR langId = ?)";
|
||||||
|
String[] whereArgs = new String[] {
|
||||||
|
wordFilter + "%",
|
||||||
|
String.valueOf(language.getId()),
|
||||||
|
String.valueOf(new EmojiLanguage().getId())
|
||||||
|
};
|
||||||
|
|
||||||
|
try (Cursor cursor = db.query(Tables.CUSTOM_WORDS, select, where, whereArgs, null, null, "word")) {
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
words.add(cursor.getString(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return words;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all words as a ready-to-export CSV string. If the language is null or customWords is true,
|
* Gets all words as a ready-to-export CSV string. If the language is null or customWords is true,
|
||||||
* only custom words are returned.
|
* only custom words are returned.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import io.github.sspanak.tt9.preferences.screens.MainSettingsScreen;
|
||||||
import io.github.sspanak.tt9.preferences.screens.UsageStatsScreen;
|
import io.github.sspanak.tt9.preferences.screens.UsageStatsScreen;
|
||||||
import io.github.sspanak.tt9.preferences.screens.appearance.AppearanceScreen;
|
import io.github.sspanak.tt9.preferences.screens.appearance.AppearanceScreen;
|
||||||
import io.github.sspanak.tt9.preferences.screens.debug.DebugScreen;
|
import io.github.sspanak.tt9.preferences.screens.debug.DebugScreen;
|
||||||
|
import io.github.sspanak.tt9.preferences.screens.deleteWords.DeleteWordsScreen;
|
||||||
import io.github.sspanak.tt9.preferences.screens.hotkeys.HotkeysScreen;
|
import io.github.sspanak.tt9.preferences.screens.hotkeys.HotkeysScreen;
|
||||||
import io.github.sspanak.tt9.preferences.screens.keypad.KeyPadScreen;
|
import io.github.sspanak.tt9.preferences.screens.keypad.KeyPadScreen;
|
||||||
import io.github.sspanak.tt9.preferences.screens.languages.LanguagesScreen;
|
import io.github.sspanak.tt9.preferences.screens.languages.LanguagesScreen;
|
||||||
|
|
@ -110,6 +111,8 @@ public class PreferencesActivity extends AppCompatActivity implements Preference
|
||||||
return new AppearanceScreen(this);
|
return new AppearanceScreen(this);
|
||||||
case DebugScreen.NAME:
|
case DebugScreen.NAME:
|
||||||
return new DebugScreen(this);
|
return new DebugScreen(this);
|
||||||
|
case DeleteWordsScreen.NAME:
|
||||||
|
return new DeleteWordsScreen(this);
|
||||||
case HotkeysScreen.NAME:
|
case HotkeysScreen.NAME:
|
||||||
return new HotkeysScreen(this);
|
return new HotkeysScreen(this);
|
||||||
case KeyPadScreen.NAME:
|
case KeyPadScreen.NAME:
|
||||||
|
|
|
||||||
|
|
@ -278,6 +278,7 @@ public class SettingsStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final static int DELETE_WORDS_SEARCH_DELAY = 500; // ms
|
||||||
public final static int DICTIONARY_AUTO_LOAD_COOLDOWN_TIME = 120000; // ms
|
public final static int DICTIONARY_AUTO_LOAD_COOLDOWN_TIME = 120000; // ms
|
||||||
public final static int DICTIONARY_IMPORT_BATCH_SIZE = 5000; // words
|
public final static int DICTIONARY_IMPORT_BATCH_SIZE = 5000; // words
|
||||||
public final static int DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME = 250; // ms
|
public final static int DICTIONARY_IMPORT_PROGRESS_UPDATE_TIME = 250; // ms
|
||||||
|
|
@ -286,7 +287,6 @@ public class SettingsStore {
|
||||||
public final static float SOFT_KEY_COMPLEX_LABEL_TITLE_SIZE = 0.55f;
|
public final static float SOFT_KEY_COMPLEX_LABEL_TITLE_SIZE = 0.55f;
|
||||||
public final static float SOFT_KEY_COMPLEX_LABEL_ARABIC_TITLE_SIZE = 0.72f;
|
public final static float SOFT_KEY_COMPLEX_LABEL_ARABIC_TITLE_SIZE = 0.72f;
|
||||||
public final static float SOFT_KEY_COMPLEX_LABEL_SUB_TITLE_SIZE = 0.8f;
|
public final static float SOFT_KEY_COMPLEX_LABEL_SUB_TITLE_SIZE = 0.8f;
|
||||||
|
|
||||||
public final static int SUGGESTIONS_MAX = 20;
|
public final static int SUGGESTIONS_MAX = 20;
|
||||||
public final static int SUGGESTIONS_MIN = 8;
|
public final static int SUGGESTIONS_MIN = 8;
|
||||||
public final static int SUGGESTIONS_SELECT_ANIMATION_DURATION = 66;
|
public final static int SUGGESTIONS_SELECT_ANIMATION_DURATION = 66;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package io.github.sspanak.tt9.preferences.screens.deleteWords;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceCategory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.R;
|
||||||
|
|
||||||
|
class DeletableWordsList {
|
||||||
|
static final String NAME = "delete_words_list";
|
||||||
|
|
||||||
|
private final PreferenceCategory item;
|
||||||
|
|
||||||
|
DeletableWordsList(Preference preference) {
|
||||||
|
item = preference instanceof PreferenceCategory ? (PreferenceCategory) preference : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clear() {
|
||||||
|
if (item != null) {
|
||||||
|
item.removeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addWord(String word) {
|
||||||
|
if (item != null) {
|
||||||
|
PreferenceDeletableWord pref = new PreferenceDeletableWord(item.getContext());
|
||||||
|
pref.setWord(word);
|
||||||
|
pref.setLayoutResource(R.layout.pref_deletable_word);
|
||||||
|
item.addPreference(pref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addWords(ArrayList<String> words) {
|
||||||
|
for (String word : words) {
|
||||||
|
addWord(word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addNoResult(boolean noSearchTerm) {
|
||||||
|
if (item != null) {
|
||||||
|
Preference pref = new Preference(item.getContext());
|
||||||
|
pref.setSummary(noSearchTerm ? "--" : item.getContext().getString(R.string.delete_words_no_result));
|
||||||
|
pref.setLayoutResource(R.layout.pref_text);
|
||||||
|
item.addPreference(pref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setResult(@NonNull String searchTerm, ArrayList<String> words) {
|
||||||
|
clear();
|
||||||
|
if (words == null || words.isEmpty()) {
|
||||||
|
addNoResult(searchTerm.isEmpty());
|
||||||
|
} else {
|
||||||
|
addWords(words);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package io.github.sspanak.tt9.preferences.screens.deleteWords;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.R;
|
||||||
|
import io.github.sspanak.tt9.preferences.PreferencesActivity;
|
||||||
|
import io.github.sspanak.tt9.preferences.screens.BaseScreenFragment;
|
||||||
|
|
||||||
|
public class DeleteWordsScreen extends BaseScreenFragment {
|
||||||
|
final public static String NAME = "DeleteWords";
|
||||||
|
|
||||||
|
public DeleteWordsScreen() { init(); }
|
||||||
|
public DeleteWordsScreen(PreferencesActivity activity) { init(activity); }
|
||||||
|
|
||||||
|
@Override public String getName() { return NAME; }
|
||||||
|
@Override protected int getTitle() { return R.string.pref_category_delete_words; }
|
||||||
|
@Override protected int getXml() { return R.xml.prefs_screen_delete_words; }
|
||||||
|
|
||||||
|
@Override protected void onCreate() {
|
||||||
|
createPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPage() {
|
||||||
|
DeletableWordsList searchResultsList = new DeletableWordsList(findPreference(DeletableWordsList.NAME));
|
||||||
|
searchResultsList.setResult("", null);
|
||||||
|
|
||||||
|
PreferenceSearchWords searchWords = findPreference(PreferenceSearchWords.NAME);
|
||||||
|
if (searchWords != null) {
|
||||||
|
searchWords.setOnWordsHandler((words) -> searchResultsList.setResult(searchWords.getLastSearchTerm(), words));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package io.github.sspanak.tt9.preferences.screens.deleteWords;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceCategory;
|
||||||
|
import androidx.preference.PreferenceViewHolder;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.R;
|
||||||
|
import io.github.sspanak.tt9.db.WordStoreAsync;
|
||||||
|
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||||
|
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||||
|
import io.github.sspanak.tt9.ui.UI;
|
||||||
|
|
||||||
|
public class PreferenceDeletableWord extends Preference {
|
||||||
|
private String word;
|
||||||
|
|
||||||
|
|
||||||
|
public PreferenceDeletableWord(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); }
|
||||||
|
public PreferenceDeletableWord(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
|
||||||
|
public PreferenceDeletableWord(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); }
|
||||||
|
public PreferenceDeletableWord(@NonNull Context context) { super(context); }
|
||||||
|
|
||||||
|
|
||||||
|
public void setWord(String word) {
|
||||||
|
this.word = word;
|
||||||
|
setTitle(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
super.onClick();
|
||||||
|
|
||||||
|
Context context = getContext();
|
||||||
|
|
||||||
|
UI.confirm(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.delete_words_deleted_confirm_deletion_title),
|
||||||
|
context.getString(R.string.delete_words_deleted_confirm_deletion_question, word),
|
||||||
|
context.getString(R.string.delete_words_deleted_confirm_deletion_yes),
|
||||||
|
this::onDeletionConfirmed,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void onDeletionConfirmed() {
|
||||||
|
SettingsStore settings = new SettingsStore(getContext());
|
||||||
|
WordStoreAsync.deleteCustomWord(
|
||||||
|
this::onWordDeleted,
|
||||||
|
LanguageCollection.getLanguage(getContext(), settings.getInputLanguage()),
|
||||||
|
word
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void onWordDeleted() {
|
||||||
|
if (getParent() instanceof PreferenceCategory) {
|
||||||
|
getParent().removePreference(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Activity activity = (Activity) getContext();
|
||||||
|
activity.runOnUiThread(
|
||||||
|
() -> UI.toastFromAsync(getContext(), activity.getString(R.string.delete_words_deleted_x, word))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package io.github.sspanak.tt9.preferences.screens.deleteWords;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceViewHolder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.ConsumerCompat;
|
||||||
|
import io.github.sspanak.tt9.Logger;
|
||||||
|
import io.github.sspanak.tt9.R;
|
||||||
|
import io.github.sspanak.tt9.db.WordStoreAsync;
|
||||||
|
import io.github.sspanak.tt9.languages.Language;
|
||||||
|
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||||
|
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||||
|
|
||||||
|
public class PreferenceSearchWords extends Preference {
|
||||||
|
public static final String NAME = "dictionary_delete_words_search";
|
||||||
|
private static final String LOG_TAG = PreferenceSearchWords.class.getSimpleName();
|
||||||
|
|
||||||
|
private ConsumerCompat<ArrayList<String>> onWords;
|
||||||
|
private SettingsStore settings;
|
||||||
|
@NonNull private String lastSearchTerm = "";
|
||||||
|
|
||||||
|
|
||||||
|
public PreferenceSearchWords(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); }
|
||||||
|
public PreferenceSearchWords(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
|
||||||
|
public PreferenceSearchWords(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); }
|
||||||
|
public PreferenceSearchWords(@NonNull Context context) { super(context); }
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
|
||||||
|
super.onBindViewHolder(holder);
|
||||||
|
EditText editText = holder.itemView.findViewById(R.id.input_text_input_field);
|
||||||
|
if (editText == null) {
|
||||||
|
Logger.e(LOG_TAG, "Cannot attach a text change listener. Unable to find the EditText element.");
|
||||||
|
} else {
|
||||||
|
editText.addTextChangedListener(TextChangeListener.getInstance(this::onChange));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getLastSearchTerm() {
|
||||||
|
return lastSearchTerm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SettingsStore getSettings() {
|
||||||
|
if (settings == null) {
|
||||||
|
settings = new SettingsStore(getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void onChange(String word) {
|
||||||
|
lastSearchTerm = word == null || word.trim().isEmpty() ? "" : word.trim();
|
||||||
|
|
||||||
|
if (onWords == null) {
|
||||||
|
Logger.w(LOG_TAG, "No handler set for the word change event.");
|
||||||
|
} else if (lastSearchTerm.isEmpty()) {
|
||||||
|
Logger.d(LOG_TAG, "Not searching for an empty word.");
|
||||||
|
onWords.accept(null);
|
||||||
|
} else {
|
||||||
|
Language currentLanguage = LanguageCollection.getLanguage(getContext(), getSettings().getInputLanguage());
|
||||||
|
WordStoreAsync.getCustomWords(onWords, currentLanguage, lastSearchTerm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setOnWordsHandler(ConsumerCompat<ArrayList<String>> onWords) {
|
||||||
|
this.onWords = onWords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package io.github.sspanak.tt9.preferences.screens.deleteWords;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.ConsumerCompat;
|
||||||
|
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||||
|
|
||||||
|
class TextChangeListener implements TextWatcher {
|
||||||
|
private static TextChangeListener self;
|
||||||
|
|
||||||
|
@NonNull private ConsumerCompat<String> onChange;
|
||||||
|
@NonNull private final Handler debouncer = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
private TextChangeListener(@NonNull ConsumerCompat<String> onChange) {
|
||||||
|
this.onChange = onChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TextChangeListener getInstance(@NonNull ConsumerCompat<String> onChange) {
|
||||||
|
if (self == null) {
|
||||||
|
self = new TextChangeListener(onChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = onChange;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void afterTextChanged(Editable s) {
|
||||||
|
debouncer.removeCallbacksAndMessages(null);
|
||||||
|
debouncer.postDelayed(() -> onChange.accept(s.toString()), SettingsStore.DELETE_WORDS_SEARCH_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||||
|
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.github.sspanak.tt9.preferences.screens.languages;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.preferences.items.ItemClickable;
|
||||||
|
|
||||||
|
class ItemDeleteCustomWords extends ItemClickable {
|
||||||
|
final static String NAME = "screen_delete_words";
|
||||||
|
ItemDeleteCustomWords(Preference item) { super(item); }
|
||||||
|
@Override protected boolean onClick(Preference p) { return false; }
|
||||||
|
}
|
||||||
|
|
@ -39,8 +39,6 @@ class ItemLoadDictionary extends ItemClickable {
|
||||||
this.onStart = onStart;
|
this.onStart = onStart;
|
||||||
this.onFinish = onFinish;
|
this.onFinish = onFinish;
|
||||||
|
|
||||||
|
|
||||||
loader.setOnStatusChange(this::onLoadingStatusChange);
|
|
||||||
refreshStatus();
|
refreshStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,6 +83,7 @@ class ItemLoadDictionary extends ItemClickable {
|
||||||
|
|
||||||
|
|
||||||
private void setLoadingStatus() {
|
private void setLoadingStatus() {
|
||||||
|
loader.setOnStatusChange(this::onLoadingStatusChange);
|
||||||
onStart.run();
|
onStart.run();
|
||||||
item.setTitle(context.getString(R.string.dictionary_cancel_load));
|
item.setTitle(context.getString(R.string.dictionary_cancel_load));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ public class LanguagesScreen extends BaseScreenFragment {
|
||||||
this::onActionFinish
|
this::onActionFinish
|
||||||
));
|
));
|
||||||
|
|
||||||
|
clickables.add(new ItemDeleteCustomWords(findPreference(ItemDeleteCustomWords.NAME)));
|
||||||
|
|
||||||
exportCustomWordsItem = new ItemExportCustomWords(
|
exportCustomWordsItem = new ItemExportCustomWords(
|
||||||
findPreference(ItemExportCustomWords.NAME),
|
findPreference(ItemExportCustomWords.NAME),
|
||||||
activity,
|
activity,
|
||||||
|
|
|
||||||
28
app/src/main/res/layout/pref_deletable_word.xml
Normal file
28
app/src/main/res/layout/pref_deletable_word.xml
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="@dimen/pref_padding_horizontal"
|
||||||
|
android:paddingVertical="@dimen/pref_padding_vertical"
|
||||||
|
app:layout_anchorGravity="center_horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingEnd="15dp"
|
||||||
|
android:text="✕"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.TextView"
|
||||||
|
android:textSize="@dimen/soft_key_icon_size"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.TextView"
|
||||||
|
android:textSize="@dimen/pref_text_size"
|
||||||
|
tools:text="Lorem" />
|
||||||
|
</LinearLayout>
|
||||||
33
app/src/main/res/layout/pref_input_text.xml
Normal file
33
app/src/main/res/layout/pref_input_text.xml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:descendantFocusability="afterDescendants"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="@dimen/pref_padding_horizontal"
|
||||||
|
android:paddingVertical="@dimen/pref_padding_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:labelFor="@id/input_text_input_field"
|
||||||
|
android:text="?android:title" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/input_text_input_field"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="text"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:textSize="@dimen/pref_text_size" />
|
||||||
|
|
||||||
|
<TextView android:id="@android:id/summary"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
|
android:textSize="@dimen/pref_summary_size" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
<string name="key_back">Назад</string>
|
<string name="key_back">Назад</string>
|
||||||
<string name="key_call">Зелена слушалка</string>
|
<string name="key_call">Зелена слушалка</string>
|
||||||
<string name="dictionary_export">Експортирай избраните</string>
|
<string name="dictionary_export">Експортирай избраните</string>
|
||||||
<string name="dictionary_export_custom_words_button">Експортирай</string>
|
<string name="dictionary_export_custom_words">Експортирай</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Експортиране на CSV с всички добавени думи в: „%1$s“.</string>
|
<string name="dictionary_export_custom_words_summary">Експортиране на CSV с всички добавени думи в: „%1$s“.</string>
|
||||||
<string name="dictionary_export_failed">Неуспешно експортиране</string>
|
<string name="dictionary_export_failed">Неуспешно експортиране</string>
|
||||||
<string name="dictionary_export_failed_more_info">За повече информация, активирайте режима за отстраняване на грешки и прегледайте журнала.</string>
|
<string name="dictionary_export_failed_more_info">За повече информация, активирайте режима за отстраняване на грешки и прегледайте журнала.</string>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
<string name="pref_dark_theme_no">Nein</string>
|
<string name="pref_dark_theme_no">Nein</string>
|
||||||
<string name="pref_dark_theme_auto">Automatisch</string>
|
<string name="pref_dark_theme_auto">Automatisch</string>
|
||||||
<string name="dictionary_export">Ausgewählte exportieren</string>
|
<string name="dictionary_export">Ausgewählte exportieren</string>
|
||||||
<string name="dictionary_export_custom_words_button">Exportieren</string>
|
<string name="dictionary_export_custom_words">Exportieren</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Exportiere ein CSV mit allen hinzugefügten Wörtern nach: „%1$s“.</string>
|
<string name="dictionary_export_custom_words_summary">Exportiere ein CSV mit allen hinzugefügten Wörtern nach: „%1$s“.</string>
|
||||||
<string name="dictionary_export_failed">Export fehlgeschlagen</string>
|
<string name="dictionary_export_failed">Export fehlgeschlagen</string>
|
||||||
<string name="dictionary_export_failed_more_info">Für weitere Informationen, aktivieren Sie den Debug-Modus und sehen Sie sich die Protokolle an.</string>
|
<string name="dictionary_export_failed_more_info">Für weitere Informationen, aktivieren Sie den Debug-Modus und sehen Sie sich die Protokolle an.</string>
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@
|
||||||
<string name="pref_dark_theme_no">No</string>
|
<string name="pref_dark_theme_no">No</string>
|
||||||
<string name="pref_dark_theme_auto">Automática</string>
|
<string name="pref_dark_theme_auto">Automática</string>
|
||||||
<string name="dictionary_export">Exportar seleccionados</string>
|
<string name="dictionary_export">Exportar seleccionados</string>
|
||||||
<string name="dictionary_export_custom_words_button">Exportar</string>
|
<string name="dictionary_export_custom_words">Exportar</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Exportar un CSV con todas las palabras añadidas a: \"%1$s\".</string>
|
<string name="dictionary_export_custom_words_summary">Exportar un CSV con todas las palabras añadidas a: \"%1$s\".</string>
|
||||||
<string name="dictionary_export_failed">Fallo en la exportación</string>
|
<string name="dictionary_export_failed">Fallo en la exportación</string>
|
||||||
<string name="dictionary_export_failed_more_info">Para obtener más información, habilita el modo de depuración y consulta los registros.</string>
|
<string name="dictionary_export_failed_more_info">Para obtener más información, habilita el modo de depuración y consulta los registros.</string>
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@
|
||||||
<string name="pref_dark_theme_auto">Automatique</string>
|
<string name="pref_dark_theme_auto">Automatique</string>
|
||||||
<string name="add_word_confirm">Ajouter mot « %1$s » à %2$s?</string>
|
<string name="add_word_confirm">Ajouter mot « %1$s » à %2$s?</string>
|
||||||
<string name="dictionary_export">Exporter les sélectionées</string>
|
<string name="dictionary_export">Exporter les sélectionées</string>
|
||||||
<string name="dictionary_export_custom_words_button">Exporter</string>
|
<string name="dictionary_export_custom_words">Exporter</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Exporter un CSV avec tous les mots ajoutés vers : «%1$s».</string>
|
<string name="dictionary_export_custom_words_summary">Exporter un CSV avec tous les mots ajoutés vers : «%1$s».</string>
|
||||||
<string name="dictionary_export_failed">Échec de l\'exportation</string>
|
<string name="dictionary_export_failed">Échec de l\'exportation</string>
|
||||||
<string name="dictionary_export_failed_more_info">Pour plus d\'informations, activez le mode de débogage et consultez les journaux.</string>
|
<string name="dictionary_export_failed_more_info">Pour plus d\'informations, activez le mode de débogage et consultez les journaux.</string>
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
<string name="pref_dark_theme_no">No</string>
|
<string name="pref_dark_theme_no">No</string>
|
||||||
<string name="pref_dark_theme_auto">Automatica</string>
|
<string name="pref_dark_theme_auto">Automatica</string>
|
||||||
<string name="dictionary_export">Esporta selezionate</string>
|
<string name="dictionary_export">Esporta selezionate</string>
|
||||||
<string name="dictionary_export_custom_words_button">Esportare</string>
|
<string name="dictionary_export_custom_words">Esportare</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Esporta un CSV con tutte le parole aggiunte su: \"%1$s\".</string>
|
<string name="dictionary_export_custom_words_summary">Esporta un CSV con tutte le parole aggiunte su: \"%1$s\".</string>
|
||||||
<string name="dictionary_export_failed">Esportazione fallita</string>
|
<string name="dictionary_export_failed">Esportazione fallita</string>
|
||||||
<string name="dictionary_export_failed_more_info">Per ulteriori informazioni, abilita la modalità di debug e consulta i log.</string>
|
<string name="dictionary_export_failed_more_info">Per ulteriori informazioni, abilita la modalità di debug e consulta i log.</string>
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
<string name="pref_dark_theme_no">לא</string>
|
<string name="pref_dark_theme_no">לא</string>
|
||||||
<string name="pref_dark_theme_auto">אוטומטי</string>
|
<string name="pref_dark_theme_auto">אוטומטי</string>
|
||||||
<string name="dictionary_export">ייצוא שנבחר</string>
|
<string name="dictionary_export">ייצוא שנבחר</string>
|
||||||
<string name="dictionary_export_custom_words_button">לְיְצוֹא</string>
|
<string name="dictionary_export_custom_words">לְיְצוֹא</string>
|
||||||
<string name="dictionary_export_custom_words_summary">ייצוא CSV עם כל המילים שנוספו ל: \"%1$s\".</string>
|
<string name="dictionary_export_custom_words_summary">ייצוא CSV עם כל המילים שנוספו ל: \"%1$s\".</string>
|
||||||
<string name="dictionary_export_failed">נכשל בייצוא</string>
|
<string name="dictionary_export_failed">נכשל בייצוא</string>
|
||||||
<string name="dictionary_export_failed_more_info">"למידע נוסף, הפעל מצב איתור באגים וראה את הלוגים. "</string>
|
<string name="dictionary_export_failed_more_info">"למידע נוסף, הפעל מצב איתור באגים וראה את הלוגים. "</string>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
<string name="pref_dark_theme_no">Nee</string>
|
<string name="pref_dark_theme_no">Nee</string>
|
||||||
<string name="pref_dark_theme_auto">Automatisch</string>
|
<string name="pref_dark_theme_auto">Automatisch</string>
|
||||||
<string name="dictionary_export">Geselecteerde exporteren</string>
|
<string name="dictionary_export">Geselecteerde exporteren</string>
|
||||||
<string name="dictionary_export_custom_words_button">Exporteren</string>
|
<string name="dictionary_export_custom_words">Exporteren</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Exporteer een CSV met alle toegevoegde woorden naar: \"%1$s\".</string>
|
<string name="dictionary_export_custom_words_summary">Exporteer een CSV met alle toegevoegde woorden naar: \"%1$s\".</string>
|
||||||
<string name="dictionary_export_failed">Exporteren mislukt</string>
|
<string name="dictionary_export_failed">Exporteren mislukt</string>
|
||||||
<string name="dictionary_export_failed_more_info">Voor meer informatie, schakel de debug-modus in en bekijk de logs.</string>
|
<string name="dictionary_export_failed_more_info">Voor meer informatie, schakel de debug-modus in en bekijk de logs.</string>
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
<string name="pref_dark_theme_no">Não</string>
|
<string name="pref_dark_theme_no">Não</string>
|
||||||
<string name="pref_dark_theme_auto">Automático</string>
|
<string name="pref_dark_theme_auto">Automático</string>
|
||||||
<string name="dictionary_export">Exportar selecionados</string>
|
<string name="dictionary_export">Exportar selecionados</string>
|
||||||
<string name="dictionary_export_custom_words_button">Exportar</string>
|
<string name="dictionary_export_custom_words">Exportar</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Exportar um CSV com todas as palavras adicionadas para: \"%1$s\".</string>
|
<string name="dictionary_export_custom_words_summary">Exportar um CSV com todas as palavras adicionadas para: \"%1$s\".</string>
|
||||||
<string name="dictionary_export_failed">Falha na exportação</string>
|
<string name="dictionary_export_failed">Falha na exportação</string>
|
||||||
<string name="dictionary_export_failed_more_info">Para mais informações, ative o modo de depuração e veja os registros.</string>
|
<string name="dictionary_export_failed_more_info">Para mais informações, ative o modo de depuração e veja os registros.</string>
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@
|
||||||
<string name="pref_dark_theme_auto">Автоматически</string>
|
<string name="pref_dark_theme_auto">Автоматически</string>
|
||||||
<string name="add_word_confirm">Добавить слово «%1$s» в %2$s?</string>
|
<string name="add_word_confirm">Добавить слово «%1$s» в %2$s?</string>
|
||||||
<string name="dictionary_export">Экспортировать выбранные</string>
|
<string name="dictionary_export">Экспортировать выбранные</string>
|
||||||
<string name="dictionary_export_custom_words_button">Экспортировать</string>
|
<string name="dictionary_export_custom_words">Экспортировать</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Экспорт CSV со всеми добавленными словами в: «%1$s».</string>
|
<string name="dictionary_export_custom_words_summary">Экспорт CSV со всеми добавленными словами в: «%1$s».</string>
|
||||||
<string name="dictionary_export_failed">Ошибка экспорта</string>
|
<string name="dictionary_export_failed">Ошибка экспорта</string>
|
||||||
<string name="dictionary_export_failed_more_info">Для получения дополнительной информации включите режим отладки и просмотрите журналы.</string>
|
<string name="dictionary_export_failed_more_info">Для получения дополнительной информации включите режим отладки и просмотрите журналы.</string>
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@
|
||||||
<string name="dictionary_truncating">Видаляється…</string>
|
<string name="dictionary_truncating">Видаляється…</string>
|
||||||
|
|
||||||
<string name="dictionary_export">Експортувати вибрані</string>
|
<string name="dictionary_export">Експортувати вибрані</string>
|
||||||
<string name="dictionary_export_custom_words_button">Експортувати</string>
|
<string name="dictionary_export_custom_words">Експортувати</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Експорт CSV з усіма доданими словами в: \"%1$s\".</string>
|
<string name="dictionary_export_custom_words_summary">Експорт CSV з усіма доданими словами в: \"%1$s\".</string>
|
||||||
<string name="dictionary_export_failed">Помилка експорту</string>
|
<string name="dictionary_export_failed">Помилка експорту</string>
|
||||||
<string name="dictionary_export_failed_more_info">Для отримання додаткової інформації увімкніть режим відлагодження та перегляньте журнали.</string>
|
<string name="dictionary_export_failed_more_info">Для отримання додаткової інформації увімкніть режим відлагодження та перегляньте журнали.</string>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
<string name="pref_category_about">About</string>
|
<string name="pref_category_about">About</string>
|
||||||
<string name="pref_category_abc_mode">ABC Mode</string>
|
<string name="pref_category_abc_mode">ABC Mode</string>
|
||||||
<string name="pref_category_custom_words">Added Words</string>
|
<string name="pref_category_custom_words">Added Words</string>
|
||||||
|
<string name="pref_category_delete_words">Delete Added Words</string>
|
||||||
<string name="pref_category_hacks">Compatibility</string>
|
<string name="pref_category_hacks">Compatibility</string>
|
||||||
<string name="pref_category_appearance">Appearance</string>
|
<string name="pref_category_appearance">Appearance</string>
|
||||||
<string name="pref_category_debug_options" translatable="false">Debug Options</string>
|
<string name="pref_category_debug_options" translatable="false">Debug Options</string>
|
||||||
|
|
@ -73,7 +74,7 @@
|
||||||
<string name="dictionary_truncating">Deleting…</string>
|
<string name="dictionary_truncating">Deleting…</string>
|
||||||
|
|
||||||
<string name="dictionary_export">Export Selected</string>
|
<string name="dictionary_export">Export Selected</string>
|
||||||
<string name="dictionary_export_custom_words_button">Export</string>
|
<string name="dictionary_export_custom_words">Export</string>
|
||||||
<string name="dictionary_export_custom_words_summary">Export a CSV with all added words in: \"%1$s\".</string>
|
<string name="dictionary_export_custom_words_summary">Export a CSV with all added words in: \"%1$s\".</string>
|
||||||
<string name="dictionary_export_failed">Exporting Failed</string>
|
<string name="dictionary_export_failed">Exporting Failed</string>
|
||||||
<string name="dictionary_export_failed_more_info">For more info, enable debugging mode and see the logs.</string>
|
<string name="dictionary_export_failed_more_info">For more info, enable debugging mode and see the logs.</string>
|
||||||
|
|
@ -82,6 +83,16 @@
|
||||||
<string name="dictionary_export_generating_csv">Exporting CSV…</string>
|
<string name="dictionary_export_generating_csv">Exporting CSV…</string>
|
||||||
<string name="dictionary_export_generating_csv_for_language">Exporting CSV (%1$s)…</string>
|
<string name="dictionary_export_generating_csv_for_language">Exporting CSV (%1$s)…</string>
|
||||||
|
|
||||||
|
<string name="delete_words_link">Delete</string>
|
||||||
|
<string name="delete_words_link_summary">Search and delete misspelled or unneeded words.</string>
|
||||||
|
<string name="delete_words_search_placeholder">Search Words</string>
|
||||||
|
<string name="delete_words_list">Search Results</string>
|
||||||
|
<string name="delete_words_no_result">No results</string>
|
||||||
|
<string name="delete_words_deleted_confirm_deletion_title">Confirm Deletion</string>
|
||||||
|
<string name="delete_words_deleted_confirm_deletion_question">Are you sure you want to delete \"%1$s\"?</string>
|
||||||
|
<string name="delete_words_deleted_confirm_deletion_yes">Delete</string>
|
||||||
|
<string name="delete_words_deleted_x">\"%1$s\" was deleted.</string>
|
||||||
|
|
||||||
<string name="dictionary_update_message">Dictionary update available for \"%1$s\". Would you like to load it?</string>
|
<string name="dictionary_update_message">Dictionary update available for \"%1$s\". Would you like to load it?</string>
|
||||||
<string name="dictionary_update_update">Load</string>
|
<string name="dictionary_update_update">Load</string>
|
||||||
|
|
||||||
|
|
|
||||||
13
app/src/main/res/xml/prefs_screen_delete_words.xml
Normal file
13
app/src/main/res/xml/prefs_screen_delete_words.xml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:orderingFromXml="true">
|
||||||
|
|
||||||
|
<io.github.sspanak.tt9.preferences.screens.deleteWords.PreferenceSearchWords
|
||||||
|
android:layout="@layout/pref_input_text"
|
||||||
|
android:key="dictionary_delete_words_search"
|
||||||
|
android:title="@string/delete_words_search_placeholder" />
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="delete_words_list"
|
||||||
|
android:title="@string/delete_words_list"
|
||||||
|
android:layout="@layout/pref_category" />
|
||||||
|
</PreferenceScreen>
|
||||||
|
|
@ -35,7 +35,14 @@
|
||||||
<Preference
|
<Preference
|
||||||
app:key="dictionary_export_custom"
|
app:key="dictionary_export_custom"
|
||||||
app:layout="@layout/pref_text"
|
app:layout="@layout/pref_text"
|
||||||
app:title="@string/dictionary_export_custom_words_button" />
|
app:title="@string/dictionary_export_custom_words" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
app:fragment="io.github.sspanak.tt9.preferences.DeleteWordsScreen"
|
||||||
|
app:key="screen_delete_words"
|
||||||
|
app:layout="@layout/pref_text"
|
||||||
|
app:title="@string/delete_words_link"
|
||||||
|
app:summary="@string/delete_words_link_summary"/>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue