parent
7f261b339a
commit
019964387a
@ -13,7 +13,6 @@ before_script:
|
||||
test:
|
||||
script:
|
||||
- cd app
|
||||
- ./tools/langs-list-check.py
|
||||
- ./tools/check-string-format.py
|
||||
- cd ..
|
||||
- ./gradlew assemble -PdisablePreDex
|
||||
|
@ -227,6 +227,7 @@ public class FDroidApp extends Application {
|
||||
Preferences.setup(this);
|
||||
curTheme = Preferences.get().getTheme();
|
||||
Preferences.get().configureProxy();
|
||||
Languages.setup(getClass(), R.string.pref_language_default);
|
||||
|
||||
InstalledAppProviderService.compareToPackageManager(this);
|
||||
AppUpdateStatusService.scanDownloadedApks(this);
|
||||
|
277
app/src/main/java/org/fdroid/fdroid/Languages.java
Normal file
277
app/src/main/java/org/fdroid/fdroid/Languages.java
Normal file
@ -0,0 +1,277 @@
|
||||
package org.fdroid.fdroid;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.res.AssetManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public final class Languages {
|
||||
public static final String TAG = "Languages";
|
||||
|
||||
public static final String USE_SYSTEM_DEFAULT = "";
|
||||
|
||||
private static final Locale DEFAULT_LOCALE;
|
||||
private static final Locale TIBETAN = new Locale("bo");
|
||||
private static final String DEFAULT_STRING = "System Default";
|
||||
|
||||
private static Locale locale;
|
||||
private static Languages singleton;
|
||||
private static Class<?> clazz;
|
||||
private static int resId;
|
||||
private static Map<String, String> tmpMap = new TreeMap<>();
|
||||
private static Map<String, String> nameMap;
|
||||
|
||||
static {
|
||||
DEFAULT_LOCALE = Locale.getDefault();
|
||||
}
|
||||
|
||||
private Languages(Activity activity) {
|
||||
AssetManager assets = activity.getAssets();
|
||||
Configuration config = activity.getResources().getConfiguration();
|
||||
// Resources() requires DisplayMetrics, but they are only needed for drawables
|
||||
DisplayMetrics ignored = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(ignored);
|
||||
Resources resources;
|
||||
Set<Locale> localeSet = new LinkedHashSet<>();
|
||||
for (Locale locale : LOCALES_TO_TEST) {
|
||||
config.locale = locale;
|
||||
resources = new Resources(assets, ignored, config);
|
||||
if (!TextUtils.equals(DEFAULT_STRING, resources.getString(resId))
|
||||
|| locale.equals(Locale.ENGLISH)) {
|
||||
localeSet.add(locale);
|
||||
}
|
||||
}
|
||||
for (Locale locale : localeSet) {
|
||||
if (locale.equals(TIBETAN)) {
|
||||
// include English name for devices without Tibetan font support
|
||||
tmpMap.put(TIBETAN.getLanguage(), "Tibetan བོད་སྐད།"); // Tibetan
|
||||
} else if (locale.equals(Locale.SIMPLIFIED_CHINESE)) {
|
||||
tmpMap.put(Locale.SIMPLIFIED_CHINESE.toString(), "中文 (中国)"); // Chinese (China)
|
||||
} else if (locale.equals(Locale.TRADITIONAL_CHINESE)) {
|
||||
tmpMap.put(Locale.TRADITIONAL_CHINESE.toString(), "中文 (台灣)"); // Chinese (Taiwan)
|
||||
} else {
|
||||
tmpMap.put(locale.getLanguage(), locale.getDisplayLanguage(locale));
|
||||
}
|
||||
}
|
||||
|
||||
/* SYSTEM_DEFAULT is a fake one for displaying in a chooser menu. */
|
||||
localeSet.add(null);
|
||||
tmpMap.put(USE_SYSTEM_DEFAULT, activity.getString(resId));
|
||||
nameMap = Collections.unmodifiableMap(tmpMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of {@link Languages} to work with, providing the
|
||||
* {@link Activity} that is will be working as part of, as well as the
|
||||
* {@code resId} that has the exact string "Use System Default",
|
||||
* i.e. {@code R.string.use_system_default}.
|
||||
* <p/>
|
||||
* That string resource {@code resId} is also used to find the supported
|
||||
* translations: if an included translation has a translated string that
|
||||
* matches that {@code resId}, then that language will be included as a
|
||||
* supported language.
|
||||
*
|
||||
* @param clazz the {@link Class} of the default {@code Activity},
|
||||
* usually the main {@code Activity} from where the
|
||||
* Settings is launched from.
|
||||
* @param resId the string resource ID to for the string "System Default",
|
||||
* e.g. {@code R.string.pref_language_default}
|
||||
*/
|
||||
public static void setup(Class<?> clazz, int resId) {
|
||||
if (Languages.clazz == null) {
|
||||
Languages.clazz = clazz;
|
||||
Languages.resId = resId;
|
||||
} else {
|
||||
throw new RuntimeException("Languages singleton was already initialized, duplicate call to Languages.setup()!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activity the {@link Activity} this is working as part of
|
||||
* @return the singleton to work with
|
||||
*/
|
||||
public static Languages get(Activity activity) {
|
||||
if (singleton == null) {
|
||||
singleton = new Languages(activity);
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@TargetApi(17)
|
||||
public static void setLanguage(final ContextWrapper contextWrapper, String language, boolean refresh) {
|
||||
if (locale != null && TextUtils.equals(locale.getLanguage(), language) && (!refresh)) {
|
||||
return; // already configured
|
||||
} else if (language == null || language.equals(USE_SYSTEM_DEFAULT)) {
|
||||
locale = DEFAULT_LOCALE;
|
||||
} else {
|
||||
/* handle locales with the country in it, i.e. zh_CN, zh_TW, etc */
|
||||
String[] localeSplit = language.split("_");
|
||||
if (localeSplit.length > 1) {
|
||||
locale = new Locale(localeSplit[0], localeSplit[1]);
|
||||
} else {
|
||||
locale = new Locale(language);
|
||||
}
|
||||
}
|
||||
|
||||
final Resources resources = contextWrapper.getBaseContext().getResources();
|
||||
Configuration config = resources.getConfiguration();
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
config.setLocale(locale);
|
||||
} else {
|
||||
config.locale = locale;
|
||||
}
|
||||
resources.updateConfiguration(config, resources.getDisplayMetrics());
|
||||
Locale.setDefault(locale);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Force reload the {@link Activity to make language changes take effect.}
|
||||
*
|
||||
* @param activity the {@code Activity} to force reload
|
||||
*/
|
||||
public static void forceChangeLanguage(Activity activity) {
|
||||
Intent intent = activity.getIntent();
|
||||
if (intent == null) { // when launched as LAUNCHER
|
||||
return;
|
||||
}
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
activity.finish();
|
||||
activity.overridePendingTransition(0, 0);
|
||||
activity.startActivity(intent);
|
||||
activity.overridePendingTransition(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the language based on the locale.
|
||||
*/
|
||||
public String getName(String locale) {
|
||||
String ret = nameMap.get(locale);
|
||||
// if no match, try to return a more general name (i.e. English for en_IN)
|
||||
if (ret == null && locale.contains("_")) {
|
||||
ret = nameMap.get(locale.split("_")[0]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an array of the names of all the supported languages, sorted to
|
||||
* match what is returned by {@link Languages#getSupportedLocales()}.
|
||||
*/
|
||||
public String[] getAllNames() {
|
||||
return nameMap.values().toArray(new String[nameMap.size()]);
|
||||
}
|
||||
|
||||
public int getPosition(Locale locale) {
|
||||
String localeName = locale.getLanguage();
|
||||
int i = 0;
|
||||
for (String key : nameMap.keySet()) {
|
||||
if (TextUtils.equals(key, localeName)) {
|
||||
return i;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return sorted list of supported locales.
|
||||
*/
|
||||
public String[] getSupportedLocales() {
|
||||
Set<String> keys = nameMap.keySet();
|
||||
return keys.toArray(new String[keys.size()]);
|
||||
}
|
||||
|
||||
private static final Locale[] LOCALES_TO_TEST = {
|
||||
Locale.ENGLISH,
|
||||
Locale.FRENCH,
|
||||
Locale.GERMAN,
|
||||
Locale.ITALIAN,
|
||||
Locale.JAPANESE,
|
||||
Locale.KOREAN,
|
||||
Locale.SIMPLIFIED_CHINESE,
|
||||
Locale.TRADITIONAL_CHINESE,
|
||||
TIBETAN,
|
||||
new Locale("af"),
|
||||
new Locale("am"),
|
||||
new Locale("ar"),
|
||||
new Locale("az"),
|
||||
new Locale("be"),
|
||||
new Locale("bg"),
|
||||
new Locale("bn"),
|
||||
new Locale("ca"),
|
||||
new Locale("cs"),
|
||||
new Locale("da"),
|
||||
new Locale("el"),
|
||||
new Locale("es"),
|
||||
new Locale("et"),
|
||||
new Locale("eu"),
|
||||
new Locale("fa"),
|
||||
new Locale("fi"),
|
||||
new Locale("gl"),
|
||||
new Locale("hi"),
|
||||
new Locale("hr"),
|
||||
new Locale("hu"),
|
||||
new Locale("hy"),
|
||||
new Locale("in"),
|
||||
new Locale("hy"),
|
||||
new Locale("in"),
|
||||
new Locale("is"),
|
||||
new Locale("it"),
|
||||
new Locale("iw"),
|
||||
new Locale("ka"),
|
||||
new Locale("kk"),
|
||||
new Locale("km"),
|
||||
new Locale("kn"),
|
||||
new Locale("ky"),
|
||||
new Locale("lo"),
|
||||
new Locale("lt"),
|
||||
new Locale("lv"),
|
||||
new Locale("mk"),
|
||||
new Locale("ml"),
|
||||
new Locale("mn"),
|
||||
new Locale("mr"),
|
||||
new Locale("ms"),
|
||||
new Locale("my"),
|
||||
new Locale("nb"),
|
||||
new Locale("ne"),
|
||||
new Locale("nl"),
|
||||
new Locale("pl"),
|
||||
new Locale("pt"),
|
||||
new Locale("rm"),
|
||||
new Locale("ro"),
|
||||
new Locale("ru"),
|
||||
new Locale("si"),
|
||||
new Locale("sk"),
|
||||
new Locale("sl"),
|
||||
new Locale("sn"),
|
||||
new Locale("sr"),
|
||||
new Locale("sv"),
|
||||
new Locale("sw"),
|
||||
new Locale("ta"),
|
||||
new Locale("te"),
|
||||
new Locale("th"),
|
||||
new Locale("tl"),
|
||||
new Locale("tr"),
|
||||
new Locale("uk"),
|
||||
new Locale("ur"),
|
||||
new Locale("uz"),
|
||||
new Locale("vi"),
|
||||
new Locale("zu"),
|
||||
};
|
||||
|
||||
}
|
@ -12,19 +12,19 @@ import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.support.v4.preference.PreferenceFragment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.geecko.QuickLyric.view.AppCompatListPreference;
|
||||
import info.guardianproject.netcipher.NetCipher;
|
||||
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||
import org.fdroid.fdroid.AppDetails2;
|
||||
import org.fdroid.fdroid.CleanCacheService;
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
import org.fdroid.fdroid.Languages;
|
||||
import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.installer.InstallHistoryService;
|
||||
import org.fdroid.fdroid.installer.PrivilegedInstaller;
|
||||
|
||||
import info.guardianproject.netcipher.NetCipher;
|
||||
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||
|
||||
public class PreferencesFragment extends PreferenceFragment
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@ -62,6 +62,12 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
enableProxyCheckPref = (CheckBoxPreference) findPreference(Preferences.PREF_ENABLE_PROXY);
|
||||
updateAutoDownloadPref = findPreference(Preferences.PREF_AUTO_DOWNLOAD_INSTALL_UPDATES);
|
||||
updatePrivilegedExtensionPref = findPreference(Preferences.PREF_UNINSTALL_PRIVILEGED_APP);
|
||||
|
||||
AppCompatListPreference languagePref = (AppCompatListPreference) findPreference(Preferences.PREF_LANGUAGE);
|
||||
Languages languages = Languages.get(getActivity());
|
||||
languagePref.setDefaultValue(Languages.USE_SYSTEM_DEFAULT);
|
||||
languagePref.setEntries(languages.getAllNames());
|
||||
languagePref.setEntryValues(languages.getSupportedLocales());
|
||||
}
|
||||
|
||||
private void checkSummary(String key, int resId) {
|
||||
|
@ -44,126 +44,4 @@
|
||||
<item>night</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="languageValues">
|
||||
<item></item>
|
||||
<item>en</item>
|
||||
<item>af</item>
|
||||
<item>ar</item>
|
||||
<item>ast</item>
|
||||
<item>be</item>
|
||||
<item>bg</item>
|
||||
<item>ca</item>
|
||||
<item>cs</item>
|
||||
<item>da</item>
|
||||
<item>de</item>
|
||||
<item>el</item>
|
||||
<item>eo</item>
|
||||
<item>es</item>
|
||||
<item>et</item>
|
||||
<item>eu</item>
|
||||
<item>fa</item>
|
||||
<item>fi</item>
|
||||
<item>fr</item>
|
||||
<item>gl</item>
|
||||
<item>he</item>
|
||||
<item>hi</item>
|
||||
<item>hr</item>
|
||||
<item>hu</item>
|
||||
<item>hy</item>
|
||||
<item>id</item>
|
||||
<item>is</item>
|
||||
<item>it</item>
|
||||
<item>ja</item>
|
||||
<item>ko</item>
|
||||
<item>lt</item>
|
||||
<item>lv</item>
|
||||
<item>mk</item>
|
||||
<item>my</item>
|
||||
<item>nb</item>
|
||||
<item>nl</item>
|
||||
<item>pl</item>
|
||||
<item>pt-rBR</item>
|
||||
<item>pt-rPT</item>
|
||||
<item>ro</item>
|
||||
<item>ru</item>
|
||||
<item>sc</item>
|
||||
<item>sk</item>
|
||||
<item>sl</item>
|
||||
<item>sn</item>
|
||||
<item>sq</item>
|
||||
<item>sr</item>
|
||||
<item>sv</item>
|
||||
<item>ta</item>
|
||||
<item>th</item>
|
||||
<item>tr</item>
|
||||
<item>ug</item>
|
||||
<item>uk</item>
|
||||
<item>ur</item>
|
||||
<item>vi</item>
|
||||
<item>zh-rCN</item>
|
||||
<item>zh-rHK</item>
|
||||
<item>zh-rTW</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="languageNames">
|
||||
<item>@string/pref_language_default</item>
|
||||
<item>English</item>
|
||||
<item>Afrikaans</item>
|
||||
<item>ﺎﻠﻋﺮﺒﻳﺓ</item>
|
||||
<item>Asturian</item>
|
||||
<item>белорусский</item>
|
||||
<item>Български</item>
|
||||
<item>Català</item>
|
||||
<item>Čeština</item>
|
||||
<item>Dansk</item>
|
||||
<item>Deutsch</item>
|
||||
<item>Ελληνικά</item>
|
||||
<item>Esperanto</item>
|
||||
<item>Español</item>
|
||||
<item>Eesti</item>
|
||||
<item>Euskara</item>
|
||||
<item>ﻑﺍﺮﺳی</item>
|
||||
<item>Suomi</item>
|
||||
<item>Français</item>
|
||||
<item>Galego</item>
|
||||
<item>עברית</item>
|
||||
<item>हिन्दी</item>
|
||||
<item>Hrvatski</item>
|
||||
<item>Magyar</item>
|
||||
<item>հայերեն</item>
|
||||
<item>Bahasa Indonesia</item>
|
||||
<item>Íslenska</item>
|
||||
<item>Italiano</item>
|
||||
<item>日本語</item>
|
||||
<item>한국어</item>
|
||||
<item>Lietuvių</item>
|
||||
<item>Latviešu</item>
|
||||
<item>македонски</item>
|
||||
<item>မြန်မာစာ</item>
|
||||
<item>Norsk bokmål</item>
|
||||
<item>Nederlands</item>
|
||||
<item>Polski</item>
|
||||
<item>Português (Brasil)</item>
|
||||
<item>Português (Portugal)</item>
|
||||
<item>Română</item>
|
||||
<item>Русский</item>
|
||||
<item>Sardinian</item>
|
||||
<item>Slovenčina</item>
|
||||
<item>Slovenščina</item>
|
||||
<item>ChiSona</item>
|
||||
<item>Shqip</item>
|
||||
<item>Српски</item>
|
||||
<item>Svenska</item>
|
||||
<item>தமிழ்</item>
|
||||
<item>ไทย</item>
|
||||
<item>Türkçe</item>
|
||||
<item>ﺉۇﻲﻏۇﺭچە</item>
|
||||
<item>Українська</item>
|
||||
<item>اردو</item>
|
||||
<item>Tiếng Việt</item>
|
||||
<item>中文 (中国)</item>
|
||||
<item>中文 (香港)</item>
|
||||
<item>中文 (台湾)</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
@ -43,10 +43,7 @@
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/display">
|
||||
<com.geecko.QuickLyric.view.AppCompatListPreference android:title="@string/pref_language"
|
||||
android:key="language"
|
||||
android:defaultValue=""
|
||||
android:entries="@array/languageNames"
|
||||
android:entryValues="@array/languageValues" />
|
||||
android:key="language"/>
|
||||
<com.geecko.QuickLyric.view.AppCompatListPreference android:title="@string/theme"
|
||||
android:key="theme"
|
||||
android:defaultValue="light"
|
||||
|
@ -1,63 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# List supported languages missing from the preference array
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
from xml.etree import ElementTree
|
||||
|
||||
prefs = set([''])
|
||||
trans = set(['', 'en'])
|
||||
|
||||
donottranslate = os.path.join('src', 'main', 'res', 'values', 'donottranslate.xml')
|
||||
|
||||
for e in ElementTree.parse(donottranslate).getroot().findall('.//string-array'):
|
||||
if e.attrib['name'] != 'languageValues':
|
||||
continue
|
||||
for i in e.findall('.//item'):
|
||||
lang = i.text
|
||||
if not lang:
|
||||
continue
|
||||
prefs.add(lang)
|
||||
|
||||
for d in glob.glob(os.path.join('src', 'main', 'res', 'values-*')):
|
||||
lang = d[len(os.path.join('src', 'main', 'res', 'values-')):]
|
||||
if not lang:
|
||||
continue
|
||||
if re.match('^sw[0-9]+dp|v[0-9]+$', lang):
|
||||
continue
|
||||
if lang == 'ldrtl':
|
||||
continue
|
||||
if os.path.islink(d):
|
||||
continue
|
||||
trans.add(lang)
|
||||
|
||||
print("In the settings array: %s" % ' '.join(sorted(prefs)))
|
||||
print("Actually translated: %s" % ' '.join(sorted(trans)))
|
||||
|
||||
missing = []
|
||||
for lang in trans:
|
||||
if lang not in prefs:
|
||||
missing.append(lang)
|
||||
|
||||
if missing:
|
||||
print("Missing:")
|
||||
for lang in missing:
|
||||
print(" %s" % lang)
|
||||
|
||||
extra = []
|
||||
for lang in prefs:
|
||||
if lang not in trans:
|
||||
extra.append(lang)
|
||||
|
||||
if extra:
|
||||
print("Extra:")
|
||||
for lang in extra:
|
||||
print(" %s" % lang)
|
||||
|
||||
if not missing and not extra:
|
||||
print("All good.")
|
||||
else:
|
||||
sys.exit(1)
|
Loading…
x
Reference in New Issue
Block a user