diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/DictionarySettingsFragment.kt b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/DictionarySettingsFragment.kt index 23bfefdde..d19b87fa7 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/DictionarySettingsFragment.kt +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/DictionarySettingsFragment.kt @@ -13,6 +13,8 @@ import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.view.View +import android.widget.Button +import android.widget.LinearLayout import android.widget.TextView import android.widget.Toast import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants @@ -20,6 +22,7 @@ import org.dslul.openboard.inputmethod.latin.BinaryDictionaryGetter import org.dslul.openboard.inputmethod.latin.R import org.dslul.openboard.inputmethod.latin.common.FileUtils import org.dslul.openboard.inputmethod.latin.common.LocaleUtils +import org.dslul.openboard.inputmethod.latin.makedict.DictionaryHeader import org.dslul.openboard.inputmethod.latin.utils.DialogUtils import org.dslul.openboard.inputmethod.latin.utils.DictionaryInfoUtils import java.io.File @@ -114,57 +117,73 @@ class DictionarySettingsFragment : SubScreenFragment() { if (currentDictLocale == null && currentDictState != DICT_NEW) return + var dialog: AlertDialog? = null val link = "" + resources.getString(R.string.dictionary_link_text) + "" - val message = if (currentDictState == DICT_NEW) - Html.fromHtml(resources.getString(R.string.add_new_dictionary, link)) - else - Html.fromHtml(resources.getString(R.string.update_dictionary, link)) + val message = Html.fromHtml(resources.getString(R.string.add_dictionary, link)) val title = if (currentDictState == DICT_NEW) R.string.add_new_dictionary_title else R.string.dictionary_settings_category - val updateButtonTitle = if (currentDictExistsForUser) R.string.update_dictionary_button - else R.string.user_dict_settings_add_menu_title val builder = AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity)) .setNegativeButton(R.string.cancel, null) - .setMessage(message) .setTitle(title) - .setPositiveButton(updateButtonTitle) { _, _ -> + .setPositiveButton(R.string.user_dict_settings_add_menu_title) { _, _ -> val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) .addCategory(Intent.CATEGORY_OPENABLE) .setType("application/octet-stream") startActivityForResult(intent, DICTIONARY_REQUEST_CODE) } - - // allow removing dictionaries - if (currentDictExistsForUser) { - builder.setNeutralButton(if (currentDictExistsInternal) R.string.reset_dictionary else R.string.delete_dict) { _, _ -> - AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity)) - .setTitle(R.string.remove_dictionary_title) - .setMessage(resources.getString(R.string.remove_dictionary_message, currentDictLocale?.displayName())) - .setNegativeButton(R.string.cancel, null) - .setPositiveButton(R.string.delete_dict) { _,_ -> - currentDictLocale?.getUserDictFilenames()?.let { files -> - var parent: File? = null - files.forEach { - val f = File(it) - parent = f.parentFile - f.delete() - } - if (parent?.list()?.isEmpty() == true) - parent?.delete() - } - reloadDictionaries() - } - .show() + if (!currentDictExistsForUser) { + builder.setMessage(message) + } else { + val l = LinearLayout(activity).apply { + orientation = LinearLayout.VERTICAL + setPadding(30, 30, 30, 10) } + val filenames = currentDictLocale?.getUserDictFilenames().orEmpty() + if (filenames.isNotEmpty()) + l.addView(TextView(activity).apply { + setText(R.string.existing_dictionaries) + textSize = 16f + }) + for (fn in filenames) { + val b = Button(activity).apply { + text = getUserDictType(fn) + setOnClickListener { + AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity)) + .setTitle(R.string.remove_dictionary_title) + .setMessage(resources.getString(R.string.remove_dictionary_message, text, currentDictLocale?.displayName())) + .setNegativeButton(R.string.cancel, null) + .setPositiveButton(R.string.delete_dict) { _,_ -> + val f = File(fn) + val parent = f.parentFile + f.delete() + if (parent?.list()?.isEmpty() == true) + parent.delete() + + val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION) + activity.sendBroadcast(newDictBroadcast) + reloadDictionaries() + dialog?.dismiss() + } + .show() + } + } + l.addView(b) + } + val t = TextView(activity).apply { + text = message + textSize = 16f + } + l.addView(t) + builder.setView(l) + t.movementMethod = LinkMovementMethod.getInstance() } - val dialog = builder.create() + dialog = builder.create() dialog.show() // make links in the HTML text work - (dialog.findViewById(android.R.id.message) as TextView).movementMethod = - LinkMovementMethod.getInstance() + (dialog.findViewById(android.R.id.message) as? TextView)?.movementMethod = LinkMovementMethod.getInstance() } // copied from CustomInputStyleSettingsFragment @@ -216,19 +235,35 @@ class DictionarySettingsFragment : SubScreenFragment() { return } val locale = newHeader.mLocaleString.toLocale() + val currentDictLocale = currentDictLocale if (currentDictLocale != null && locale != currentDictLocale) { - cachedDictionaryFile.delete() - onDictionaryLoadingError(resources.getString(R.string.dictionary_file_wrong_locale, locale.displayName(), currentDictLocale?.displayName())) + val message = resources.getString( + R.string.dictionary_file_wrong_locale, + locale.displayName(), + currentDictLocale.displayName() + ) + AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity)) + .setMessage(message) + .setNegativeButton(android.R.string.cancel) { _, _ -> cachedDictionaryFile.delete() } + .setPositiveButton(R.string.dictionary_file_wrong_locale_ok) { _, _ -> + checkCachedDictionaryVersion(currentDictLocale, newHeader) + } + .show() return } + checkCachedDictionaryVersion(currentDictLocale ?: locale, newHeader) + } + + // baseLocale is the locale to which the dict will be added, not necessarily equal to dict locale + private fun checkCachedDictionaryVersion(baseLocale: Locale, newHeader: DictionaryHeader) { // idString is content of 'dictionary' key, in format : val dictionaryType = newHeader.mIdString.substringBefore(":") - val userDictFile = File(locale.getUserDictFilename(dictionaryType)) + val oldDictFile = File(baseLocale.getUserDictFilename(dictionaryType)) // ask for user confirmation if it would be a version downgrade or if user pressed add new, // but we already have a user dictionary for the same locale - val shouldAskMessageId = if (userDictFile.exists()) { - val oldHeader = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(userDictFile, 0, userDictFile.length()) + val shouldAskMessageId = if (oldDictFile.exists()) { + val oldHeader = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(oldDictFile, 0, oldDictFile.length()) if (oldHeader != null && oldHeader.mVersionString.toInt() > newHeader.mVersionString.toInt()) R.string.overwrite_old_dicitonary_messsage else if (currentDictState == DICT_NEW && currentDictLocale == null) @@ -236,9 +271,9 @@ class DictionarySettingsFragment : SubScreenFragment() { else 0 } else 0 if (shouldAskMessageId != 0) - showConfirmReplaceDialog(locale, dictionaryType, shouldAskMessageId) + showConfirmReplaceDialog(baseLocale, dictionaryType, shouldAskMessageId) else - moveCachedFileToDictionaries(locale, dictionaryType) + moveCachedFileToDictionaries(baseLocale, dictionaryType) } private fun showConfirmReplaceDialog(locale: Locale, dictionaryType: String, messageId: Int) { @@ -282,25 +317,20 @@ class DictionarySettingsFragment : SubScreenFragment() { AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity)) .setNegativeButton(android.R.string.ok, null) .setMessage(message) - .setTitle("loading error") .show() } private fun Locale.getUserDictFilename(dictionaryType: String) = DictionaryInfoUtils.getCacheDirectoryForLocale(this.toString(), activity) + File.separator + dictionaryType + "_" + USER_DICTIONARY_SUFFIX + private fun getUserDictType(dictionaryFilename: String) = dictionaryFilename.substringAfterLast(File.separator).substringBefore("_$USER_DICTIONARY_SUFFIX") + private fun Locale.getUserDictFilenames(): List { - val dicts = mutableListOf() - val p = DictionaryInfoUtils.getCacheDirectoryForLocale(this.toString(), activity) - DictionaryInfoUtils.getCachedDirectoryList(activity)?.forEach { dir -> - if (!dir.isDirectory) - return@forEach - dir.list()?.forEach { - if (it.endsWith(USER_DICTIONARY_SUFFIX)) - dicts.add(p + File.separator + it) - } + val dir = File(DictionaryInfoUtils.getCacheDirectoryForLocale(this.toString(), activity)) + if (dir.exists() && dir.isDirectory) { + return dir.listFiles { _, name -> name.endsWith(USER_DICTIONARY_SUFFIX) }?.map { it.absolutePath }.orEmpty() } - return dicts + return emptyList() } private fun Locale.getInternalDictFilename() = diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b065d7cb2..cae1a8c70 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -500,8 +500,6 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM Built-in dictionary "Add dictionary from file" - - "Update" "Really replace existing user-added dictionary for %s?" @@ -509,15 +507,15 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM "Replace dictionary" - "Really remove user-added dictionaries for %s?" + "Really remove user-added dictionary \"%1$s\" for %2$s?" "Remove dictionary" "Reset to default" - "Select a dictionary to replace the current main dictionary. Dictionaries can be downloaded at %s." - - "Select a new dictionary to be added to the list. Dictionaries can be downloaded at the %s." + "Select a dictionary to add. Dictionaries can be downloaded at %s." + + "User-added dictionaries, click to remove:" "project repository" @@ -527,7 +525,9 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM "Error: Selected file is not a valid dictionary file" - "Error: Selected file is for %1$s, but %2$s was expected" + "The selected file is for %1$s, but %2$s was expected. Still use it for %2$s?" + + "Still use" "Error loading dictionary file"