Skip to content

Commit 68b82c1

Browse files
committed
Add in-app language selection support.
1 parent 4977092 commit 68b82c1

7 files changed

Lines changed: 143 additions & 10 deletions

File tree

res/values/arrays.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,52 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33

4+
<string-array name="language_entries">
5+
<item>@string/preferences__default</item>
6+
<item>English</item>
7+
<item>Arabic العربية</item>
8+
<item>Burmese မြန်မာစာ</item>
9+
<item>Chinese 中国的</item>
10+
<item>Deutsch</item>
11+
<item>Español</item>
12+
<item>Français</item>
13+
<item>Italiano</item>
14+
<item>Japanese 日本人</item>
15+
<item>Magyar</item>
16+
<item>Nederlands</item>
17+
<item>Norsk</item>
18+
<item>Português</item>
19+
<item>Português (Brasil)</item>
20+
<item>Russian Pусский</item>
21+
<item>Slovenščina</item>
22+
<item>Slovenský</item>
23+
<item>Svenska</item>
24+
<item>Tibetan བོད་སྐད།</item>
25+
</string-array>
26+
27+
<string-array name="language_values">
28+
<item>zz</item>
29+
<item>en</item>
30+
<item>ar</item>
31+
<item>my</item>
32+
<item>zh_CN</item>
33+
<item>de</item>
34+
<item>es</item>
35+
<item>fr</item>
36+
<item>it</item>
37+
<item>ja</item>
38+
<item>he</item>
39+
<item>nl</item>
40+
<item>no</item>
41+
<item>pt</item>
42+
<item>pt_BR</item>
43+
<item>ru</item>
44+
<item>sl</item>
45+
<item>sk</item>
46+
<item>sv</item>
47+
<item>bo</item>
48+
</string-array>
49+
450
<string-array name="minutes_hours">
551
<item>@string/preferences__minutes</item>
652
<item>@string/preferences__hours</item>

res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@
445445
<string name="preferences__dark_theme">Dark Theme</string>
446446
<string name="preferences__appearance">Appearance</string>
447447
<string name="preferences__theme">Theme</string>
448+
<string name="preferences__default">Default</string>
448449

449450
<!-- **************************************** -->
450451
<!-- menus -->
@@ -511,6 +512,7 @@
511512

512513
<!-- verify_keys -->
513514
<string name="verify_keys__menu_verified">Verified</string>
515+
<string name="preferences__language">Language</string>
514516
<!-- EOF -->
515517

516518
</resources>

res/xml/preferences.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@
7878
android:entryValues="@array/pref_theme_values"
7979
android:defaultValue="light">
8080
</ListPreference>
81+
82+
<ListPreference android:key="pref_language"
83+
android:title="@string/preferences__language"
84+
android:entries="@array/language_entries"
85+
android:entryValues="@array/language_values"
86+
android:defaultValue="zz"/>
8187
</PreferenceCategory>
8288

8389
<PreferenceCategory android:title="@string/preferences__storage">

src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,22 @@
2525
import android.os.Bundle;
2626
import android.preference.EditTextPreference;
2727
import android.preference.Preference;
28-
import android.preference.PreferenceScreen;
2928
import android.preference.PreferenceManager;
29+
import android.preference.PreferenceScreen;
3030
import android.provider.ContactsContract;
3131
import android.util.Log;
3232
import android.widget.Toast;
3333

34+
import com.actionbarsherlock.view.MenuItem;
3435
import org.thoughtcrime.securesms.contacts.ContactAccessor;
3536
import org.thoughtcrime.securesms.contacts.ContactIdentityManager;
36-
import org.thoughtcrime.securesms.crypto.IdentityKey;
3737
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
3838
import org.thoughtcrime.securesms.crypto.MasterSecret;
3939
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
40-
import org.thoughtcrime.securesms.util.Dialogs;
40+
import org.thoughtcrime.securesms.util.DynamicLanguage;
4141
import org.thoughtcrime.securesms.util.DynamicTheme;
4242
import org.thoughtcrime.securesms.util.MemoryCleaner;
4343
import org.thoughtcrime.securesms.util.Trimmer;
44-
import org.thoughtcrime.securesms.util.Util;
45-
46-
import com.actionbarsherlock.view.MenuItem;
47-
48-
import java.util.List;
4944

5045
/**
5146
* The Activity for application preference display and management.
@@ -72,6 +67,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
7267
public static final String PASSPHRASE_TIMEOUT_PREF = "pref_timeout_passphrase";
7368
public static final String AUTO_KEY_EXCHANGE_PREF = "pref_auto_complete_key_exchange";
7469
public static final String THEME_PREF = "pref_theme";
70+
public static final String LANGUAGE_PREF = "pref_language";
7571
public static final String ENTER_SENDS_PREF = "pref_enter_sends";
7672
public static final String ENTER_PRESENT_PREF = "pref_enter_key";
7773

@@ -98,11 +94,13 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
9894
public static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
9995
public static final String GCM_PASSWORD_PREF = "pref_gcm_password";
10096

101-
private final DynamicTheme dynamicTheme = new DynamicTheme();
97+
private final DynamicTheme dynamicTheme = new DynamicTheme();
98+
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
10299

103100
@Override
104101
protected void onCreate(Bundle icicle) {
105102
dynamicTheme.onCreate(this);
103+
dynamicLanguage.onCreate(this);
106104
super.onCreate(icicle);
107105

108106
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@@ -134,6 +132,7 @@ public void onStart() {
134132
public void onResume() {
135133
super.onResume();
136134
dynamicTheme.onResume(this);
135+
dynamicLanguage.onResume(this);
137136
}
138137

139138
@Override
@@ -233,6 +232,8 @@ private void handleIdentitySelection(Intent data) {
233232
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
234233
if (key.equals(THEME_PREF)) {
235234
dynamicTheme.onResume(this);
235+
} else if (key.equals(LANGUAGE_PREF)) {
236+
dynamicLanguage.onResume(this);
236237
}
237238
}
238239

src/org/thoughtcrime/securesms/ConversationActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
8181
import org.thoughtcrime.securesms.util.BitmapDecodingException;
8282
import org.thoughtcrime.securesms.util.CharacterCalculator;
83+
import org.thoughtcrime.securesms.util.DynamicLanguage;
8384
import org.thoughtcrime.securesms.util.DynamicTheme;
8485
import org.thoughtcrime.securesms.util.EncryptedCharacterCalculator;
8586
import org.thoughtcrime.securesms.util.InvalidMessageException;
@@ -138,10 +139,12 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
138139

139140
private CharacterCalculator characterCalculator = new CharacterCalculator();
140141
private DynamicTheme dynamicTheme = new DynamicTheme();
142+
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
141143

142144
@Override
143145
protected void onCreate(Bundle state) {
144146
dynamicTheme.onCreate(this);
147+
dynamicLanguage.onCreate(this);
145148
super.onCreate(state);
146149

147150
setContentView(R.layout.conversation_activity);
@@ -165,6 +168,7 @@ protected void onStart() {
165168
protected void onResume() {
166169
super.onResume();
167170
dynamicTheme.onResume(this);
171+
dynamicLanguage.onResume(this);
168172

169173
initializeSecurity();
170174
initializeTitleBar();

src/org/thoughtcrime/securesms/ConversationListActivity.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.thoughtcrime.securesms.recipients.Recipients;
2929
import org.thoughtcrime.securesms.service.KeyCachingService;
3030
import org.thoughtcrime.securesms.service.SendReceiveService;
31+
import org.thoughtcrime.securesms.util.DynamicLanguage;
3132
import org.thoughtcrime.securesms.util.DynamicTheme;
3233
import org.thoughtcrime.securesms.util.MemoryCleaner;
3334

@@ -39,7 +40,8 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
3940
implements ConversationListFragment.ConversationSelectedListener,
4041
ListView.OnItemClickListener
4142
{
42-
private final DynamicTheme dynamicTheme = new DynamicTheme();
43+
private final DynamicTheme dynamicTheme = new DynamicTheme ();
44+
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
4345

4446
private ConversationListFragment fragment;
4547
private MasterSecret masterSecret;
@@ -49,6 +51,7 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
4951
@Override
5052
public void onCreate(Bundle icicle) {
5153
dynamicTheme.onCreate(this);
54+
dynamicLanguage.onCreate(this);
5255
super.onCreate(icicle);
5356

5457
setContentView(R.layout.conversation_list_activity);
@@ -64,6 +67,7 @@ public void onCreate(Bundle icicle) {
6467
public void onResume() {
6568
super.onResume();
6669
dynamicTheme.onResume(this);
70+
dynamicLanguage.onResume(this);
6771
}
6872

6973
@Override
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.thoughtcrime.securesms.util;
2+
3+
import android.app.Activity;
4+
import android.content.Intent;
5+
import android.content.res.Configuration;
6+
import android.os.Build;
7+
import android.preference.PreferenceManager;
8+
import android.util.Log;
9+
10+
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
11+
12+
import java.util.Locale;
13+
14+
public class DynamicLanguage {
15+
16+
private static final String DEFAULT = "zz";
17+
18+
private Locale currentLocale;
19+
20+
public void onCreate(Activity activity) {
21+
currentLocale = getSelectedLocale(activity);
22+
setActivityLocale(activity, currentLocale);
23+
}
24+
25+
public void onResume(Activity activity) {
26+
if (!currentLocale.getLanguage().equalsIgnoreCase(getSelectedLocale(activity).getLanguage())) {
27+
Intent intent = activity.getIntent();
28+
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
29+
30+
activity.startActivity(intent);
31+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
32+
OverridePendingTransition.invoke(activity);
33+
}
34+
35+
activity.finish();
36+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
37+
OverridePendingTransition.invoke(activity);
38+
}
39+
}
40+
}
41+
42+
private static void setActivityLocale(Activity activity, Locale selectedLocale) {
43+
Configuration configuration = activity.getResources().getConfiguration();
44+
45+
if (!configuration.locale.getLanguage().equalsIgnoreCase(selectedLocale.getLanguage())) {
46+
configuration.locale = selectedLocale;
47+
activity.getResources().updateConfiguration(configuration,
48+
activity.getResources().getDisplayMetrics());
49+
}
50+
}
51+
52+
private static Locale getActivityLocale(Activity activity) {
53+
return activity.getResources().getConfiguration().locale;
54+
}
55+
56+
private static Locale getSelectedLocale(Activity activity) {
57+
String language = PreferenceManager.getDefaultSharedPreferences(activity)
58+
.getString(ApplicationPreferencesActivity.LANGUAGE_PREF, DEFAULT);
59+
60+
if (language.equals(DEFAULT)) return Locale.getDefault();
61+
else return new Locale(language);
62+
}
63+
64+
private static final class OverridePendingTransition {
65+
static void invoke(Activity activity) {
66+
activity.overridePendingTransition(0, 0);
67+
}
68+
}
69+
70+
}

0 commit comments

Comments
 (0)