diff --git a/xwords4/android/XWords4/jni/Android.mk b/xwords4/android/XWords4/jni/Android.mk
index 057f89440..25e123332 100644
--- a/xwords4/android/XWords4/jni/Android.mk
+++ b/xwords4/android/XWords4/jni/Android.mk
@@ -10,7 +10,7 @@ local_C_INCLUDES+= \
local_LDLIBS += -llog
-# local_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING
+local_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING
local_DEFINES += \
$(local_DEBUG) \
-DXWFEATURE_RELAY \
diff --git a/xwords4/android/XWords4/jni/xwjni.c b/xwords4/android/XWords4/jni/xwjni.c
index 28f3a5f4c..26f4c4f2e 100644
--- a/xwords4/android/XWords4/jni/xwjni.c
+++ b/xwords4/android/XWords4/jni/xwjni.c
@@ -82,6 +82,8 @@ makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
lp->name = copyString( mpool, buf );
getString( env, jlp, "password", buf, VSIZE(buf) );
lp->password = copyString( mpool, buf );
+ getString( env, jlp, "dictName", buf, VSIZE(buf) );
+ lp->dictName = copyString( mpool, buf );
lp->secondsUsed = 0;
@@ -129,6 +131,7 @@ setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
setBool( env, jlp, "isLocal", lp->isLocal );
setString( env, jlp, "name", lp->name );
setString( env, jlp, "password", lp->password );
+ setString( env, jlp, "dictName", lp->dictName );
setInt( env, jlp, "secondsUsed", lp->secondsUsed );
(*env)->DeleteLocalRef( env, jlp );
diff --git a/xwords4/android/XWords4/res/layout/game_config.xml b/xwords4/android/XWords4/res/layout/game_config.xml
index aeb62ceac..b7d0c3dbe 100644
--- a/xwords4/android/XWords4/res/layout/game_config.xml
+++ b/xwords4/android/XWords4/res/layout/game_config.xml
@@ -78,14 +78,14 @@
-
+
+
+
+
Create game
Edit game
Crosswords
- Dictionaries (language/wordcount)
+ Dictionaries (wordcount)
+ Languages (based on installed
+ dictionaries)
+ Game language
Game
%s settings
%s settings (networked)
@@ -164,6 +167,7 @@
Details
Dictionary
+ Dictionary (in %s)
Device role
Connection
Connection (via internet)
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictLangCache.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictLangCache.java
index 45935e866..9b43b03a2 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictLangCache.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictLangCache.java
@@ -24,6 +24,8 @@ import android.content.Context;
import android.content.res.Resources;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Arrays;
import org.eehouse.android.xw4.jni.JNIUtilsImpl;
import org.eehouse.android.xw4.jni.XwJNI;
@@ -33,6 +35,7 @@ public class DictLangCache {
private static final HashMap s_nameToLang =
new HashMap();
private static String[] s_langNames;
+ private static String[] s_langNamesPresent;
public static String annotatedDictName( Context context, String name )
{
@@ -72,7 +75,7 @@ public class DictLangCache {
int count = 0;
String[] dicts = GameUtils.dictList( context );
for ( String dict : dicts ) {
- if ( code == getLangCode( context, dict ) ) {
+ if ( code == getDictLangCode( context, dict ) ) {
++count;
}
}
@@ -94,7 +97,9 @@ public class DictLangCache {
al.add( dict );
}
}
- return al.toArray( new String[al.size()] );
+ String[] result = al.toArray( new String[al.size()] );
+ Arrays.sort( result );
+ return result;
}
public static String[] getHaveLang( Context context, int code )
@@ -113,14 +118,27 @@ public class DictLangCache {
return nameWithCount.substring( 0, indx );
}
- public static int getLangCode( Context context, String name )
+ public static int getDictLangCode( Context context, String dict )
{
- return getInfo( context, name ).langCode;
+ return getInfo( context, dict ).langCode;
+ }
+
+ public static int getLangLangCode( Context context, String lang )
+ {
+ int code = 0;
+ String[] namesArray = getNamesArray( context );
+ for ( int ii = 0; ii < namesArray.length; ++ii ) {
+ if ( namesArray[ii].equals( lang ) ) {
+ code = ii;
+ break;
+ }
+ }
+ return code;
}
public static String getLangName( Context context, String name )
{
- int code = getLangCode( context, name );
+ int code = getDictLangCode( context, name );
return getLangName( context, code );
}
@@ -129,6 +147,16 @@ public class DictLangCache {
s_nameToLang.remove( name );
}
+ public static String[] listLangs( Context context, final String[] names )
+ {
+ HashSet langs = new HashSet();
+ for ( String name:names ) {
+ langs.add( getLangName( context, name ) );
+ }
+ String[] result = new String[langs.size()];
+ return langs.toArray( result );
+ }
+
private static String[] getNamesArray( Context context )
{
if ( null == s_langNames ) {
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java
index 696e1a348..19cca53d2 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java
@@ -26,6 +26,7 @@ import android.net.Uri;
import android.os.Bundle;
import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
@@ -90,11 +91,11 @@ public class GameConfig extends XWActivity
// private Spinner m_roleSpinner;
// private Spinner m_connectSpinner;
private Spinner m_phoniesSpinner;
- private Spinner m_dictSpinner;
+ private Spinner m_langSpinner;
private Spinner m_smartnessSpinner;
- private String[] m_dictItems;
- private String[] m_dicts;
- private int m_browsePosition;
+ private String[] m_langs;
+ // private String[] m_dicts;
+ private int m_langsBrowsePosition;
private LinearLayout m_playerLayout;
private CommsAddrRec m_carOrig;
private CommsAddrRec m_car;
@@ -106,7 +107,7 @@ public class GameConfig extends XWActivity
private String[] m_connStrings;
private static final int[] s_disabledWhenLocked = { R.id.juggle_players
,R.id.add_player
- ,R.id.dict_spinner
+ ,R.id.lang_spinner
,R.id.join_public_room_check
,R.id.room_edit
,R.id.advertise_new_room_check
@@ -297,6 +298,14 @@ public class GameConfig extends XWActivity
Utils.setText( dialog, R.id.player_name_edit, lp.name );
Utils.setText( dialog, R.id.password_edit, lp.password );
+ // Dicts spinner with label
+ String langName = DictLangCache.getLangName( this, m_gi.dictLang );
+ String label = String.format( getString( R.string.dict_lang_labelf ),
+ langName );
+ TextView text = (TextView)dialog.findViewById( R.id.dict_label );
+ text.setText( label );
+ configDictSpinner( dialog, lp );
+
final View localSet = dialog.findViewById( R.id.local_player_set );
CheckBox check = (CheckBox)
@@ -338,6 +347,11 @@ public class GameConfig extends XWActivity
LocalPlayer lp = m_gi.players[m_whichPlayer];
lp.name = Utils.getText( dialog, R.id.player_name_edit );
lp.password = Utils.getText( dialog, R.id.password_edit );
+ Spinner spinner =
+ (Spinner)((Dialog)di).findViewById( R.id.dict_spinner );
+ int position = spinner.getSelectedItemPosition();
+ lp.dictName = DictLangCache.getHaveLang( this, m_gi.dictLang )[position];
+ Utils.logf( "reading name via position %d: %s", position, lp.dictName );
lp.setIsRobot( Utils.getChecked( dialog, R.id.robot_check ) );
lp.isLocal = !Utils.getChecked( dialog, R.id.remote_check );
@@ -376,7 +390,7 @@ public class GameConfig extends XWActivity
m_playButton.setOnClickListener( this );
m_playerLayout = (LinearLayout)findViewById( R.id.player_list );
- m_dictSpinner = (Spinner)findViewById( R.id.dict_spinner );
+ m_langSpinner = (Spinner)findViewById( R.id.lang_spinner );
m_phoniesSpinner = (Spinner)findViewById( R.id.phonies_spinner );
m_smartnessSpinner = (Spinner)findViewById( R.id.smart_robot );
@@ -409,9 +423,9 @@ public class GameConfig extends XWActivity
handleLockedChange();
}
- int curSel = listAvailableDicts( m_giOrig.dictName );
+ int curSel = listAvailableLangs( m_giOrig.dictName );
m_giOrig.dictLang =
- DictLangCache.getLangCode( this,
+ DictLangCache.getDictLangCode( this,
GameUtils.dictList( this )[curSel] );
m_gi = new CurGameInfo( m_giOrig );
@@ -453,8 +467,7 @@ public class GameConfig extends XWActivity
}
loadPlayers();
-
- configDictSpinner();
+ configLangSpinner();
m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() );
@@ -620,62 +633,109 @@ public class GameConfig extends XWActivity
adjustPlayersLabel();
} // loadPlayers
- private int listAvailableDicts( String curDict )
+ private String[] buildListWithBrowse( String[] input )
{
- int curSel = -1;
-
- String[] list = GameUtils.dictList( this );
-
- m_browsePosition = list.length;
- m_dictItems = new String[m_browsePosition+1];
- m_dictItems[m_browsePosition] = getString( R.string.download_dicts );
- m_dicts = new String[m_browsePosition];
+ Arrays.sort( input );
+ int browsePosn = input.length;
+ String[] result = new String[browsePosn+1];
+ result[browsePosn] = getString( R.string.download_dicts );
- for ( int ii = 0; ii < m_browsePosition; ++ii ) {
- String dict = list[ii];
- m_dicts[ii] = dict;
- m_dictItems[ii] = DictLangCache.annotatedDictName( this, dict );
- if ( dict.equals( curDict ) ) {
- curSel = ii;
- }
+ for ( int ii = 0; ii < browsePosn; ++ii ) {
+ String lang = input[ii];
+ result[ii] = lang;
}
-
- return curSel;
+ return result;
}
- private void configDictSpinner()
+ private int listAvailableLangs( String curDict )
{
- int curSel = listAvailableDicts( m_gi.dictName );
+ String[] langs =
+ DictLangCache.listLangs( this, GameUtils.dictList( this ) );
+ String curLang = DictLangCache.getLangName( this, curDict );
+ m_langs = buildListWithBrowse( langs );
+ m_langsBrowsePosition = m_langs.length - 1;
+ return Arrays.binarySearch( m_langs, curLang );
+ } // listAvailableLangs
+
+ private void configDictSpinner( final Dialog dialog, final LocalPlayer lp )
+ {
+ String[] tmpDicts =
+ DictLangCache.getHaveLang( this, m_gi.dictLang );
+ final String[] dicts = buildListWithBrowse( tmpDicts );
+ Spinner dictsSpinner =
+ (Spinner)dialog.findViewById( R.id.dict_spinner );
+ int curSel = -1;
+ if ( null != lp.dictName ) {
+ curSel = Arrays.binarySearch( dicts, lp.dictName );
+ }
+
+ OnItemSelectedListener onSel =
+ new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected( AdapterView> parentView,
+ View selectedItemView,
+ int position, long id ) {
+ if ( position == dicts.length - 1 ) {
+ Utils.logf( "posn=%d; starting activity", position );
+ startActivity( Utils.mkDownloadActivity(GameConfig.this,
+ m_gi.dictLang ) );
+ } else {
+ // lp.dictName = dicts[position];
+ // Utils.logf( "set lp.dictName: %s", lp.dictName );
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parentView) {}
+ };
+
+ configSpinnerWDownload( dictsSpinner, dicts, curSel, onSel );
+ }
+
+ private void configLangSpinner()
+ {
+ OnItemSelectedListener onSel =
+ new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parentView,
+ View selectedItemView,
+ int position, long id ) {
+ if ( position == m_langsBrowsePosition ) {
+ Utils.logf( "configLangSpinner: position=%d; starting download", position );
+ startActivity( Utils.mkDownloadActivity(GameConfig.this) );
+ } else {
+ m_gi.dictLang =
+ DictLangCache.getLangLangCode( GameConfig.this,
+ m_langs[position] );
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parentView) {}
+ };
+ configSpinnerWDownload( m_langSpinner, m_langs,
+ listAvailableLangs( m_gi.dictName ),
+ onSel );
+ }
+
+ private void configSpinnerWDownload( Spinner spinner, String[] texts,
+ int curSel,
+ OnItemSelectedListener onSel )
+ {
ArrayAdapter adapter =
new ArrayAdapter( this,
android.R.layout.simple_spinner_item,
- m_dictItems );
+ texts );
int resID = android.R.layout.simple_spinner_dropdown_item;
adapter.setDropDownViewResource( resID );
- m_dictSpinner.setAdapter( adapter );
+ spinner.setAdapter( adapter );
if ( curSel >= 0 ) {
- m_dictSpinner.setSelection( curSel );
+ Utils.logf( "setting selection: %d", curSel );
+ spinner.setSelection( curSel );
}
- m_dictSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parentView,
- View selectedItemView,
- int position, long id ) {
- if ( position == m_browsePosition ) {
- startActivity( Utils.mkDownloadActivity(GameConfig.this) );
- } else {
- m_gi.dictName = m_dicts[position];
- Utils.logf( "assigned dictName: " + m_gi.dictName );
- m_gi.dictLang = DictLangCache.getLangCode( GameConfig.this,
- m_gi.dictName );
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parentView) {}
- });
+ spinner.setOnItemSelectedListener( onSel );
}
private void setSmartnessSpinner()
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java
index 8cbd1ed9a..2ba47e7fe 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java
@@ -109,9 +109,11 @@ public class Utils {
String dict, int lang )
{
String dict_url = CommonPrefs.getDefaultDictURL( context );
+ if ( 0 != lang ) {
+ dict_url += "/" + DictLangCache.getLangName( context, lang );
+ }
if ( null != dict ) {
- dict_url += "/" + DictLangCache.getLangName( context, lang )
- + "/" + dict + XWConstants.DICT_EXTN;
+ dict_url += "/" + dict + XWConstants.DICT_EXTN;
}
Uri uri = Uri.parse( dict_url );
Intent intent = new Intent( Intent.ACTION_VIEW, uri );
@@ -124,6 +126,11 @@ public class Utils {
return mkDownloadActivity( context, null, 0 );
}
+ public static Intent mkDownloadActivity( Context context, int lang )
+ {
+ return mkDownloadActivity( context, null, lang );
+ }
+
public static void setChecked( Activity activity, int id, boolean value )
{
CheckBox cbx = (CheckBox)activity.findViewById( id );
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/CurGameInfo.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/CurGameInfo.java
index f84967823..e992cc54d 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/CurGameInfo.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/CurGameInfo.java
@@ -73,7 +73,7 @@ public class CurGameInfo {
serverRole = isNetworked ? DeviceRole.SERVER_ISCLIENT
: DeviceRole.SERVER_STANDALONE;
dictName = CommonPrefs.getDefaultDict( context );
- dictLang = DictLangCache.getLangCode( context, dictName );
+ dictLang = DictLangCache.getDictLangCode( context, dictName );
hintsNotAllowed = !CommonPrefs.getDefaultHintsAllowed( context );
phoniesAction = CommonPrefs.getDefaultPhonies( context );
timerEnabled = CommonPrefs.getDefaultTimerEnabled( context );
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/LocalPlayer.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/LocalPlayer.java
index 9dce35871..62a6951e1 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/LocalPlayer.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/LocalPlayer.java
@@ -27,6 +27,7 @@ import junit.framework.Assert;
public class LocalPlayer {
public String name;
public String password;
+ public String dictName;
public int secondsUsed;
public int robotIQ;
public boolean isLocal;
@@ -50,6 +51,9 @@ public class LocalPlayer {
if ( null != src.password ) {
password = new String(src.password);
}
+ if ( null != src.dictName ) {
+ dictName = new String(src.dictName);
+ }
secondsUsed = src.secondsUsed;
}