mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-15 06:22:45 +00:00
improve UI for user-added dictionaries
This commit is contained in:
parent
4a5d3155b4
commit
c53224dd2b
2 changed files with 88 additions and 58 deletions
|
@ -13,6 +13,8 @@ import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants
|
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.R
|
||||||
import org.dslul.openboard.inputmethod.latin.common.FileUtils
|
import org.dslul.openboard.inputmethod.latin.common.FileUtils
|
||||||
import org.dslul.openboard.inputmethod.latin.common.LocaleUtils
|
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.DialogUtils
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.DictionaryInfoUtils
|
import org.dslul.openboard.inputmethod.latin.utils.DictionaryInfoUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -114,57 +117,73 @@ class DictionarySettingsFragment : SubScreenFragment() {
|
||||||
if (currentDictLocale == null && currentDictState != DICT_NEW)
|
if (currentDictLocale == null && currentDictState != DICT_NEW)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
var dialog: AlertDialog? = null
|
||||||
val link = "<a href='$DICTIONARY_URL'>" +
|
val link = "<a href='$DICTIONARY_URL'>" +
|
||||||
resources.getString(R.string.dictionary_link_text) + "</a>"
|
resources.getString(R.string.dictionary_link_text) + "</a>"
|
||||||
val message = if (currentDictState == DICT_NEW)
|
val message = Html.fromHtml(resources.getString(R.string.add_dictionary, link))
|
||||||
Html.fromHtml(resources.getString(R.string.add_new_dictionary, link))
|
|
||||||
else
|
|
||||||
Html.fromHtml(resources.getString(R.string.update_dictionary, link))
|
|
||||||
val title = if (currentDictState == DICT_NEW) R.string.add_new_dictionary_title
|
val title = if (currentDictState == DICT_NEW) R.string.add_new_dictionary_title
|
||||||
else R.string.dictionary_settings_category
|
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))
|
val builder = AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity))
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.setMessage(message)
|
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setPositiveButton(updateButtonTitle) { _, _ ->
|
.setPositiveButton(R.string.user_dict_settings_add_menu_title) { _, _ ->
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||||
.addCategory(Intent.CATEGORY_OPENABLE)
|
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
.setType("application/octet-stream")
|
.setType("application/octet-stream")
|
||||||
startActivityForResult(intent, DICTIONARY_REQUEST_CODE)
|
startActivityForResult(intent, DICTIONARY_REQUEST_CODE)
|
||||||
}
|
}
|
||||||
|
if (!currentDictExistsForUser) {
|
||||||
// allow removing dictionaries
|
builder.setMessage(message)
|
||||||
if (currentDictExistsForUser) {
|
} else {
|
||||||
builder.setNeutralButton(if (currentDictExistsInternal) R.string.reset_dictionary else R.string.delete_dict) { _, _ ->
|
val l = LinearLayout(activity).apply {
|
||||||
AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity))
|
orientation = LinearLayout.VERTICAL
|
||||||
.setTitle(R.string.remove_dictionary_title)
|
setPadding(30, 30, 30, 10)
|
||||||
.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()
|
|
||||||
}
|
}
|
||||||
|
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()
|
dialog.show()
|
||||||
// make links in the HTML text work
|
// make links in the HTML text work
|
||||||
(dialog.findViewById<View>(android.R.id.message) as TextView).movementMethod =
|
(dialog.findViewById<View>(android.R.id.message) as? TextView)?.movementMethod = LinkMovementMethod.getInstance()
|
||||||
LinkMovementMethod.getInstance()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copied from CustomInputStyleSettingsFragment
|
// copied from CustomInputStyleSettingsFragment
|
||||||
|
@ -216,19 +235,35 @@ class DictionarySettingsFragment : SubScreenFragment() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val locale = newHeader.mLocaleString.toLocale()
|
val locale = newHeader.mLocaleString.toLocale()
|
||||||
|
val currentDictLocale = currentDictLocale
|
||||||
if (currentDictLocale != null && locale != currentDictLocale) {
|
if (currentDictLocale != null && locale != currentDictLocale) {
|
||||||
cachedDictionaryFile.delete()
|
val message = resources.getString(
|
||||||
onDictionaryLoadingError(resources.getString(R.string.dictionary_file_wrong_locale, locale.displayName(), currentDictLocale?.displayName()))
|
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
|
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 <type>:<locale>
|
// idString is content of 'dictionary' key, in format <type>:<locale>
|
||||||
val dictionaryType = newHeader.mIdString.substringBefore(":")
|
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,
|
// 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
|
// but we already have a user dictionary for the same locale
|
||||||
val shouldAskMessageId = if (userDictFile.exists()) {
|
val shouldAskMessageId = if (oldDictFile.exists()) {
|
||||||
val oldHeader = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(userDictFile, 0, userDictFile.length())
|
val oldHeader = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(oldDictFile, 0, oldDictFile.length())
|
||||||
if (oldHeader != null && oldHeader.mVersionString.toInt() > newHeader.mVersionString.toInt())
|
if (oldHeader != null && oldHeader.mVersionString.toInt() > newHeader.mVersionString.toInt())
|
||||||
R.string.overwrite_old_dicitonary_messsage
|
R.string.overwrite_old_dicitonary_messsage
|
||||||
else if (currentDictState == DICT_NEW && currentDictLocale == null)
|
else if (currentDictState == DICT_NEW && currentDictLocale == null)
|
||||||
|
@ -236,9 +271,9 @@ class DictionarySettingsFragment : SubScreenFragment() {
|
||||||
else 0
|
else 0
|
||||||
} else 0
|
} else 0
|
||||||
if (shouldAskMessageId != 0)
|
if (shouldAskMessageId != 0)
|
||||||
showConfirmReplaceDialog(locale, dictionaryType, shouldAskMessageId)
|
showConfirmReplaceDialog(baseLocale, dictionaryType, shouldAskMessageId)
|
||||||
else
|
else
|
||||||
moveCachedFileToDictionaries(locale, dictionaryType)
|
moveCachedFileToDictionaries(baseLocale, dictionaryType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showConfirmReplaceDialog(locale: Locale, dictionaryType: String, messageId: Int) {
|
private fun showConfirmReplaceDialog(locale: Locale, dictionaryType: String, messageId: Int) {
|
||||||
|
@ -282,25 +317,20 @@ class DictionarySettingsFragment : SubScreenFragment() {
|
||||||
AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity))
|
AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(activity))
|
||||||
.setNegativeButton(android.R.string.ok, null)
|
.setNegativeButton(android.R.string.ok, null)
|
||||||
.setMessage(message)
|
.setMessage(message)
|
||||||
.setTitle("loading error")
|
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Locale.getUserDictFilename(dictionaryType: String) =
|
private fun Locale.getUserDictFilename(dictionaryType: String) =
|
||||||
DictionaryInfoUtils.getCacheDirectoryForLocale(this.toString(), activity) + File.separator + dictionaryType + "_" + USER_DICTIONARY_SUFFIX
|
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<String> {
|
private fun Locale.getUserDictFilenames(): List<String> {
|
||||||
val dicts = mutableListOf<String>()
|
val dir = File(DictionaryInfoUtils.getCacheDirectoryForLocale(this.toString(), activity))
|
||||||
val p = DictionaryInfoUtils.getCacheDirectoryForLocale(this.toString(), activity)
|
if (dir.exists() && dir.isDirectory) {
|
||||||
DictionaryInfoUtils.getCachedDirectoryList(activity)?.forEach { dir ->
|
return dir.listFiles { _, name -> name.endsWith(USER_DICTIONARY_SUFFIX) }?.map { it.absolutePath }.orEmpty()
|
||||||
if (!dir.isDirectory)
|
|
||||||
return@forEach
|
|
||||||
dir.list()?.forEach {
|
|
||||||
if (it.endsWith(USER_DICTIONARY_SUFFIX))
|
|
||||||
dicts.add(p + File.separator + it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dicts
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Locale.getInternalDictFilename() =
|
private fun Locale.getInternalDictFilename() =
|
||||||
|
|
|
@ -500,8 +500,6 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM
|
||||||
<string name="internal_dictionary_summary">Built-in dictionary</string>
|
<string name="internal_dictionary_summary">Built-in dictionary</string>
|
||||||
<!-- Title for the adding new user dictionary dialog -->
|
<!-- Title for the adding new user dictionary dialog -->
|
||||||
<string name="add_new_dictionary_title">"Add dictionary from file"</string>
|
<string name="add_new_dictionary_title">"Add dictionary from file"</string>
|
||||||
<!-- Button text for updating a dictionary -->
|
|
||||||
<string name="update_dictionary_button">"Update"</string>
|
|
||||||
<!-- Message for user dictionary replacement dialog -->
|
<!-- Message for user dictionary replacement dialog -->
|
||||||
<string name="replace_dictionary_message">"Really replace existing user-added dictionary for %s?"</string>
|
<string name="replace_dictionary_message">"Really replace existing user-added dictionary for %s?"</string>
|
||||||
<!-- Message when trying to replace user dictionary with older version -->
|
<!-- Message when trying to replace user dictionary with older version -->
|
||||||
|
@ -509,15 +507,15 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM
|
||||||
<!-- Title and confirm button text for user dictionary replacement dialog -->
|
<!-- Title and confirm button text for user dictionary replacement dialog -->
|
||||||
<string name="replace_dictionary">"Replace dictionary"</string>
|
<string name="replace_dictionary">"Replace dictionary"</string>
|
||||||
<!-- Message for user dictionary remove dialog -->
|
<!-- Message for user dictionary remove dialog -->
|
||||||
<string name="remove_dictionary_message">"Really remove user-added dictionaries for %s?"</string>
|
<string name="remove_dictionary_message">"Really remove user-added dictionary \"%1$s\" for %2$s?"</string>
|
||||||
<!-- Title for user dictionary remove dialog -->
|
<!-- Title for user dictionary remove dialog -->
|
||||||
<string name="remove_dictionary_title">"Remove dictionary"</string>
|
<string name="remove_dictionary_title">"Remove dictionary"</string>
|
||||||
<!-- Button text in user dictionary remove dialog for resetting to default -->
|
<!-- Button text in user dictionary remove dialog for resetting to default -->
|
||||||
<string name="reset_dictionary">"Reset to default"</string>
|
<string name="reset_dictionary">"Reset to default"</string>
|
||||||
<!-- Message for the user dictionary selection dialog. This string will be interpreted as HTML -->
|
<!-- Message for the user dictionary selection dialog. This string will be interpreted as HTML -->
|
||||||
<string name="update_dictionary">"Select a dictionary to replace the current main dictionary. Dictionaries can be downloaded at %s."</string>
|
<string name="add_dictionary">"Select a dictionary to add. Dictionaries can be downloaded at %s."</string>
|
||||||
<!-- Message for the user dictionary selection dialog. This string will be interpreted as HTML -->
|
<!-- Message above list of user-added dictionaries -->
|
||||||
<string name="add_new_dictionary">"Select a new dictionary to be added to the list. Dictionaries can be downloaded at the %s."</string>
|
<string name="existing_dictionaries">"User-added dictionaries, click to remove:"</string>
|
||||||
<!-- Title of the link to the download page inserted into selection message (above) -->
|
<!-- Title of the link to the download page inserted into selection message (above) -->
|
||||||
<string name="dictionary_link_text">"project repository"</string>
|
<string name="dictionary_link_text">"project repository"</string>
|
||||||
<!-- Button text for dictionary file selection -->
|
<!-- Button text for dictionary file selection -->
|
||||||
|
@ -527,7 +525,9 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM
|
||||||
<!-- Text shown when dictionary file could not be read -->
|
<!-- Text shown when dictionary file could not be read -->
|
||||||
<string name="dictionary_file_error">"Error: Selected file is not a valid dictionary file"</string>
|
<string name="dictionary_file_error">"Error: Selected file is not a valid dictionary file"</string>
|
||||||
<!-- Text shown when dictionary file is not for the selected locale -->
|
<!-- Text shown when dictionary file is not for the selected locale -->
|
||||||
<string name="dictionary_file_wrong_locale">"Error: Selected file is for %1$s, but %2$s was expected"</string>
|
<string name="dictionary_file_wrong_locale">"The selected file is for %1$s, but %2$s was expected. Still use it for %2$s?"</string>
|
||||||
|
<!-- Button text for confirm / yes to the dictionary_file_wrong_locale message (above) -->
|
||||||
|
<string name="dictionary_file_wrong_locale_ok">"Still use"</string>
|
||||||
<!-- Text shown on other errors when loading dictionary file -->
|
<!-- Text shown on other errors when loading dictionary file -->
|
||||||
<string name="dictionary_load_error">"Error loading dictionary file"</string>
|
<string name="dictionary_load_error">"Error loading dictionary file"</string>
|
||||||
<!-- Name of the user dictionaries settings category -->
|
<!-- Name of the user dictionaries settings category -->
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue