mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-29 08:34:37 +01:00
Merge branch 'android_branch' into french_xlation
Conflicts: xwords4/android/XWords4/res/values/strings.xml
This commit is contained in:
commit
a72883ae9a
23 changed files with 527 additions and 324 deletions
|
@ -22,7 +22,7 @@
|
|||
to come from a domain that you own or have control over. -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.eehouse.android.xw4"
|
||||
android:versionCode="25"
|
||||
android:versionCode="26"
|
||||
android:versionName="@string/app_version"
|
||||
>
|
||||
|
||||
|
|
|
@ -398,7 +398,10 @@ and_dictionary_destroy( DictionaryCtxt* dict )
|
|||
XP_FREEP( ctxt->super.mpool, &ctxt->super.langName );
|
||||
|
||||
if ( NULL == ctxt->byteArray ) { /* mmap case */
|
||||
int err = munmap( ctxt->bytes, ctxt->bytesSize );
|
||||
#ifdef DEBUG
|
||||
int err =
|
||||
#endif
|
||||
munmap( ctxt->bytes, ctxt->bytesSize );
|
||||
XP_ASSERT( 0 == err );
|
||||
} else {
|
||||
(*env)->ReleaseByteArrayElements( env, ctxt->byteArray, ctxt->bytes, 0 );
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
/>
|
||||
|
||||
|
|
|
@ -6,27 +6,33 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<b>Crosswords 4.4 beta 32 release</b>
|
||||
|
||||
<p><em>32's a quickie to fix a crash introduced in 31. So I'll leave the
|
||||
older changes in place</em></p>
|
||||
<b>Crosswords 4.4 beta 33 release</b>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Give choice between sending invites as TEXT or HTML, then format
|
||||
differently depending</li>
|
||||
<li>Use the term "wordlist" instead of "dictionary" to not imply that
|
||||
there are definitions provided.</li>
|
||||
|
||||
<li>include link in invites to install Crosswords</li>
|
||||
<li>Change how downloaded wordlists are opened to consume much less
|
||||
Java memory. Downside: wordlists on external storage are not
|
||||
available when that storage is mounted on a computer over USB.</li>
|
||||
|
||||
<li>Add expand/contract buttons to games list</li>
|
||||
<li>In the Wordlists screen, hide wordlists stored on external media
|
||||
when the media's not available. Notice when it becomes available
|
||||
and redraw the list.</li>
|
||||
|
||||
<li>Make a game's language one of several configurable attributes
|
||||
that can be displayed along with the game</li>
|
||||
|
||||
<li>Fix rename of games to work when keyboard opened while dialog
|
||||
up.</li>
|
||||
|
||||
<li>Add icons to games list display so it's easier to tell networked
|
||||
from standalone. These are placeholders until I can get an artist
|
||||
to help out. :-)</li>
|
||||
|
||||
<li>Add ability to rename games</li>
|
||||
|
||||
<li>Don't crash when user chooses "Copy"</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<p>Please remember that this is beta software. Please let me know (at
|
||||
eehouse@eehouse.org) what's broken and what features you'd most like
|
||||
to see.</p>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
<!-- <string name="default_host">10.0.2.2</string> -->
|
||||
<string name="dict_url">http://eehouse.org/and_dicts_hh</string>
|
||||
<string name="app_version">4.4 beta 32</string>
|
||||
<string name="app_version">4.4 beta 33</string>
|
||||
<string name="game_url_pathf">//%1$s/redir.php</string>
|
||||
|
||||
<!-- Debugging stuff. No point in localizing it. -->
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
############################################################
|
||||
-->
|
||||
<!-- window title -->
|
||||
<string name="title_dicts_list">Wordlists</string>
|
||||
<string name="title_dicts_list">Installed Crosswords Wordlists</string>
|
||||
|
||||
<!--
|
||||
############################################################
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
<!-- title for popup list of langugages from which user picks -->
|
||||
<string name="title_langs_list">Languages (based on installed
|
||||
dictionaries)</string>
|
||||
wordlists)</string>
|
||||
|
||||
<!-- text of checkbox at top of dialog allowing to unlock in-play
|
||||
game to make changes -->
|
||||
|
@ -161,16 +161,16 @@
|
|||
<string name="tell_unused">Not used yet...</string>
|
||||
|
||||
<!-- sub-preference for dictionaries (soon to be called "word lists") -->
|
||||
<string name="prefs_dicts">Dictionaries</string>
|
||||
<string name="prefs_dicts">Wordlists</string>
|
||||
<!-- clarification of above -->
|
||||
<string name="prefs_dicts_summary">Default dictionaries</string>
|
||||
<string name="prefs_dicts_summary">Default wordlists</string>
|
||||
|
||||
<!-- dictionary used by default for human players when creating
|
||||
new game -->
|
||||
<string name="default_dict">Dictionary for humans</string>
|
||||
<string name="default_dict">Wordlist for humans</string>
|
||||
<!-- dictionary used by default for robot players when creating
|
||||
new game -->
|
||||
<string name="default_robodict">Dictionary for robots</string>
|
||||
<string name="default_robodict">Wordlist for robots</string>
|
||||
|
||||
<!-- clarification on hints_allowed, whether new games will
|
||||
default to having the hint feature enabled(string elsewhere
|
||||
|
@ -419,6 +419,7 @@
|
|||
<string name="str_local_name">%s</string>
|
||||
<string name="str_nonlocal_name">(remote)</string>
|
||||
<string name="str_nonlocal_namef">%s (remote)</string>
|
||||
<string name="vs_join">\u0020vs.\u0020</string>
|
||||
<string name="str_game_namef">%1$s (%2$s)</string>
|
||||
<string name="str_bonus_all">Bonus for using all tiles: 50\n</string>
|
||||
<string name="strd_turn_score">Score for turn: %d\n</string>
|
||||
|
@ -438,7 +439,8 @@
|
|||
<string name="str_cant_hint_while_disabled">The hint feature is disabled for this game. Enable it for a new game using the Settings dialog.</string>
|
||||
<string name="str_no_peek_remote_tiles">No peeking at remote players\' tiles!</string>
|
||||
<string name="str_reg_unexpected_user">Refused attempt to register unexpected user[s]</string>
|
||||
<string name="str_server_dict_wins">Conflict between Host and Guest dictionaries; Host wins.</string>
|
||||
<string name="str_server_dict_wins">Conflict between Host and
|
||||
Guest wordlists; Host wins.</string>
|
||||
<string name="str_reg_server_sans_remote">At least one player must be marked \"Remote\" for a game started as Host.</string>
|
||||
|
||||
<string name="remote_label">Off-device player</string>
|
||||
|
@ -453,18 +455,18 @@
|
|||
<string name="players_label_host">Players (%1$d local, %2$d
|
||||
off-device)</string>
|
||||
|
||||
<string name="dicts_item_move">Move dictionary</string>
|
||||
<string name="dicts_item_move">Move wordlist</string>
|
||||
<string name="dicts_item_select">Make default</string>
|
||||
<string name="dicts_item_details">Details</string>
|
||||
<string name="move_dictf">Move dictionary %1$s from %2$s to %3$s?</string>
|
||||
<string name="move_dictf">Move wordlist %1$s from %2$s to %3$s?</string>
|
||||
<string name="set_default_messagef">For what players should this
|
||||
dictionary (and the language %s) be the default for new
|
||||
games?</string>
|
||||
wordlist be the default for new games? (The language %s will be
|
||||
the default for both.)</string>
|
||||
<string name="button_default_human">Human</string>
|
||||
<string name="button_default_robot">Robot</string>
|
||||
<string name="button_default_both">Both</string>
|
||||
|
||||
<string name="dict_lang_labelf">Dictionary (in %s)</string>
|
||||
<string name="dict_lang_labelf">Wordlist (in %s)</string>
|
||||
|
||||
<string name="configure_rolef">Configure %s connection</string>
|
||||
|
||||
|
@ -492,10 +494,10 @@
|
|||
<string name="confirm_delete_dictf">Are you sure you want to
|
||||
delete %s?</string>
|
||||
<string name="confirm_deleteonly_dictf">\u0020It is the only %s
|
||||
dictionary installed. One or more games will be unopenable
|
||||
wordlist installed. One or more games will be unopenable
|
||||
without it.</string>
|
||||
<string name="confirm_deletemore_dictf">\u0020One game (at least)
|
||||
is using it (but there is another %s dictionary installed that
|
||||
is using it (but there is another %s wordlist installed that
|
||||
can replace it.)</string>
|
||||
|
||||
<string name="progress_title">Searching for moves</string>
|
||||
|
@ -503,8 +505,8 @@
|
|||
<string name="color_tiles_summary">Draw tiles using color of
|
||||
player who played them</string>
|
||||
|
||||
<string name="storeWhereTitle">Dictionary storage</string>
|
||||
<string name="storeWhereMsg">Store downloaded dictionaries using
|
||||
<string name="storeWhereTitle">Wordlist storage</string>
|
||||
<string name="storeWhereMsg">Store downloaded wordlists using
|
||||
internal or external (SD card) memory? (You can always move them
|
||||
later.)</string>
|
||||
<string name="button_internal">Internal</string>
|
||||
|
@ -517,7 +519,7 @@
|
|||
<string name="robot_smartest">Smartest robot</string>
|
||||
|
||||
<string name="menu_prefs">Settings</string>
|
||||
<string name="gamel_menu_dicts">Dictionaries</string>
|
||||
<string name="gamel_menu_dicts">Wordlists</string>
|
||||
<string name="menu_revert_all">Restore all</string>
|
||||
<string name="menu_revert_colors">Restore colors</string>
|
||||
<string name="confirm_revert_colors">Are you sure you want to
|
||||
|
@ -552,7 +554,7 @@
|
|||
another device. You will not be able to play any
|
||||
further.</string>
|
||||
|
||||
<string name="ids_badwords">Word[s] %s not found in dictionary.</string>
|
||||
<string name="ids_badwords">Word[s] %s not found in wordlist.</string>
|
||||
<string name="badwords_accept"> Do you still want to accept this move?</string>
|
||||
<string name="badwords_lost"> Turn lost.</string>
|
||||
<string name="badwords_title">Illegal word[s]</string>
|
||||
|
@ -586,17 +588,24 @@
|
|||
credits pending permission.</string>
|
||||
|
||||
<string name="downloading_dictf">Downloading Crosswords
|
||||
dictionary %s...</string>
|
||||
<string name="no_dict_title">Dictionary not found</string>
|
||||
wordlist %s...</string>
|
||||
<string name="no_dict_title">Wordlist not found</string>
|
||||
<string name="button_download">Download</string>
|
||||
<string name="subst_dict_title">Substitute dictionary (wordcount)</string>
|
||||
<string name="subst_dict_title">Substitute wordlist (wordcount)</string>
|
||||
<string name="button_substdict">Substitute</string>
|
||||
|
||||
<string name="no_dictf">Unable to open game because no %s
|
||||
dictionary found.</string>
|
||||
<string name="no_dict_substf">Unable to open game because
|
||||
dictionary %1$s not found. You can download a replacement or
|
||||
substitute another %2$s dictionary.</string>
|
||||
<string name="button_close_game">Close game</string>
|
||||
<string name="no_dict_finish">A wordlist this game is using has
|
||||
disappeared. (Usually this means it\'s on an external card that
|
||||
is no longer available.)</string>
|
||||
<string name="no_dictf">Unable to open game \"%1$s\" because no
|
||||
%2$s wordlist found. (It may have been deleted, or stored on
|
||||
an external card that is no longer available.)</string>
|
||||
<string name="no_dict_substf">Unable to open game \"%1$s\" because
|
||||
wordlist %2$s not found. (It may have been deleted, or stored
|
||||
on an external card that is no longer available.) You can
|
||||
download a replacement or substitute another %3$s
|
||||
wordlist.</string>
|
||||
|
||||
<string name="msg_ask_password">Password for \"%s\":</string>
|
||||
|
||||
|
@ -703,12 +712,12 @@
|
|||
game on the relay. You will be notified when the remaining
|
||||
device[s] have joined your room and play can begin.</string>
|
||||
|
||||
<string name="not_again_dicts">Crosswords dictionaries, which are
|
||||
<string name="not_again_dicts">Crosswords wordlists, which are
|
||||
just compressed lists of words plus tile information, determine
|
||||
what language a game is played in and how \"smart\" the robot is.
|
||||
You can download different sized dictionaries in many languages
|
||||
here. Email me at eehouse@eehouse.org for information on building
|
||||
and installing your own dictionaries.</string>
|
||||
what language a game is played in and how \"smart\" the robot
|
||||
is. You can download different sized wordlists in many
|
||||
languages here. Email me at eehouse@eehouse.org for information
|
||||
on building and installing your own wordlists.</string>
|
||||
|
||||
<string name="not_again_arrow">Moving tiles to the board:\nYou can
|
||||
drag tiles between the rack and the board, or you can tap an
|
||||
|
|
|
@ -38,6 +38,7 @@ import android.app.Dialog;
|
|||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.EditText;
|
||||
|
@ -80,7 +81,7 @@ public class BoardActivity extends XWActivity
|
|||
private int m_jniGamePtr;
|
||||
private GameUtils.GameLock m_gameLock;
|
||||
private CurGameInfo m_gi;
|
||||
CommsTransport m_xport;
|
||||
private CommsTransport m_xport;
|
||||
private Handler m_handler = null;
|
||||
private TimerRunnable[] m_timers;
|
||||
private Runnable m_screenTimer;
|
||||
|
@ -1044,89 +1045,96 @@ public class BoardActivity extends XWActivity
|
|||
private void loadGame()
|
||||
{
|
||||
if ( 0 == m_jniGamePtr ) {
|
||||
Assert.assertNull( m_gameLock );
|
||||
m_gameLock = new GameUtils.GameLock( m_rowid, true ).lock();
|
||||
|
||||
byte[] stream = GameUtils.savedGame( this, m_gameLock );
|
||||
XwJNI.gi_from_stream( m_gi, stream );
|
||||
|
||||
String[] dictNames = m_gi.dictNames();
|
||||
GameUtils.DictPairs pairs = GameUtils.openDicts( this, dictNames );
|
||||
String langName = m_gi.langName();
|
||||
m_jniGamePtr = XwJNI.initJNI();
|
||||
|
||||
if ( m_gi.serverRole != DeviceRole.SERVER_STANDALONE ) {
|
||||
m_xport = new CommsTransport( m_jniGamePtr, this, this,
|
||||
m_gi.serverRole );
|
||||
}
|
||||
if ( pairs.anyMissing( dictNames ) ) {
|
||||
showDictGoneFinish();
|
||||
} else {
|
||||
|
||||
CommonPrefs cp = CommonPrefs.get( this );
|
||||
if ( null == stream ||
|
||||
! XwJNI.game_makeFromStream( m_jniGamePtr, stream,
|
||||
m_gi, dictNames, pairs.m_bytes,
|
||||
pairs.m_paths, langName, m_utils,
|
||||
m_jniu, m_view, cp, m_xport ) ) {
|
||||
XwJNI.game_makeNewGame( m_jniGamePtr, m_gi, m_utils, m_jniu,
|
||||
m_view, cp, m_xport, dictNames,
|
||||
pairs.m_bytes, pairs.m_paths,
|
||||
langName );
|
||||
}
|
||||
String langName = m_gi.langName();
|
||||
|
||||
m_jniThread = new
|
||||
JNIThread( m_jniGamePtr, m_gi, m_view, m_gameLock, this,
|
||||
new Handler() {
|
||||
public void handleMessage( Message msg ) {
|
||||
switch( msg.what ) {
|
||||
case JNIThread.DRAW:
|
||||
m_view.invalidate();
|
||||
break;
|
||||
case JNIThread.DIALOG:
|
||||
m_dlgBytes = (String)msg.obj;
|
||||
m_dlgTitle = msg.arg1;
|
||||
showDialog( DLG_OKONLY );
|
||||
break;
|
||||
case JNIThread.QUERY_ENDGAME:
|
||||
showDialog( QUERY_ENDGAME );
|
||||
break;
|
||||
case JNIThread.TOOLBAR_STATES:
|
||||
if ( null != m_jniThread ) {
|
||||
m_gsi = m_jniThread.getGameStateInfo();
|
||||
updateToolbar();
|
||||
Assert.assertNull( m_gameLock );
|
||||
m_gameLock = new GameUtils.GameLock( m_rowid, true ).lock();
|
||||
|
||||
byte[] stream = GameUtils.savedGame( this, m_gameLock );
|
||||
XwJNI.gi_from_stream( m_gi, stream );
|
||||
|
||||
m_jniGamePtr = XwJNI.initJNI();
|
||||
|
||||
if ( m_gi.serverRole != DeviceRole.SERVER_STANDALONE ) {
|
||||
m_xport = new CommsTransport( m_jniGamePtr, this, this,
|
||||
m_gi.serverRole );
|
||||
}
|
||||
|
||||
CommonPrefs cp = CommonPrefs.get( this );
|
||||
if ( null == stream ||
|
||||
! XwJNI.game_makeFromStream( m_jniGamePtr, stream,
|
||||
m_gi, dictNames, pairs.m_bytes,
|
||||
pairs.m_paths, langName, m_utils,
|
||||
m_jniu, m_view, cp, m_xport ) ) {
|
||||
XwJNI.game_makeNewGame( m_jniGamePtr, m_gi, m_utils, m_jniu,
|
||||
m_view, cp, m_xport, dictNames,
|
||||
pairs.m_bytes, pairs.m_paths,
|
||||
langName );
|
||||
}
|
||||
|
||||
m_jniThread = new
|
||||
JNIThread( m_jniGamePtr, m_gi, m_view, m_gameLock, this,
|
||||
new Handler() {
|
||||
public void handleMessage( Message msg ) {
|
||||
switch( msg.what ) {
|
||||
case JNIThread.DRAW:
|
||||
m_view.invalidate();
|
||||
break;
|
||||
case JNIThread.DIALOG:
|
||||
m_dlgBytes = (String)msg.obj;
|
||||
m_dlgTitle = msg.arg1;
|
||||
showDialog( DLG_OKONLY );
|
||||
break;
|
||||
case JNIThread.QUERY_ENDGAME:
|
||||
showDialog( QUERY_ENDGAME );
|
||||
break;
|
||||
case JNIThread.TOOLBAR_STATES:
|
||||
if ( null != m_jniThread ) {
|
||||
m_gsi = m_jniThread.getGameStateInfo();
|
||||
updateToolbar();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} );
|
||||
// see http://stackoverflow.com/questions/680180/where-to-stop-\
|
||||
// destroy-threads-in-android-service-class
|
||||
m_jniThread.setDaemon( true );
|
||||
m_jniThread.start();
|
||||
} );
|
||||
// see http://stackoverflow.com/questions/680180/where-to-stop-\
|
||||
// destroy-threads-in-android-service-class
|
||||
m_jniThread.setDaemon( true );
|
||||
m_jniThread.start();
|
||||
|
||||
m_view.startHandling( this, m_jniThread, m_jniGamePtr, m_gi );
|
||||
if ( null != m_xport ) {
|
||||
m_xport.setReceiver( m_jniThread );
|
||||
}
|
||||
m_jniThread.handle( JNICmd.CMD_START );
|
||||
m_view.startHandling( this, m_jniThread, m_jniGamePtr, m_gi );
|
||||
if ( null != m_xport ) {
|
||||
m_xport.setReceiver( m_jniThread );
|
||||
}
|
||||
m_jniThread.handle( JNICmd.CMD_START );
|
||||
|
||||
if ( !CommonPrefs.getHideTitleBar( this ) ) {
|
||||
setTitle( GameUtils.getName( this, m_rowid ) );
|
||||
}
|
||||
m_toolbar = new Toolbar( this );
|
||||
if ( !CommonPrefs.getHideTitleBar( this ) ) {
|
||||
setTitle( GameUtils.getName( this, m_rowid ) );
|
||||
}
|
||||
m_toolbar = new Toolbar( this );
|
||||
|
||||
populateToolbar();
|
||||
populateToolbar();
|
||||
|
||||
int flags = DBUtils.getMsgFlags( this, m_rowid );
|
||||
if ( 0 != (GameSummary.MSG_FLAGS_CHAT & flags) ) {
|
||||
startChatActivity();
|
||||
}
|
||||
if ( 0 != (GameSummary.MSG_FLAGS_GAMEOVER & flags) ) {
|
||||
m_jniThread.handle( JNIThread.JNICmd.CMD_POST_OVER );
|
||||
}
|
||||
if ( 0 != flags ) {
|
||||
DBUtils.setMsgFlags( m_rowid, GameSummary.MSG_FLAGS_NONE );
|
||||
}
|
||||
int flags = DBUtils.getMsgFlags( this, m_rowid );
|
||||
if ( 0 != (GameSummary.MSG_FLAGS_CHAT & flags) ) {
|
||||
startChatActivity();
|
||||
}
|
||||
if ( 0 != (GameSummary.MSG_FLAGS_GAMEOVER & flags) ) {
|
||||
m_jniThread.handle( JNIThread.JNICmd.CMD_POST_OVER );
|
||||
}
|
||||
if ( 0 != flags ) {
|
||||
DBUtils.setMsgFlags( m_rowid, GameSummary.MSG_FLAGS_NONE );
|
||||
}
|
||||
|
||||
trySendChats();
|
||||
trySendChats();
|
||||
}
|
||||
}
|
||||
} // loadGame
|
||||
|
||||
|
@ -1209,9 +1217,9 @@ public class BoardActivity extends XWActivity
|
|||
});
|
||||
} // populateToolbar
|
||||
|
||||
private DialogInterface.OnDismissListener makeODLforBlocking( final int id )
|
||||
private OnDismissListener makeODLforBlocking( final int id )
|
||||
{
|
||||
return new DialogInterface.OnDismissListener() {
|
||||
return new OnDismissListener() {
|
||||
public void onDismiss( DialogInterface di ) {
|
||||
releaseIfBlocking();
|
||||
removeDialog( id );
|
||||
|
|
|
@ -107,7 +107,7 @@ public class DBUtils {
|
|||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
summary = new GameSummary();
|
||||
summary = new GameSummary( context );
|
||||
summary.nMoves = cursor.getInt(cursor.
|
||||
getColumnIndex(DBHelper.NUM_MOVES));
|
||||
summary.nPlayers =
|
||||
|
@ -223,7 +223,7 @@ public class DBUtils {
|
|||
values.put( DBHelper.TURN, summary.turn );
|
||||
values.put( DBHelper.GIFLAGS, summary.giflags() );
|
||||
values.put( DBHelper.PLAYERS,
|
||||
summary.summarizePlayers(context) );
|
||||
summary.summarizePlayers() );
|
||||
values.put( DBHelper.DICTLANG, summary.dictLang );
|
||||
values.put( DBHelper.GAME_OVER, summary.gameOver );
|
||||
|
||||
|
|
|
@ -55,7 +55,8 @@ import org.eehouse.android.xw4.jni.JNIUtilsImpl;
|
|||
import org.eehouse.android.xw4.jni.CommonPrefs;
|
||||
|
||||
public class DictsActivity extends ExpandableListActivity
|
||||
implements View.OnClickListener, XWListItem.DeleteCallback {
|
||||
implements View.OnClickListener, XWListItem.DeleteCallback,
|
||||
SDCardWatcher.SDCardNotifiee {
|
||||
|
||||
private static final String DICT_DOLAUNCH = "do_launch";
|
||||
private static final String DICT_LANG_EXTRA = "use_lang";
|
||||
|
@ -75,9 +76,10 @@ public class DictsActivity extends ExpandableListActivity
|
|||
private XWListItem m_rowView;
|
||||
GameUtils.DictLoc m_moveFromLoc;
|
||||
GameUtils.DictLoc m_moveToLoc;
|
||||
String m_moveName;
|
||||
private SDCardWatcher m_cardWatcher;
|
||||
private String m_moveName;
|
||||
|
||||
LayoutInflater m_factory;
|
||||
private LayoutInflater m_factory;
|
||||
|
||||
private class DictListAdapter implements ExpandableListAdapter {
|
||||
private Context m_context;
|
||||
|
@ -331,10 +333,17 @@ public class DictsActivity extends ExpandableListActivity
|
|||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
m_cardWatcher = new SDCardWatcher( this, this );
|
||||
mkListAdapter();
|
||||
expandGroups();
|
||||
}
|
||||
|
||||
protected void onPause() {
|
||||
m_cardWatcher.close();
|
||||
m_cardWatcher = null;
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
public void onClick( View v )
|
||||
{
|
||||
askStartDownload( 0, null );
|
||||
|
@ -368,6 +377,9 @@ public class DictsActivity extends ExpandableListActivity
|
|||
|| ! GameUtils.haveWriteableSD() ) {
|
||||
menu.removeItem( R.id.dicts_item_move );
|
||||
}
|
||||
|
||||
String fmt = getString(R.string.game_item_menu_titlef );
|
||||
menu.setHeaderTitle( String.format( fmt, row.getText() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,7 +441,7 @@ public class DictsActivity extends ExpandableListActivity
|
|||
showDialog( MOVE_DICT );
|
||||
}
|
||||
|
||||
// DeleteCallback interface
|
||||
// XWListItem.DeleteCallback interface
|
||||
public void deleteCalled( int myPosition, final String dict )
|
||||
{
|
||||
int code = DictLangCache.getDictLangCode( this, dict );
|
||||
|
@ -457,6 +469,13 @@ public class DictsActivity extends ExpandableListActivity
|
|||
m_delegate.showConfirmThen( msg, action );
|
||||
}
|
||||
|
||||
// SDCardWatcher.SDCardNotifiee interface
|
||||
public void cardMounted()
|
||||
{
|
||||
mkListAdapter();
|
||||
expandGroups();
|
||||
}
|
||||
|
||||
private void deleteDict( String dict )
|
||||
{
|
||||
GameUtils.deleteDict( this, dict );
|
||||
|
|
|
@ -40,7 +40,8 @@ public class DlgDelegate {
|
|||
public static final int DIALOG_NOTAGAIN = 3;
|
||||
public static final int CONFIRM_THEN = 4;
|
||||
public static final int TEXT_OR_HTML_THEN = 5;
|
||||
public static final int DIALOG_LAST = TEXT_OR_HTML_THEN;
|
||||
public static final int DLG_DICTGONE = 6;
|
||||
public static final int DIALOG_LAST = DLG_DICTGONE;
|
||||
|
||||
private int m_msgID;
|
||||
private String m_msg;
|
||||
|
@ -78,6 +79,9 @@ public class DlgDelegate {
|
|||
case TEXT_OR_HTML_THEN:
|
||||
dialog = createHtmlThenDialog();
|
||||
break;
|
||||
case DLG_DICTGONE:
|
||||
dialog = createDictGoneDialog();
|
||||
break;
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
@ -141,6 +145,11 @@ public class DlgDelegate {
|
|||
m_activity.showDialog( DIALOG_OKONLY );
|
||||
}
|
||||
|
||||
public void showDictGoneFinish()
|
||||
{
|
||||
m_activity.showDialog( DLG_DICTGONE );
|
||||
}
|
||||
|
||||
public void showAboutDialog()
|
||||
{
|
||||
m_activity.showDialog( DIALOG_ABOUT );
|
||||
|
@ -283,4 +292,23 @@ public class DlgDelegate {
|
|||
.create();
|
||||
}
|
||||
|
||||
private Dialog createDictGoneDialog()
|
||||
{
|
||||
Utils.logf( "DlgDelegate.createDictGoneDialog() called" );
|
||||
Dialog dialog;
|
||||
dialog = new AlertDialog.Builder( m_activity )
|
||||
.setTitle( R.string.no_dict_title )
|
||||
.setMessage( R.string.no_dict_finish )
|
||||
.setPositiveButton( R.string.button_close_game, null )
|
||||
.create();
|
||||
|
||||
dialog.setOnDismissListener( new DialogInterface.OnDismissListener() {
|
||||
public void onDismiss( DialogInterface di ) {
|
||||
m_activity.finish();
|
||||
}
|
||||
} );
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -396,88 +396,91 @@ public class GameConfig extends XWActivity
|
|||
{
|
||||
super.onResume();
|
||||
|
||||
int gamePtr = XwJNI.initJNI();
|
||||
m_giOrig = new CurGameInfo( this );
|
||||
// Lock in case we're going to config. We *could* re-get the
|
||||
// lock once the user decides to make changes. PENDING.
|
||||
m_gameLock = new GameUtils.GameLock( m_rowid, true ).lock();
|
||||
GameUtils.loadMakeGame( this, gamePtr, m_giOrig, m_gameLock );
|
||||
m_gameStarted = XwJNI.model_getNMoves( gamePtr ) > 0
|
||||
|| XwJNI.comms_isConnected( gamePtr );
|
||||
|
||||
if ( m_gameStarted ) {
|
||||
if ( null == m_gameLockedCheck ) {
|
||||
m_gameLockedCheck =
|
||||
(CheckBox)findViewById( R.id.game_locked_check );
|
||||
m_gameLockedCheck.setVisibility( View.VISIBLE );
|
||||
m_gameLockedCheck.setChecked( true );
|
||||
m_gameLockedCheck.setOnClickListener( this );
|
||||
}
|
||||
handleLockedChange();
|
||||
}
|
||||
|
||||
m_gi = new CurGameInfo( this, m_giOrig );
|
||||
|
||||
m_carOrig = new CommsAddrRec( this );
|
||||
if ( XwJNI.game_hasComms( gamePtr ) ) {
|
||||
XwJNI.comms_getAddr( gamePtr, m_carOrig );
|
||||
int gamePtr = GameUtils.loadMakeGame( this, m_giOrig, m_gameLock );
|
||||
if ( 0 == gamePtr ) {
|
||||
showDictGoneFinish();
|
||||
} else {
|
||||
String relayName = CommonPrefs.getDefaultRelayHost( this );
|
||||
int relayPort = CommonPrefs.getDefaultRelayPort( this );
|
||||
XwJNI.comms_getInitialAddr( m_carOrig, relayName, relayPort );
|
||||
}
|
||||
XwJNI.game_dispose( gamePtr );
|
||||
m_gameStarted = XwJNI.model_getNMoves( gamePtr ) > 0
|
||||
|| XwJNI.comms_isConnected( gamePtr );
|
||||
|
||||
m_car = new CommsAddrRec( m_carOrig );
|
||||
|
||||
m_notNetworkedGame = DeviceRole.SERVER_STANDALONE == m_gi.serverRole;
|
||||
setTitle();
|
||||
|
||||
if ( !m_notNetworkedGame ) {
|
||||
m_joinPublicCheck =
|
||||
(CheckBox)findViewById(R.id.join_public_room_check);
|
||||
m_joinPublicCheck.setOnClickListener( this );
|
||||
m_joinPublicCheck.setChecked( m_car.ip_relay_seeksPublicRoom );
|
||||
Utils.setChecked( this, R.id.advertise_new_room_check,
|
||||
m_car.ip_relay_advertiseRoom );
|
||||
m_publicRoomsSet =
|
||||
(LinearLayout)findViewById(R.id.public_rooms_set );
|
||||
m_privateRoomsSet =
|
||||
(LinearLayout)findViewById(R.id.private_rooms_set );
|
||||
|
||||
Utils.setText( this, R.id.room_edit, m_car.ip_relay_invite );
|
||||
|
||||
m_roomChoose = (Spinner)findViewById( R.id.room_spinner );
|
||||
|
||||
m_refreshRoomsButton =
|
||||
(ImageButton)findViewById( R.id.refresh_button );
|
||||
m_refreshRoomsButton.setOnClickListener( this );
|
||||
|
||||
adjustConnectStuff();
|
||||
}
|
||||
|
||||
loadPlayers();
|
||||
configLangSpinner();
|
||||
|
||||
m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() );
|
||||
|
||||
setSmartnessSpinner();
|
||||
|
||||
Utils.setChecked( this, R.id.hints_allowed, !m_gi.hintsNotAllowed );
|
||||
Utils.setInt( this, R.id.timer_minutes_edit,
|
||||
m_gi.gameSeconds/60/m_gi.nPlayers );
|
||||
|
||||
CheckBox check = (CheckBox)findViewById( R.id.use_timer );
|
||||
CompoundButton.OnCheckedChangeListener lstnr =
|
||||
new CompoundButton.OnCheckedChangeListener() {
|
||||
public void onCheckedChanged( CompoundButton buttonView,
|
||||
boolean checked ) {
|
||||
View view = findViewById( R.id.timer_set );
|
||||
view.setVisibility( checked ? View.VISIBLE : View.GONE );
|
||||
if ( m_gameStarted ) {
|
||||
if ( null == m_gameLockedCheck ) {
|
||||
m_gameLockedCheck =
|
||||
(CheckBox)findViewById( R.id.game_locked_check );
|
||||
m_gameLockedCheck.setVisibility( View.VISIBLE );
|
||||
m_gameLockedCheck.setChecked( true );
|
||||
m_gameLockedCheck.setOnClickListener( this );
|
||||
}
|
||||
};
|
||||
check.setOnCheckedChangeListener( lstnr );
|
||||
Utils.setChecked( this, R.id.use_timer, m_gi.timerEnabled );
|
||||
handleLockedChange();
|
||||
}
|
||||
|
||||
m_gi = new CurGameInfo( this, m_giOrig );
|
||||
|
||||
m_carOrig = new CommsAddrRec( this );
|
||||
if ( XwJNI.game_hasComms( gamePtr ) ) {
|
||||
XwJNI.comms_getAddr( gamePtr, m_carOrig );
|
||||
} else {
|
||||
String relayName = CommonPrefs.getDefaultRelayHost( this );
|
||||
int relayPort = CommonPrefs.getDefaultRelayPort( this );
|
||||
XwJNI.comms_getInitialAddr( m_carOrig, relayName, relayPort );
|
||||
}
|
||||
XwJNI.game_dispose( gamePtr );
|
||||
|
||||
m_car = new CommsAddrRec( m_carOrig );
|
||||
|
||||
m_notNetworkedGame = DeviceRole.SERVER_STANDALONE == m_gi.serverRole;
|
||||
setTitle();
|
||||
|
||||
if ( !m_notNetworkedGame ) {
|
||||
m_joinPublicCheck =
|
||||
(CheckBox)findViewById(R.id.join_public_room_check);
|
||||
m_joinPublicCheck.setOnClickListener( this );
|
||||
m_joinPublicCheck.setChecked( m_car.ip_relay_seeksPublicRoom );
|
||||
Utils.setChecked( this, R.id.advertise_new_room_check,
|
||||
m_car.ip_relay_advertiseRoom );
|
||||
m_publicRoomsSet =
|
||||
(LinearLayout)findViewById(R.id.public_rooms_set );
|
||||
m_privateRoomsSet =
|
||||
(LinearLayout)findViewById(R.id.private_rooms_set );
|
||||
|
||||
Utils.setText( this, R.id.room_edit, m_car.ip_relay_invite );
|
||||
|
||||
m_roomChoose = (Spinner)findViewById( R.id.room_spinner );
|
||||
|
||||
m_refreshRoomsButton =
|
||||
(ImageButton)findViewById( R.id.refresh_button );
|
||||
m_refreshRoomsButton.setOnClickListener( this );
|
||||
|
||||
adjustConnectStuff();
|
||||
}
|
||||
|
||||
loadPlayers();
|
||||
configLangSpinner();
|
||||
|
||||
m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() );
|
||||
|
||||
setSmartnessSpinner();
|
||||
|
||||
Utils.setChecked( this, R.id.hints_allowed, !m_gi.hintsNotAllowed );
|
||||
Utils.setInt( this, R.id.timer_minutes_edit,
|
||||
m_gi.gameSeconds/60/m_gi.nPlayers );
|
||||
|
||||
CheckBox check = (CheckBox)findViewById( R.id.use_timer );
|
||||
CompoundButton.OnCheckedChangeListener lstnr =
|
||||
new CompoundButton.OnCheckedChangeListener() {
|
||||
public void onCheckedChanged( CompoundButton buttonView,
|
||||
boolean checked ) {
|
||||
View view = findViewById( R.id.timer_set );
|
||||
view.setVisibility( checked ? View.VISIBLE : View.GONE );
|
||||
}
|
||||
};
|
||||
check.setOnCheckedChangeListener( lstnr );
|
||||
Utils.setChecked( this, R.id.use_timer, m_gi.timerEnabled );
|
||||
}
|
||||
} // onResume
|
||||
|
||||
@Override
|
||||
|
|
|
@ -118,7 +118,7 @@ public class GameListAdapter extends XWListAdapter {
|
|||
} else {
|
||||
//Assert.assertNotNull( summary );
|
||||
|
||||
String state = summary.summarizeState( m_context );
|
||||
String state = summary.summarizeState();
|
||||
|
||||
TextView view = (TextView)layout.findViewById( R.id.game_name );
|
||||
if ( hideTitle ) {
|
||||
|
@ -134,7 +134,7 @@ public class GameListAdapter extends XWListAdapter {
|
|||
summary.dictLang );
|
||||
break;
|
||||
case R.string.game_summary_field_opponents:
|
||||
value = "vs Kati +2";
|
||||
value = summary.playerNames();
|
||||
break;
|
||||
case R.string.game_summary_field_state:
|
||||
value = state;
|
||||
|
@ -168,7 +168,7 @@ public class GameListAdapter extends XWListAdapter {
|
|||
View tmp = m_factory.inflate( R.layout.player_list_elem,
|
||||
null );
|
||||
view = (TextView)tmp.findViewById( R.id.item_name );
|
||||
view.setText( summary.summarizePlayer( m_context, ii ) );
|
||||
view.setText( summary.summarizePlayer( ii ) );
|
||||
view = (TextView)tmp.findViewById( R.id.item_score );
|
||||
view.setText( String.format( " %d", summary.scores[ii] ) );
|
||||
if ( summary.isNextToPlay( ii ) ) {
|
||||
|
@ -200,7 +200,7 @@ public class GameListAdapter extends XWListAdapter {
|
|||
marker.setImageResource( iconID );
|
||||
|
||||
view = (TextView)layout.findViewById( R.id.role );
|
||||
String roleSummary = summary.summarizeRole( m_context );
|
||||
String roleSummary = summary.summarizeRole();
|
||||
if ( null != roleSummary ) {
|
||||
view.setText( roleSummary );
|
||||
} else {
|
||||
|
|
|
@ -158,7 +158,23 @@ public class GameUtils {
|
|||
public DictPairs( byte[][] bytes, String[] paths ) {
|
||||
m_bytes = bytes; m_paths = paths;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean anyMissing( final String[] names )
|
||||
{
|
||||
boolean missing = false;
|
||||
for ( int ii = 0; ii < m_paths.length; ++ii ) {
|
||||
if ( names[ii] != null ) {
|
||||
// It's ok for there to be no dict IFF there's no
|
||||
// name. That's a player using the default dict.
|
||||
if ( null == m_paths[ii] && null == m_bytes[ii] ) {
|
||||
missing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return missing;
|
||||
}
|
||||
} // DictPairs
|
||||
|
||||
private static Object s_syncObj = new Object();
|
||||
|
||||
|
@ -180,15 +196,14 @@ public class GameUtils {
|
|||
* basis for a new one.
|
||||
*/
|
||||
public static GameLock resetGame( Context context, GameLock lockSrc,
|
||||
GameLock lockDest )
|
||||
GameLock lockDest )
|
||||
{
|
||||
int gamePtr = XwJNI.initJNI();
|
||||
CurGameInfo gi = new CurGameInfo( context );
|
||||
CommsAddrRec addr = null;
|
||||
|
||||
// loadMakeGame, if makinga new game, will add comms as long
|
||||
// as DeviceRole.SERVER_STANDALONE != gi.serverRole
|
||||
loadMakeGame( context, gamePtr, gi, lockSrc );
|
||||
int gamePtr = loadMakeGame( context, gi, lockSrc );
|
||||
String[] dictNames = gi.dictNames();
|
||||
DictPairs pairs = openDicts( context, dictNames );
|
||||
|
||||
|
@ -243,7 +258,7 @@ public class GameUtils {
|
|||
int gamePtr, CurGameInfo gi,
|
||||
FeedUtilsImpl feedImpl )
|
||||
{
|
||||
GameSummary summary = new GameSummary( gi );
|
||||
GameSummary summary = new GameSummary( context, gi );
|
||||
XwJNI.game_summarize( gamePtr, summary );
|
||||
|
||||
if ( null != feedImpl ) {
|
||||
|
@ -266,9 +281,8 @@ public class GameUtils {
|
|||
|
||||
public static GameSummary summarize( Context context, GameLock lock )
|
||||
{
|
||||
int gamePtr = XwJNI.initJNI();
|
||||
CurGameInfo gi = new CurGameInfo( context );
|
||||
loadMakeGame( context, gamePtr, gi, lock );
|
||||
int gamePtr = loadMakeGame( context, gi, lock );
|
||||
|
||||
return summarizeAndClose( context, lock, gamePtr, gi );
|
||||
}
|
||||
|
@ -305,33 +319,40 @@ public class GameUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static void loadMakeGame( Context context, int gamePtr,
|
||||
CurGameInfo gi, GameLock lock )
|
||||
public static int loadMakeGame( Context context, CurGameInfo gi,
|
||||
GameLock lock )
|
||||
{
|
||||
loadMakeGame( context, gamePtr, gi, null, lock );
|
||||
return loadMakeGame( context, gi, null, lock );
|
||||
}
|
||||
|
||||
public static void loadMakeGame( Context context, int gamePtr,
|
||||
CurGameInfo gi, UtilCtxt util,
|
||||
GameLock lock )
|
||||
public static int loadMakeGame( Context context, CurGameInfo gi,
|
||||
UtilCtxt util, GameLock lock )
|
||||
{
|
||||
int gamePtr = 0;
|
||||
|
||||
byte[] stream = savedGame( context, lock );
|
||||
XwJNI.gi_from_stream( gi, stream );
|
||||
String[] dictNames = gi.dictNames();
|
||||
DictPairs pairs = openDicts( context, dictNames );
|
||||
String langName = gi.langName();
|
||||
if ( pairs.anyMissing( dictNames ) ) {
|
||||
Utils.logf( "loadMakeGame() failing: dict unavailable" );
|
||||
} else {
|
||||
gamePtr = XwJNI.initJNI();
|
||||
|
||||
boolean madeGame = XwJNI.game_makeFromStream( gamePtr, stream,
|
||||
JNIUtilsImpl.get(), gi,
|
||||
dictNames, pairs.m_bytes,
|
||||
pairs.m_paths, langName,
|
||||
util,
|
||||
CommonPrefs.get(context));
|
||||
if ( !madeGame ) {
|
||||
XwJNI.game_makeNewGame( gamePtr, gi, JNIUtilsImpl.get(),
|
||||
CommonPrefs.get(context), dictNames,
|
||||
pairs.m_bytes, pairs.m_paths, langName );
|
||||
String langName = gi.langName();
|
||||
boolean madeGame = XwJNI.game_makeFromStream( gamePtr, stream,
|
||||
JNIUtilsImpl.get(), gi,
|
||||
dictNames, pairs.m_bytes,
|
||||
pairs.m_paths, langName,
|
||||
util,
|
||||
CommonPrefs.get(context));
|
||||
if ( !madeGame ) {
|
||||
XwJNI.game_makeNewGame( gamePtr, gi, JNIUtilsImpl.get(),
|
||||
CommonPrefs.get(context), dictNames,
|
||||
pairs.m_bytes, pairs.m_paths, langName );
|
||||
}
|
||||
}
|
||||
return gamePtr;
|
||||
}
|
||||
|
||||
public static long saveGame( Context context, int gamePtr,
|
||||
|
@ -718,7 +739,7 @@ public class GameUtils {
|
|||
File file = context.getFileStreamPath( name );
|
||||
if ( !file.exists() ) {
|
||||
file = getSDPathFor( context, name );
|
||||
if ( !file.exists() ) {
|
||||
if ( null != file && !file.exists() ) {
|
||||
file = null;
|
||||
}
|
||||
}
|
||||
|
@ -856,12 +877,11 @@ public class GameUtils {
|
|||
boolean draw = false;
|
||||
long rowid = DBUtils.getRowIDFor( context, relayID );
|
||||
if ( -1 != rowid ) {
|
||||
int gamePtr = XwJNI.initJNI();
|
||||
CurGameInfo gi = new CurGameInfo( context );
|
||||
FeedUtilsImpl feedImpl = new FeedUtilsImpl( context, rowid );
|
||||
GameLock lock = new GameLock( rowid, true );
|
||||
if ( lock.tryLock() ) {
|
||||
loadMakeGame( context, gamePtr, gi, feedImpl, lock );
|
||||
int gamePtr = loadMakeGame( context, gi, feedImpl, lock );
|
||||
|
||||
for ( byte[] msg : msgs ) {
|
||||
draw = XwJNI.game_receiveMessage( gamePtr, msg ) || draw;
|
||||
|
@ -897,7 +917,7 @@ public class GameUtils {
|
|||
// Which isn't possible right now, so make sure the old and new
|
||||
// dict have the same langauge code.
|
||||
public static void replaceDicts( Context context, long rowid,
|
||||
String oldDict, String newDict )
|
||||
String oldDict, String newDict )
|
||||
{
|
||||
GameLock lock = new GameLock( rowid, true ).lock();
|
||||
byte[] stream = savedGame( context, lock );
|
||||
|
@ -964,7 +984,7 @@ public class GameUtils {
|
|||
|
||||
saveGame( context, gamePtr, gi, lock, false );
|
||||
|
||||
GameSummary summary = new GameSummary( gi );
|
||||
GameSummary summary = new GameSummary( context, gi );
|
||||
XwJNI.game_summarize( gamePtr, summary );
|
||||
DBUtils.saveSummary( context, lock, summary );
|
||||
|
||||
|
|
|
@ -97,14 +97,16 @@ public class GamesList extends XWListActivity
|
|||
}
|
||||
};
|
||||
String message;
|
||||
String langName = DictLangCache.getLangName( this,
|
||||
m_missingDictLang );
|
||||
String langName =
|
||||
DictLangCache.getLangName( this, m_missingDictLang );
|
||||
String gameName = GameUtils.getName( this, m_rowid );
|
||||
if ( WARN_NODICT == id ) {
|
||||
message = String.format( getString(R.string.no_dictf),
|
||||
langName );
|
||||
message = String.format( getString( R.string.no_dictf ),
|
||||
gameName, langName );
|
||||
} else {
|
||||
message = String.format( getString(R.string.no_dict_substf),
|
||||
m_missingDictNames[0], langName );
|
||||
gameName, m_missingDictNames[0],
|
||||
langName );
|
||||
}
|
||||
|
||||
ab = new AlertDialog.Builder( this )
|
||||
|
@ -127,24 +129,26 @@ public class GamesList extends XWListActivity
|
|||
case SHOW_SUBST:
|
||||
m_sameLangDicts =
|
||||
DictLangCache.getHaveLangCounts( this, m_missingDictLang );
|
||||
ab = new AlertDialog.Builder( this )
|
||||
lstnr = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlg,
|
||||
int which ) {
|
||||
int pos = ((AlertDialog)dlg).getListView().
|
||||
getCheckedItemPosition();
|
||||
String dict = m_sameLangDicts[pos];
|
||||
dict = DictLangCache.stripCount( dict );
|
||||
GameUtils.replaceDicts( GamesList.this,
|
||||
m_missingDictRowId,
|
||||
m_missingDictNames[0],
|
||||
dict );
|
||||
}
|
||||
};
|
||||
dialog = new AlertDialog.Builder( this )
|
||||
.setTitle( R.string.subst_dict_title )
|
||||
.setPositiveButton( R.string.button_substdict, lstnr )
|
||||
.setNegativeButton( R.string.button_cancel, null )
|
||||
.setItems( m_sameLangDicts,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlg,
|
||||
int which ) {
|
||||
String dict = m_sameLangDicts[which];
|
||||
dict = DictLangCache.stripCount( dict );
|
||||
GameUtils.
|
||||
replaceDicts( GamesList.this,
|
||||
m_missingDictRowId,
|
||||
m_missingDictNames[0],
|
||||
dict );
|
||||
}
|
||||
})
|
||||
.setSingleChoiceItems( m_sameLangDicts, 0, null )
|
||||
.create();
|
||||
;
|
||||
dialog = ab.create();
|
||||
// Force destruction so onCreateDialog() will get
|
||||
// called next time and we can insert a different
|
||||
// list. There seems to be no way to change the list
|
||||
|
|
|
@ -67,10 +67,9 @@ public class RelayGameActivity extends XWActivity
|
|||
{
|
||||
super.onStart();
|
||||
|
||||
int gamePtr = XwJNI.initJNI();
|
||||
m_gi = new CurGameInfo( this );
|
||||
m_gameLock = new GameUtils.GameLock( m_rowid, true ).lock();
|
||||
GameUtils.loadMakeGame( this, gamePtr, m_gi, m_gameLock );
|
||||
int gamePtr = GameUtils.loadMakeGame( this, m_gi, m_gameLock );
|
||||
m_car = new CommsAddrRec( this );
|
||||
if ( XwJNI.game_hasComms( gamePtr ) ) {
|
||||
XwJNI.comms_getAddr( gamePtr, m_car );
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2010 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
|
||||
public class SDCardWatcher {
|
||||
public interface SDCardNotifiee {
|
||||
void cardMounted();
|
||||
}
|
||||
|
||||
private UmountReceiver m_rcvr;
|
||||
private Context m_context;
|
||||
private SDCardNotifiee m_notifiee;
|
||||
|
||||
private class UmountReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive( Context context, Intent intent )
|
||||
{
|
||||
if ( intent.getAction().
|
||||
equals( Intent.ACTION_MEDIA_MOUNTED ) ) {
|
||||
m_notifiee.cardMounted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SDCardWatcher( Context context, SDCardNotifiee notifiee )
|
||||
{
|
||||
m_context = context;
|
||||
m_rcvr = new UmountReceiver();
|
||||
m_notifiee = notifiee;
|
||||
|
||||
IntentFilter filter =
|
||||
new IntentFilter( Intent.ACTION_MEDIA_MOUNTED );
|
||||
// filter.addAction( Intent.ACTION_MEDIA_UNMOUNTED );
|
||||
// filter.addAction( Intent.ACTION_MEDIA_EJECT );
|
||||
filter.addDataScheme( "file" );
|
||||
|
||||
/*Intent intent = */context.getApplicationContext().
|
||||
registerReceiver( m_rcvr, filter );
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
m_context.getApplicationContext().unregisterReceiver( m_rcvr );
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@ public class XWActivity extends Activity {
|
|||
|
||||
private DlgDelegate m_delegate;
|
||||
|
||||
@Override
|
||||
protected void onCreate( Bundle savedInstanceState )
|
||||
{
|
||||
Utils.logf( "%s.onCreate(this=%H)", getClass().getName(), this );
|
||||
|
@ -84,10 +85,10 @@ public class XWActivity extends Activity {
|
|||
@Override
|
||||
protected Dialog onCreateDialog( int id )
|
||||
{
|
||||
Utils.logf( "%s.onCreateDialog() called", getClass().getName() );
|
||||
Dialog dialog = m_delegate.onCreateDialog( id );
|
||||
if ( null != dialog ) {
|
||||
setRemoveOnDismiss( dialog, id );
|
||||
Dialog dialog = super.onCreateDialog( id );
|
||||
if ( null == dialog ) {
|
||||
Utils.logf( "%s.onCreateDialog() called", getClass().getName() );
|
||||
dialog = m_delegate.onCreateDialog( id );
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
@ -100,6 +101,7 @@ public class XWActivity extends Activity {
|
|||
@Override
|
||||
protected void onPrepareDialog( int id, Dialog dialog )
|
||||
{
|
||||
super.onPrepareDialog( id, dialog ); // docs say should call through
|
||||
m_delegate.onPrepareDialog( id, dialog );
|
||||
}
|
||||
|
||||
|
@ -121,6 +123,11 @@ public class XWActivity extends Activity {
|
|||
m_delegate.showOKOnlyDialog( msgID );
|
||||
}
|
||||
|
||||
protected void showDictGoneFinish()
|
||||
{
|
||||
m_delegate.showDictGoneFinish();
|
||||
}
|
||||
|
||||
protected void showConfirmThen( int msgID,
|
||||
DialogInterface.OnClickListener action )
|
||||
{
|
||||
|
|
|
@ -106,6 +106,7 @@ public class XWListActivity extends ListActivity {
|
|||
@Override
|
||||
protected void onPrepareDialog( int id, Dialog dialog )
|
||||
{
|
||||
super.onPrepareDialog( id, dialog );
|
||||
m_delegate.onPrepareDialog( id, dialog );
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import junit.framework.Assert;
|
||||
import org.eehouse.android.xw4.R;
|
||||
import org.eehouse.android.xw4.Utils;
|
||||
|
@ -59,14 +60,16 @@ public class GameSummary {
|
|||
private int m_giFlags;
|
||||
private String m_playersSummary;
|
||||
private CurGameInfo m_gi;
|
||||
private Context m_context;
|
||||
|
||||
public GameSummary(){
|
||||
public GameSummary( Context context ) {
|
||||
m_context = context;
|
||||
pendingMsgLevel = 0;
|
||||
}
|
||||
|
||||
public GameSummary( CurGameInfo gi )
|
||||
public GameSummary( Context context, CurGameInfo gi )
|
||||
{
|
||||
this();
|
||||
this( context );
|
||||
nPlayers = gi.nPlayers;
|
||||
dictLang = gi.dictLang;
|
||||
serverRole = gi.serverRole;
|
||||
|
@ -78,28 +81,17 @@ public class GameSummary {
|
|||
return null != relayID;
|
||||
}
|
||||
|
||||
public String summarizePlayers( Context context )
|
||||
public String summarizePlayers()
|
||||
{
|
||||
String result;
|
||||
if ( null == m_gi ) {
|
||||
result = m_playersSummary;
|
||||
} else {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for ( int ii = 0; ; ) {
|
||||
|
||||
int score = 0;
|
||||
try {
|
||||
// scores can be null, but I've seen array OOB too.
|
||||
score = scores[ii];
|
||||
} catch ( Exception ex ){}
|
||||
|
||||
sb.append( m_gi.players[ii].name );
|
||||
if ( ++ii >= nPlayers ) {
|
||||
break;
|
||||
}
|
||||
sb.append( "\n" );
|
||||
String[] names = new String[nPlayers];
|
||||
for ( int ii = 0; ii < nPlayers; ++ii ) {
|
||||
names[ii] = m_gi.players[ii].name;
|
||||
}
|
||||
result = sb.toString();
|
||||
result = TextUtils.join( "\n", names );
|
||||
m_playersSummary = result;
|
||||
}
|
||||
return result;
|
||||
|
@ -110,25 +102,25 @@ public class GameSummary {
|
|||
m_playersSummary = summary;
|
||||
}
|
||||
|
||||
public String summarizeState( Context context )
|
||||
public String summarizeState()
|
||||
{
|
||||
String result = null;
|
||||
if ( gameOver ) {
|
||||
result = context.getString( R.string.gameOver );
|
||||
result = m_context.getString( R.string.gameOver );
|
||||
} else {
|
||||
result = String.format( context.getString(R.string.movesf),
|
||||
result = String.format( m_context.getString(R.string.movesf),
|
||||
nMoves );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String summarizeRole( Context context )
|
||||
public String summarizeRole()
|
||||
{
|
||||
String result = null;
|
||||
if ( isRelayGame() ) {
|
||||
Assert.assertTrue( CommsAddrRec.CommsConnType.COMMS_CONN_RELAY
|
||||
== conType );
|
||||
String fmt = context.getString( R.string.summary_fmt_relay );
|
||||
String fmt = m_context.getString( R.string.summary_fmt_relay );
|
||||
result = String.format( fmt, roomName );
|
||||
}
|
||||
return result;
|
||||
|
@ -175,14 +167,14 @@ public class GameSummary {
|
|||
m_giFlags = flags;
|
||||
}
|
||||
|
||||
public String summarizePlayer( Context context, int indx )
|
||||
public String summarizePlayer( int indx )
|
||||
{
|
||||
String player = players[indx];
|
||||
int formatID = 0;
|
||||
if ( !isLocal(indx) ) {
|
||||
boolean isMissing = 0 != ((1 << indx) & missingPlayers);
|
||||
if ( isMissing ) {
|
||||
player = context.getString( R.string.missing_player );
|
||||
player = m_context.getString( R.string.missing_player );
|
||||
} else {
|
||||
formatID = R.string.str_nonlocal_namef;
|
||||
}
|
||||
|
@ -191,12 +183,30 @@ public class GameSummary {
|
|||
}
|
||||
|
||||
if ( 0 != formatID ) {
|
||||
String format = context.getString( formatID );
|
||||
String format = m_context.getString( formatID );
|
||||
player = String.format( format, player );
|
||||
}
|
||||
return player;
|
||||
}
|
||||
|
||||
public String playerNames()
|
||||
{
|
||||
String[] names = null;
|
||||
if ( null != m_gi ) {
|
||||
names = m_gi.visibleNames();
|
||||
} else if ( null != m_playersSummary ) {
|
||||
names = TextUtils.split( m_playersSummary, "\n" );
|
||||
}
|
||||
|
||||
String result = null;
|
||||
if ( null != names && 0 < names.length ) {
|
||||
String joiner = m_context.getString( R.string.vs_join );
|
||||
result = TextUtils.join( joiner, names );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isNextToPlay( int indx ) {
|
||||
return indx == turn && isLocal(indx);
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ public class JNIThread extends Thread {
|
|||
XwJNI.server_do( m_jniGamePtr );
|
||||
|
||||
XwJNI.game_getGi( m_jniGamePtr, m_gi );
|
||||
GameSummary summary = new GameSummary( m_gi );
|
||||
GameSummary summary = new GameSummary( m_context, m_gi );
|
||||
XwJNI.game_summarize( m_jniGamePtr, summary );
|
||||
byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, null );
|
||||
GameUtils.saveGame( m_context, state, m_lock, false );
|
||||
|
|
|
@ -61,6 +61,7 @@ void
|
|||
stack_setBitsPerTile( StackCtxt* stack, XP_U16 bitsPerTile )
|
||||
{
|
||||
XP_ASSERT( !!stack );
|
||||
XP_ASSERT( bitsPerTile == 5 || bitsPerTile == 6 );
|
||||
stack->bitsPerTile = bitsPerTile;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,11 +225,17 @@ close_device() {
|
|||
unset ROOMS[$ID]
|
||||
}
|
||||
|
||||
OBITS=""
|
||||
|
||||
kill_from_log() {
|
||||
LOG=$1
|
||||
RELAYID=$(./scripts/relayID.sh --long $LOG)
|
||||
if [ -n "$RELAYID" ]; then
|
||||
../relay/rq -a $HOST -d $RELAYID 2>/dev/null || true
|
||||
OBITS="$OBITS -d $RELAYID"
|
||||
if [ 0 -eq $(($RANDOM%2)) ]; then
|
||||
../relay/rq -a $HOST $OBITS 2>/dev/null || true
|
||||
OBITS=""
|
||||
fi
|
||||
return 0 # success
|
||||
fi
|
||||
echo "unable to send kill command for $LOG"
|
||||
|
@ -281,10 +287,15 @@ check_game() {
|
|||
close_device $ID $DONEDIR "game over"
|
||||
done
|
||||
date
|
||||
# XWRELAY_ERROR_DELETED may be old
|
||||
elif grep -q 'relay_error_curses(XWRELAY_ERROR_DELETED)' $LOG; then
|
||||
echo "deleting $LOG $(connName $LOG) b/c another resigned"
|
||||
kill_from_log $LOG || true
|
||||
close_device $KEY $DEADDIR "other resigned"
|
||||
elif grep -q 'relay_error_curses(XWRELAY_ERROR_DEADGAME)' $LOG; then
|
||||
echo "deleting $LOG $(connName $LOG) b/c another resigned"
|
||||
kill_from_log $LOG || true
|
||||
close_device $KEY $DEADDIR "other resigned"
|
||||
else
|
||||
maybe_resign $KEY
|
||||
fi
|
||||
|
@ -334,6 +345,8 @@ run_cmds() {
|
|||
fi
|
||||
done
|
||||
|
||||
[ -n "$OBITS" ] && ../relay/rq -a $HOST $OBITS 2>/dev/null || true
|
||||
|
||||
# kill any remaining games
|
||||
if [ $COUNT -gt 0 ]; then
|
||||
mkdir -p ${LOGDIR}/not_done
|
||||
|
|
|
@ -176,15 +176,28 @@ cmdToStr( XWRELAY_Cmd cmd )
|
|||
}
|
||||
|
||||
static bool
|
||||
parseRelayID( const char* const in, char* buf, HostID* hid )
|
||||
parseRelayID( unsigned char** const inp, const unsigned char* const end,
|
||||
char* buf, int buflen, HostID* hid )
|
||||
{
|
||||
const char* hidp = strrchr( (char*)in, '/' );
|
||||
const char* hidp = strchr( (char*)*inp, '/' );
|
||||
|
||||
bool ok = NULL != hidp;
|
||||
int connNameLen;
|
||||
|
||||
if ( ok ) {
|
||||
int connNameLen = hidp - in;
|
||||
strncpy( buf, in, connNameLen );
|
||||
connNameLen = hidp - (char*)*inp;
|
||||
ok = connNameLen < buflen;
|
||||
}
|
||||
if ( ok ) {
|
||||
strncpy( buf, (char*)*inp, connNameLen );
|
||||
buf[connNameLen] = '\0';
|
||||
*hid = atoi( hidp+1 );
|
||||
char* endptr;
|
||||
*hid = strtol( hidp + 1, &endptr, 10 );
|
||||
if ( '\n' == *endptr ) {
|
||||
++endptr;
|
||||
}
|
||||
*inp = (unsigned char*)endptr;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
@ -728,43 +741,42 @@ handleMsgsMsg( int sock, bool sendFull,
|
|||
unsigned char* bufp, const unsigned char* end )
|
||||
{
|
||||
unsigned short nameCount;
|
||||
int ii;
|
||||
if ( getNetShort( &bufp, end, &nameCount ) ) {
|
||||
char* in = (char*)bufp;
|
||||
DBMgr* dbmgr = DBMgr::Get();
|
||||
unsigned short count;
|
||||
/* This is wrong now */
|
||||
/* reply format: PRX_GET_MSGS case: <message len><n_msgs>[<len><msg>]*
|
||||
* PRX_HAS_MSGS case: <message len><n_msgs><count>*
|
||||
*/
|
||||
vector<unsigned char> out(4); /* space for len and n_msgs */
|
||||
assert( out.size() == 4 );
|
||||
for ( ii = 0; ii < nameCount && bufp < end; ++ii ) {
|
||||
|
||||
char* saveptr;
|
||||
for ( count = 0; ; ++count ) {
|
||||
char* name = strtok_r( in, "\n", &saveptr );
|
||||
if ( NULL == name ) {
|
||||
break;
|
||||
}
|
||||
// See NetUtils.java for reply format
|
||||
// message-length: 2
|
||||
// nameCount: 2
|
||||
// name count reps of:
|
||||
// counts-this-name: 2
|
||||
// counts-this-name reps of
|
||||
// len: 2
|
||||
// msg: <len>
|
||||
|
||||
// pack msgs for one game
|
||||
HostID hid;
|
||||
char connName[MAX_CONNNAME_LEN+1];
|
||||
if ( !parseRelayID( name, connName, &hid ) ) {
|
||||
if ( !parseRelayID( &bufp, end, connName, sizeof(connName),
|
||||
&hid ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* For each relayID, write the number of messages and then each
|
||||
message (in the getmsg case) */
|
||||
/* For each relayID, write the number of messages and then
|
||||
each message (in the getmsg case) */
|
||||
int msgCount = dbmgr->PendingMsgCount( connName, hid );
|
||||
pushShort( out, msgCount );
|
||||
if ( sendFull ) {
|
||||
pushMsgs( out, dbmgr, connName, hid, msgCount );
|
||||
}
|
||||
|
||||
in = NULL;
|
||||
}
|
||||
|
||||
unsigned short tmp = htons( out.size() - sizeof(tmp) );
|
||||
memcpy( &out[0], &tmp, sizeof(tmp) );
|
||||
tmp = htons( count );
|
||||
tmp = htons( nameCount );
|
||||
memcpy( &out[2], &tmp, sizeof(tmp) );
|
||||
write( sock, &out[0], out.size() );
|
||||
}
|
||||
|
@ -817,24 +829,15 @@ handle_proxy_packet( unsigned char* buf, int len, int sock )
|
|||
if ( !getNetShort( &bufp, end, &seed ) ) {
|
||||
break;
|
||||
}
|
||||
unsigned char* crptr =
|
||||
(unsigned char*)strchr( (char*)bufp, '\n' );
|
||||
if ( NULL == crptr || crptr >= end ) {
|
||||
break;
|
||||
}
|
||||
*crptr = '\0';
|
||||
|
||||
HostID hid;
|
||||
char connName[MAX_CONNNAME_LEN+1];
|
||||
if ( !parseRelayID( (const char*)bufp, connName,
|
||||
&hid ) ) {
|
||||
if ( !parseRelayID( &bufp, end, connName,
|
||||
sizeof( connName ), &hid ) ) {
|
||||
break;
|
||||
}
|
||||
SafeCref scr( connName );
|
||||
scr.DeviceGone( hid, seed );
|
||||
|
||||
/* skip "\n" */
|
||||
bufp = crptr + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue