2017-09-09 17:09:04 +02:00
|
|
|
/*
|
|
|
|
* ------------------------------------------------------------------------------
|
2017-10-31 18:12:02 +01:00
|
|
|
* Gregor Santner <gsantner.net> wrote this. You can do whatever you want
|
2017-09-09 17:09:04 +02:00
|
|
|
* with it. If we meet some day, and you think it is worth it, you can buy me a
|
|
|
|
* coke in return. Provided as is without any kind of warranty. Do not blame or
|
|
|
|
* sue me if something goes wrong. No attribution required. - Gregor Santner
|
|
|
|
*
|
|
|
|
* License: Creative Commons Zero (CC0 1.0)
|
|
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Requires:
|
2018-03-02 15:56:14 +01:00
|
|
|
The BuildConfig field "APPLICATION_LANGUAGES" which is a array of all available languages
|
|
|
|
opoc/ContextUtils
|
2017-09-09 17:09:04 +02:00
|
|
|
* BuildConfig field can be defined by using the method below
|
|
|
|
|
2018-03-02 15:56:14 +01:00
|
|
|
buildConfigField "String[]", "APPLICATION_LANGUAGES", "${getUsedAndroidLanguages()}"
|
2017-09-09 17:09:04 +02:00
|
|
|
|
2017-10-31 14:18:52 +01:00
|
|
|
@SuppressWarnings(["UnnecessaryQualifiedReference", "SpellCheckingInspection", "GroovyUnusedDeclaration"])
|
2018-03-02 15:56:14 +01:00
|
|
|
// Returns used android languages as a buildConfig array: {'de', 'it', ..}"
|
|
|
|
static String getUsedAndroidLanguages() {
|
2017-09-09 17:09:04 +02:00
|
|
|
Set<String> langs = new HashSet<>()
|
|
|
|
new File('.').eachFileRecurse(groovy.io.FileType.DIRECTORIES) {
|
|
|
|
final foldername = it.name
|
|
|
|
if (foldername.startsWith('values-') && !it.canonicalPath.contains("build" + File.separator + "intermediates")) {
|
|
|
|
new File(it.toString()).eachFileRecurse(groovy.io.FileType.FILES) {
|
|
|
|
if (it.name.toLowerCase().endsWith(".xml") && it.getCanonicalFile().getText('UTF-8').contains("<string")) {
|
|
|
|
langs.add(foldername.replace("values-", ""))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-03-02 15:56:14 +01:00
|
|
|
return '{' + langs.collect { "\"${it}\"" }.join(",") + '}'
|
2017-09-09 17:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
* Summary: Change language of this app. Restart app for changes to take effect
|
|
|
|
|
|
|
|
* Define element in Preferences-XML:
|
2018-03-02 15:56:14 +01:00
|
|
|
<net.gsantner.opoc.preference.LanguagePreference
|
2017-09-09 17:09:04 +02:00
|
|
|
android:icon="@drawable/ic_language_black_24dp"
|
|
|
|
android:key="@string/pref_key__language"
|
|
|
|
android:summary="@string/pref_desc__language"
|
|
|
|
android:title="@string/pref_title__language"/>
|
|
|
|
*/
|
2018-03-02 15:56:14 +01:00
|
|
|
package net.gsantner.opoc.preference.nonsupport;
|
2017-09-09 17:09:04 +02:00
|
|
|
|
|
|
|
import android.annotation.TargetApi;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.os.Build;
|
2017-10-28 09:56:05 +02:00
|
|
|
import android.support.annotation.Nullable;
|
2018-03-02 15:56:14 +01:00
|
|
|
import android.preference.ListPreference;
|
2017-11-18 20:04:59 +01:00
|
|
|
import android.text.TextUtils;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.util.AttributeSet;
|
|
|
|
|
2017-09-15 19:56:10 +02:00
|
|
|
import net.gsantner.opoc.util.ContextUtils;
|
|
|
|
|
2017-09-09 17:09:04 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Locale;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A {@link android.preference.ListPreference} that displays a list of languages to select from
|
|
|
|
*/
|
2017-09-15 19:56:10 +02:00
|
|
|
@SuppressWarnings({"unused", "SpellCheckingInspection", "WeakerAccess"})
|
2017-09-09 17:09:04 +02:00
|
|
|
public class LanguagePreference extends ListPreference {
|
2017-09-15 19:56:10 +02:00
|
|
|
private static final String SYSTEM_LANGUAGE_CODE = "";
|
|
|
|
|
|
|
|
// The language of res/values/ -> (usually English)
|
2018-03-02 15:56:14 +01:00
|
|
|
public String _systemLanguageName = "System";
|
2017-10-28 09:56:05 +02:00
|
|
|
public String _defaultLanguageCode = "en";
|
2017-09-15 19:56:10 +02:00
|
|
|
|
2017-09-09 17:09:04 +02:00
|
|
|
public LanguagePreference(Context context) {
|
|
|
|
super(context);
|
2017-10-28 09:56:05 +02:00
|
|
|
loadLangs(context, null);
|
2017-09-09 17:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public LanguagePreference(Context context, AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
2017-10-28 09:56:05 +02:00
|
|
|
loadLangs(context, attrs);
|
2017-09-09 17:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
|
|
public LanguagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
|
|
super(context, attrs, defStyleAttr);
|
2017-10-28 09:56:05 +02:00
|
|
|
loadLangs(context, attrs);
|
2017-09-09 17:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
|
|
public LanguagePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
|
|
|
super(context, attrs, defStyleAttr, defStyleRes);
|
2017-10-28 09:56:05 +02:00
|
|
|
loadLangs(context, attrs);
|
2017-09-09 17:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2018-03-02 15:56:14 +01:00
|
|
|
public boolean callChangeListener(Object newValue) {
|
2017-09-09 17:09:04 +02:00
|
|
|
if (newValue instanceof String) {
|
|
|
|
// Does not apply to existing UI, use recreate()
|
|
|
|
new ContextUtils(getContext()).setAppLanguage((String) newValue);
|
|
|
|
}
|
|
|
|
return super.callChangeListener(newValue);
|
|
|
|
}
|
|
|
|
|
2017-10-28 09:56:05 +02:00
|
|
|
|
|
|
|
private void loadLangs(Context context) {
|
|
|
|
loadLangs(context, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void loadLangs(Context context, @Nullable AttributeSet attrs) {
|
2017-09-15 19:56:10 +02:00
|
|
|
setDefaultValue(SYSTEM_LANGUAGE_CODE);
|
|
|
|
|
2017-09-09 17:09:04 +02:00
|
|
|
// Fetch readable details
|
2017-09-15 19:56:10 +02:00
|
|
|
ContextUtils contextUtils = new ContextUtils(context);
|
2017-09-09 17:09:04 +02:00
|
|
|
List<String> languages = new ArrayList<>();
|
2017-09-15 19:56:10 +02:00
|
|
|
Object bcof = contextUtils.getBuildConfigValue("APPLICATION_LANGUAGES");
|
2017-09-09 17:09:04 +02:00
|
|
|
if (bcof instanceof String[]) {
|
|
|
|
for (String langId : (String[]) bcof) {
|
2017-09-15 19:56:10 +02:00
|
|
|
Locale locale = contextUtils.getLocaleByAndroidCode(langId);
|
2018-03-02 15:56:14 +01:00
|
|
|
languages.add(summarizeLocale(locale, langId) + ";" + langId);
|
2017-09-09 17:09:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort languages naturally
|
|
|
|
Collections.sort(languages);
|
|
|
|
|
|
|
|
// Show in UI
|
|
|
|
String[] entries = new String[languages.size() + 2];
|
|
|
|
String[] entryval = new String[languages.size() + 2];
|
|
|
|
for (int i = 0; i < languages.size(); i++) {
|
|
|
|
entries[i + 2] = languages.get(i).split(";")[0];
|
|
|
|
entryval[i + 2] = languages.get(i).split(";")[1];
|
|
|
|
}
|
2017-09-15 19:56:10 +02:00
|
|
|
entryval[0] = SYSTEM_LANGUAGE_CODE;
|
2018-03-02 15:56:14 +01:00
|
|
|
entries[0] = _systemLanguageName + " » " + summarizeLocale(context.getResources().getConfiguration().locale, "");
|
2017-10-28 09:56:05 +02:00
|
|
|
entryval[1] = _defaultLanguageCode;
|
2018-03-02 15:56:14 +01:00
|
|
|
entries[1] = summarizeLocale(contextUtils.getLocaleByAndroidCode(_defaultLanguageCode), _defaultLanguageCode);
|
2017-09-09 17:09:04 +02:00
|
|
|
|
|
|
|
setEntries(entries);
|
|
|
|
setEntryValues(entryval);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Concat english and localized language name
|
|
|
|
// Append country if country specific (e.g. Portuguese Brazil)
|
2018-03-02 15:56:14 +01:00
|
|
|
private String summarizeLocale(final Locale locale, final String localeAndroidCode) {
|
2017-09-09 17:09:04 +02:00
|
|
|
String country = locale.getDisplayCountry(locale);
|
|
|
|
String language = locale.getDisplayLanguage(locale);
|
2018-03-02 15:56:14 +01:00
|
|
|
String ret = locale.getDisplayLanguage(Locale.ENGLISH)
|
2017-10-31 14:18:52 +01:00
|
|
|
+ " (" + language.substring(0, 1).toUpperCase(Locale.getDefault()) + language.substring(1)
|
|
|
|
+ ((!country.isEmpty() && !country.toLowerCase(Locale.getDefault()).equals(language.toLowerCase(Locale.getDefault()))) ? (", " + country) : "")
|
2017-09-09 17:09:04 +02:00
|
|
|
+ ")";
|
2018-03-02 15:56:14 +01:00
|
|
|
|
|
|
|
if (localeAndroidCode.equals("zh-rCN")) {
|
|
|
|
ret = ret.substring(0, ret.indexOf(" ") + 1) + "Simplified" + ret.substring(ret.indexOf(" "));
|
|
|
|
} else if (localeAndroidCode.equals("zh-rTW")) {
|
|
|
|
ret = ret.substring(0, ret.indexOf(" ") + 1) + "Traditional" + ret.substring(ret.indexOf(" "));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2017-09-09 17:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add current language to summary
|
|
|
|
@Override
|
|
|
|
public CharSequence getSummary() {
|
|
|
|
Locale locale = new ContextUtils(getContext()).getLocaleByAndroidCode(getValue());
|
2017-11-18 20:04:59 +01:00
|
|
|
String prefix = TextUtils.isEmpty(super.getSummary())
|
|
|
|
? "" : super.getSummary() + "\n\n";
|
2018-03-02 15:56:14 +01:00
|
|
|
return prefix + summarizeLocale(locale, getValue());
|
2017-09-09 17:09:04 +02:00
|
|
|
}
|
2017-10-28 09:56:05 +02:00
|
|
|
|
|
|
|
public String getSystemLanguageName() {
|
|
|
|
return _systemLanguageName;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setSystemLanguageName(String systemLanguageName) {
|
|
|
|
_systemLanguageName = systemLanguageName;
|
|
|
|
loadLangs(getContext());
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getDefaultLanguageCode() {
|
|
|
|
return _defaultLanguageCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setDefaultLanguageCode(String defaultLanguageCode) {
|
|
|
|
_defaultLanguageCode = defaultLanguageCode;
|
|
|
|
loadLangs(getContext());
|
|
|
|
}
|
2018-03-02 15:56:14 +01:00
|
|
|
}
|