mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +01:00
Merge branch 'android_branch' into send_in_background
This commit is contained in:
commit
98c2617613
24 changed files with 1826 additions and 608 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="26"
|
||||
android:versionCode="27"
|
||||
android:versionName="@string/app_version"
|
||||
>
|
||||
|
||||
|
@ -124,6 +124,18 @@
|
|||
|
||||
<service android:name="RelayService"/>
|
||||
|
||||
<receiver android:name=".MountEventReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_MOUNTED" />
|
||||
<data android:scheme="file" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_EJECT" />
|
||||
<data android:scheme="file" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
||||
<!-- <receiver android:name="NBSReceiver"> -->
|
||||
<!-- <intent-filter android:priority="10"> -->
|
||||
<!-- <action android:name="android.intent.action.DATA_SMS_RECEIVED" /> -->
|
||||
|
|
|
@ -1196,6 +1196,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1getState
|
|||
setBool( env, jgsi, "canHint", info.canHint );
|
||||
setBool( env, jgsi, "canRedo", info.canRedo);
|
||||
setBool( env, jgsi, "inTrade", info.inTrade );
|
||||
setBool( env, jgsi, "tradeTilesSelected", info.tradeTilesSelected );
|
||||
setBool( env, jgsi, "gameIsConnected", info.gameIsConnected );
|
||||
setBool( env, jgsi, "canShuffle", info.canShuffle );
|
||||
|
||||
|
|
|
@ -6,39 +6,26 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<b>Crosswords 4.4 beta 33 release</b>
|
||||
<b>Crosswords 4.4 beta 34 release</b>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Use the term "wordlist" instead of "dictionary" to not imply that
|
||||
there are definitions provided.</li>
|
||||
|
||||
<li>Add color of bonus hints -- the 2L etc. that appear on the board
|
||||
-- to set of editable colors</li>
|
||||
<li>Don't ignore user's choice of wordlists. THIS MEANS THAT
|
||||
IN-PROGRESS GAMES NOT USING ENGLISH WILL BREAK. (But they were broken
|
||||
anyway: using English when you didn't want them to.)</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>Vastly (IMO) improve exchanging tiles: when in exchange mode, draw
|
||||
board disabled, and replace toolbar with buttons for commiting or
|
||||
abandoning the exchange</li>
|
||||
|
||||
<li>Stop getting confused when there are multiple wordlists with the
|
||||
same name. They'll all show up, and can be deleted.</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>Don't lose language choice for a game if user downloads a new wordlist</li>
|
||||
|
||||
<li>Make a game's language one of several configurable attributes
|
||||
that can be displayed along with the game</li>
|
||||
|
||||
<li>Display relay connection state as being in one of three phases:
|
||||
configured, connected, and with all players present.</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>Fix a family of crashes that occurred when dialogs were up and
|
||||
memory got low: rare, but annoying.</li>
|
||||
<li>Change how recent score and bonus value are shown after long-tap
|
||||
on scoreboard entry or bonus square: use Android's Toast feature
|
||||
instead of drawing directly on the board</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
<string name="key_notagain_sync">key_notagain_sync</string>
|
||||
<string name="key_notagain_chat">key_notagain_chat</string>
|
||||
<string name="key_notagain_relay">key_notagain_relay</string>
|
||||
<string name="key_notagain_newgame">key_notagain_newgame</string>
|
||||
<string name="key_notagain_hintprev">key_notagain_hintprev</string>
|
||||
<string name="key_notagain_hintnext">key_notagain_hintnext</string>
|
||||
<string name="key_notagain_juggle">key_notagain_juggle</string>
|
||||
|
@ -69,7 +68,6 @@
|
|||
<string name="key_notagain_conndall">key_notagain_conndall</string>
|
||||
<string name="key_notagain_conndfirst">key_notagain_conndfirst</string>
|
||||
<string name="key_notagain_conndmid">key_notagain_conndmid</string>
|
||||
<string name="key_notagain_dicts">key_notagain_dicts</string>
|
||||
<string name="key_notagain_arrow">key_notagain_arrow</string>
|
||||
<string name="key_notagain_turnchanged">key_notagain_turnchanged</string>
|
||||
<string name="key_notagain_newfrom">key_notagain_newfrom</string>
|
||||
|
@ -80,7 +78,7 @@
|
|||
|
||||
<!-- <string name="default_host">10.0.2.2</string> -->
|
||||
<string name="dict_url">http://eehouse.org/and_wordlists</string>
|
||||
<string name="app_version">4.4 beta 33</string>
|
||||
<string name="app_version">4.4 beta 34</string>
|
||||
<string name="game_url_pathf">//%1$s/redir.php</string>
|
||||
|
||||
<!-- Debugging stuff. No point in localizing it. -->
|
||||
|
@ -90,6 +88,7 @@
|
|||
<string name="redir_host">Invite redirect host</string>
|
||||
<string name="dict_host">Wordlist download URL</string>
|
||||
<string name="logging_on">Enable logging</string>
|
||||
<string name="git_rev_title">Source version id</string>
|
||||
<string name="relay_port">Relay game port</string>
|
||||
<string name="proxy_port">Relay device port</string>
|
||||
<string name="name_dict_fmt">%1$s/%2$s</string>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1078,7 +1078,9 @@ public class BoardActivity extends XWActivity
|
|||
resid = R.string.str_no_peek_robot_tiles;
|
||||
break;
|
||||
case UtilCtxt.ERR_NO_EMPTY_TRADE:
|
||||
resid = R.string.str_no_empty_trade;
|
||||
// This should not be possible as the button's
|
||||
// disabled when no tiles selected.
|
||||
Assert.fail();
|
||||
break;
|
||||
case UtilCtxt.ERR_TOO_FEW_TILES_LEFT_TO_TRADE:
|
||||
resid = R.string.str_too_few_tiles_left_to_trade;
|
||||
|
@ -1223,9 +1225,9 @@ public class BoardActivity extends XWActivity
|
|||
updateToolbar();
|
||||
if ( m_inTrade != m_gsi.inTrade ) {
|
||||
m_inTrade = m_gsi.inTrade;
|
||||
adjustTradeVisibility();
|
||||
m_view.setInTrade( m_inTrade );
|
||||
}
|
||||
adjustTradeVisibility();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1437,6 +1439,9 @@ public class BoardActivity extends XWActivity
|
|||
{
|
||||
m_toolbar.setVisibility( m_inTrade? View.GONE : View.VISIBLE );
|
||||
m_tradeButtons.setVisibility( m_inTrade? View.VISIBLE : View.GONE );
|
||||
if ( m_inTrade ) {
|
||||
m_exchCommmitButton.setEnabled( m_gsi.tradeTilesSelected );
|
||||
}
|
||||
}
|
||||
|
||||
private void setBackgroundColor()
|
||||
|
|
|
@ -454,7 +454,7 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
|
|||
secondsLeft%60 );
|
||||
|
||||
fillRectOther( rect, CommonPrefs.COLOR_BACKGRND );
|
||||
m_fillPaint.setColor( adjustColor(m_playerColors[player]) );
|
||||
m_fillPaint.setColor( m_playerColors[player] );
|
||||
|
||||
Rect shorter = new Rect( rect );
|
||||
shorter.inset( 0, shorter.height() / 5 );
|
||||
|
|
|
@ -43,6 +43,9 @@ public class DBUtils {
|
|||
private static final String ROW_ID = "rowid";
|
||||
private static final String ROW_ID_FMT = "rowid=%d";
|
||||
|
||||
private static long s_cachedRowID = -1;
|
||||
private static byte[] s_cachedBytes = null;
|
||||
|
||||
public static interface DBChangeListener {
|
||||
public void gameSaved( long rowid );
|
||||
}
|
||||
|
@ -568,6 +571,8 @@ public class DBUtils {
|
|||
}
|
||||
db.close();
|
||||
}
|
||||
setCached( rowid, null ); // force reread
|
||||
|
||||
if ( -1 != rowid ) {
|
||||
notifyListeners( rowid );
|
||||
}
|
||||
|
@ -578,21 +583,24 @@ public class DBUtils {
|
|||
{
|
||||
long rowid = lock.getRowid();
|
||||
Assert.assertTrue( -1 != rowid );
|
||||
byte[] result = null;
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
byte[] result = getCached( rowid );
|
||||
if ( null == result ) {
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
|
||||
String[] columns = { DBHelper.SNAPSHOT };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
result = cursor.getBlob( cursor
|
||||
.getColumnIndex(DBHelper.SNAPSHOT));
|
||||
String[] columns = { DBHelper.SNAPSHOT };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
result = cursor.getBlob( cursor
|
||||
.getColumnIndex(DBHelper.SNAPSHOT));
|
||||
}
|
||||
cursor.close();
|
||||
db.close();
|
||||
}
|
||||
cursor.close();
|
||||
db.close();
|
||||
setCached( rowid, result );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -803,4 +811,20 @@ public class DBUtils {
|
|||
}
|
||||
}
|
||||
|
||||
// Trivial one-item cache. Typically bytes are read three times
|
||||
// in a row, so this saves two DB accesses per game opened. Could
|
||||
// use a HashMap, but then lots of half-K byte[] chunks would fail
|
||||
// to gc. This is good enough.
|
||||
private static byte[] getCached( long rowid )
|
||||
{
|
||||
byte[] result = s_cachedRowID == rowid ? s_cachedBytes : null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void setCached( long rowid, byte[] bytes )
|
||||
{
|
||||
s_cachedRowID = rowid;
|
||||
s_cachedBytes = bytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,6 +52,15 @@ public class DictUtils {
|
|||
public static final String INVITED = "invited";
|
||||
|
||||
private static DictAndLoc[] s_dictListCache = null;
|
||||
|
||||
static {
|
||||
MountEventReceiver.register( new MountEventReceiver.SDCardNotifiee() {
|
||||
public void cardMounted( boolean nowMounted )
|
||||
{
|
||||
invalDictList();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public static class DictPairs {
|
||||
public byte[][] m_bytes;
|
||||
|
@ -98,6 +107,13 @@ public class DictUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void invalDictList()
|
||||
{
|
||||
s_dictListCache = null;
|
||||
// Should I have a list of folks who want to know when this
|
||||
// changes?
|
||||
}
|
||||
|
||||
public static DictAndLoc[] dictList( Context context )
|
||||
{
|
||||
if ( null == s_dictListCache ) {
|
||||
|
@ -188,7 +204,7 @@ public class DictUtils {
|
|||
success = copyDict( context, name, from, to );
|
||||
if ( success ) {
|
||||
deleteDict( context, name, from );
|
||||
s_dictListCache = null;
|
||||
invalDictList();
|
||||
}
|
||||
}
|
||||
return success;
|
||||
|
@ -251,7 +267,7 @@ public class DictUtils {
|
|||
Assert.assertTrue( DictLoc.INTERNAL == loc );
|
||||
context.deleteFile( name );
|
||||
}
|
||||
s_dictListCache = null;
|
||||
invalDictList();
|
||||
}
|
||||
|
||||
public static void deleteDict( Context context, String name )
|
||||
|
@ -405,7 +421,7 @@ public class DictUtils {
|
|||
fos.write( buf, 0, nRead );
|
||||
}
|
||||
fos.close();
|
||||
s_dictListCache = null;
|
||||
invalDictList();
|
||||
success = true;
|
||||
} catch ( java.io.FileNotFoundException fnf ) {
|
||||
Utils.logf( "saveDict: FileNotFoundException: %s",
|
||||
|
|
|
@ -23,13 +23,12 @@ package org.eehouse.android.xw4;
|
|||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.ListActivity;
|
||||
import android.app.ExpandableListActivity;
|
||||
import android.database.DataSetObserver;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.AdapterView;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
|
@ -48,6 +47,7 @@ import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
|
|||
import android.widget.Toast;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.net.Uri;
|
||||
import java.util.HashMap;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.DictUtils.DictAndLoc;
|
||||
|
@ -57,7 +57,7 @@ import org.eehouse.android.xw4.jni.CommonPrefs;
|
|||
|
||||
public class DictsActivity extends ExpandableListActivity
|
||||
implements View.OnClickListener, XWListItem.DeleteCallback,
|
||||
SDCardWatcher.SDCardNotifiee, DlgDelegate.DlgClickNotify {
|
||||
MountEventReceiver.SDCardNotifiee, DlgDelegate.DlgClickNotify {
|
||||
|
||||
private static final String DICT_DOLAUNCH = "do_launch";
|
||||
private static final String DICT_LANG_EXTRA = "use_lang";
|
||||
|
@ -69,6 +69,9 @@ public class DictsActivity extends ExpandableListActivity
|
|||
private static final String MOVEFROMLOC = "movefromloc";
|
||||
private static final String MOVETOLOC = "movetoloc";
|
||||
|
||||
private static HashMap<String,Boolean> s_openStates =
|
||||
new HashMap<String,Boolean>();
|
||||
|
||||
// For new callback alternative
|
||||
private static final int DELETE_DICT_ACTION = 1;
|
||||
|
||||
|
@ -88,7 +91,6 @@ public class DictsActivity extends ExpandableListActivity
|
|||
private long m_packedPosition;
|
||||
private DictUtils.DictLoc m_moveFromLoc;
|
||||
private DictUtils.DictLoc m_moveToLoc;
|
||||
private SDCardWatcher m_cardWatcher;
|
||||
|
||||
private LayoutInflater m_factory;
|
||||
|
||||
|
@ -207,8 +209,13 @@ public class DictsActivity extends ExpandableListActivity
|
|||
public boolean isChildSelectable( int groupPosition,
|
||||
int childPosition ) { return true; }
|
||||
public boolean isEmpty() { return false; }
|
||||
public void onGroupCollapsed(int groupPosition){}
|
||||
public void onGroupExpanded(int groupPosition){}
|
||||
public void onGroupCollapsed(int groupPosition)
|
||||
{
|
||||
s_openStates.put( m_langs[groupPosition], false );
|
||||
}
|
||||
public void onGroupExpanded(int groupPosition){
|
||||
s_openStates.put( m_langs[groupPosition], true );
|
||||
}
|
||||
public void registerDataSetObserver( DataSetObserver obs ){}
|
||||
public void unregisterDataSetObserver( DataSetObserver obs ){}
|
||||
|
||||
|
@ -375,7 +382,8 @@ public class DictsActivity extends ExpandableListActivity
|
|||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
m_cardWatcher = new SDCardWatcher( this, this );
|
||||
MountEventReceiver.register( this );
|
||||
|
||||
mkListAdapter();
|
||||
expandGroups();
|
||||
}
|
||||
|
@ -418,10 +426,9 @@ public class DictsActivity extends ExpandableListActivity
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
m_cardWatcher.close();
|
||||
m_cardWatcher = null;
|
||||
super.onPause();
|
||||
protected void onStop() {
|
||||
MountEventReceiver.unregister( this );
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
public void onClick( View v )
|
||||
|
@ -560,14 +567,22 @@ public class DictsActivity extends ExpandableListActivity
|
|||
}
|
||||
}
|
||||
|
||||
m_delegate.showConfirmThen( msg, DELETE_DICT_ACTION );
|
||||
m_delegate.showConfirmThen( msg, R.string.button_delete,
|
||||
DELETE_DICT_ACTION );
|
||||
}
|
||||
|
||||
// SDCardWatcher.SDCardNotifiee interface
|
||||
public void cardMounted()
|
||||
// MountEventReceiver.SDCardNotifiee interface
|
||||
public void cardMounted( boolean nowMounted )
|
||||
{
|
||||
mkListAdapter();
|
||||
expandGroups();
|
||||
Utils.logf( "DictsActivity.cardMounted(%b)", nowMounted );
|
||||
// post so other SDCardNotifiee implementations get a chance
|
||||
// to process first: avoid race conditions
|
||||
new Handler().post( new Runnable() {
|
||||
public void run() {
|
||||
mkListAdapter();
|
||||
expandGroups();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
|
@ -589,6 +604,7 @@ public class DictsActivity extends ExpandableListActivity
|
|||
DictUtils.deleteDict( this, dict, loc );
|
||||
DictLangCache.inval( this, dict, loc, false );
|
||||
mkListAdapter();
|
||||
expandGroups();
|
||||
}
|
||||
|
||||
private void askStartDownload( int lang, String name )
|
||||
|
@ -623,7 +639,14 @@ public class DictsActivity extends ExpandableListActivity
|
|||
private void expandGroups()
|
||||
{
|
||||
for ( int ii = 0; ii < m_langs.length; ++ii ) {
|
||||
m_expView.expandGroup( ii );
|
||||
boolean open = true;
|
||||
String lang = m_langs[ii];
|
||||
if ( s_openStates.containsKey( lang ) ) {
|
||||
open = s_openStates.get( lang );
|
||||
}
|
||||
if ( open ) {
|
||||
m_expView.expandGroup( ii );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ public class DlgDelegate {
|
|||
private static final String CALLBACK = "callback";
|
||||
private static final String MSGID = "msgid";
|
||||
private static final String PREFSKEY = "prefskey";
|
||||
private static final String POSBUTTON = "posbutton";
|
||||
|
||||
// Cache a couple of callback implementations that never change:
|
||||
private DialogInterface.OnClickListener m_cbkOnClickLstnr = null;
|
||||
|
@ -64,6 +65,7 @@ public class DlgDelegate {
|
|||
}
|
||||
|
||||
private int m_msgID;
|
||||
private int m_posButton;
|
||||
private int m_cbckID = 0; // if this can be set twice I have a
|
||||
// problem. See asserts below.
|
||||
private String m_msg;
|
||||
|
@ -82,6 +84,7 @@ public class DlgDelegate {
|
|||
m_msg = bundle.getString( MSG );
|
||||
m_cbckID = bundle.getInt( CALLBACK );
|
||||
m_msgID = bundle.getInt( MSGID );
|
||||
m_posButton = bundle.getInt( POSBUTTON );
|
||||
m_prefsKey = bundle.getInt( PREFSKEY );
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +94,7 @@ public class DlgDelegate {
|
|||
outState.putString( MSG, m_msg );
|
||||
outState.putInt( CALLBACK, m_cbckID );
|
||||
outState.putInt( MSGID, m_msgID );
|
||||
outState.putInt( POSBUTTON, m_posButton );
|
||||
outState.putInt( PREFSKEY, m_prefsKey );
|
||||
}
|
||||
|
||||
|
@ -137,6 +141,8 @@ public class DlgDelegate {
|
|||
ad.setMessage( m_activity.getString(m_msgID) );
|
||||
break;
|
||||
case CONFIRM_THEN:
|
||||
ad.getButton(AlertDialog.BUTTON_POSITIVE).
|
||||
setText( m_activity.getString( m_posButton ) );
|
||||
ad.setMessage( m_msg );
|
||||
break;
|
||||
}
|
||||
|
@ -185,8 +191,14 @@ public class DlgDelegate {
|
|||
}
|
||||
|
||||
public void showConfirmThen( String msg, int callbackID )
|
||||
{
|
||||
showConfirmThen( msg, R.string.button_ok, callbackID );
|
||||
}
|
||||
|
||||
public void showConfirmThen( String msg, int posButton, int callbackID )
|
||||
{
|
||||
m_msg = msg;
|
||||
m_posButton = posButton;
|
||||
Assert.assertTrue( 0 != callbackID );
|
||||
Assert.assertTrue( 0 == m_cbckID );
|
||||
m_cbckID = callbackID;
|
||||
|
|
|
@ -518,7 +518,7 @@ public class GamesList extends XWListActivity
|
|||
case R.id.gamel_menu_delete_all:
|
||||
if ( DBUtils.gamesList( this ).length > 0 ) {
|
||||
showConfirmThen( R.string.confirm_delete_all,
|
||||
DELETE_ALL_ACTION );
|
||||
R.string.button_delete, DELETE_ALL_ACTION );
|
||||
}
|
||||
handled = true;
|
||||
break;
|
||||
|
@ -561,12 +561,14 @@ public class GamesList extends XWListActivity
|
|||
m_rowid = DBUtils.gamesList( this )[position];
|
||||
|
||||
if ( R.id.list_item_delete == menuID ) {
|
||||
showConfirmThen( R.string.confirm_delete, DELETE_GAME_ACTION );
|
||||
showConfirmThen( R.string.confirm_delete, R.string.button_delete,
|
||||
DELETE_GAME_ACTION );
|
||||
} else {
|
||||
if ( checkWarnNoDict( m_rowid ) ) {
|
||||
switch ( menuID ) {
|
||||
case R.id.list_item_reset:
|
||||
showConfirmThen( R.string.confirm_reset, RESET_GAME_ACTION );
|
||||
showConfirmThen( R.string.confirm_reset,
|
||||
R.string.button_reset, RESET_GAME_ACTION );
|
||||
break;
|
||||
case R.id.list_item_config:
|
||||
GameUtils.doConfig( this, m_rowid, GameConfig.class );
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- 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 java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class MountEventReceiver extends BroadcastReceiver {
|
||||
|
||||
public interface SDCardNotifiee {
|
||||
void cardMounted( boolean nowMounted );
|
||||
}
|
||||
|
||||
private static HashSet<SDCardNotifiee> s_procs = new HashSet<SDCardNotifiee>();
|
||||
|
||||
@Override
|
||||
public void onReceive( Context context, Intent intent )
|
||||
{
|
||||
Utils.logf( "MountEventReceiver.onReceive(%s)", intent.getAction() );
|
||||
synchronized( s_procs ) {
|
||||
do {
|
||||
if ( s_procs.isEmpty() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
boolean mounted;
|
||||
String action = intent.getAction();
|
||||
if ( action.equals( Intent.ACTION_MEDIA_MOUNTED ) ) {
|
||||
mounted = true;
|
||||
} else if ( action.equals( Intent.ACTION_MEDIA_EJECT ) ) {
|
||||
mounted = false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
Iterator<SDCardNotifiee> iter = s_procs.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
iter.next().cardMounted( mounted );
|
||||
}
|
||||
} while ( false );
|
||||
}
|
||||
}
|
||||
|
||||
public static void register( SDCardNotifiee proc )
|
||||
{
|
||||
synchronized( s_procs ) {
|
||||
s_procs.add( proc );
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregister( SDCardNotifiee proc )
|
||||
{
|
||||
synchronized( s_procs ) {
|
||||
s_procs.remove( proc );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/* -*- 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 );
|
||||
}
|
||||
}
|
|
@ -84,6 +84,13 @@ public class Utils {
|
|||
}
|
||||
} // logf
|
||||
|
||||
public static void showf( Context context, String format, Object... args )
|
||||
{
|
||||
Formatter formatter = new Formatter();
|
||||
String msg = formatter.format( format, args ).toString();
|
||||
Toast.makeText( context, msg, Toast.LENGTH_SHORT ).show();
|
||||
} // showf
|
||||
|
||||
public static void printStack( StackTraceElement[] trace )
|
||||
{
|
||||
if ( s_doLog ) {
|
||||
|
|
|
@ -137,6 +137,11 @@ public class XWListActivity extends ListActivity
|
|||
showConfirmThen( getString(msg), action );
|
||||
}
|
||||
|
||||
protected void showConfirmThen( int msg, int posButton, int action )
|
||||
{
|
||||
m_delegate.showConfirmThen( getString(msg), posButton, action );
|
||||
}
|
||||
|
||||
protected void doSyncMenuitem()
|
||||
{
|
||||
m_delegate.doSyncMenuitem();
|
||||
|
|
|
@ -94,6 +94,7 @@ public class JNIThread extends Thread {
|
|||
public boolean canHint;
|
||||
public boolean canRedo;
|
||||
public boolean inTrade;
|
||||
public boolean tradeTilesSelected;
|
||||
public boolean gameIsConnected;
|
||||
public boolean canShuffle;
|
||||
public GameStateInfo clone() {
|
||||
|
|
|
@ -4,18 +4,30 @@ set -u -e
|
|||
|
||||
declare -A ENG_IDS
|
||||
LOCS=""
|
||||
LIST_ONLY=""
|
||||
PAIRS_ONLY=""
|
||||
SEARCH_SOURCE=1
|
||||
|
||||
ENG=~/dev/git/ANDROID_BRANCH/xwords4/android/XWords4/res/values/strings.xml
|
||||
# ENG=~/dev/git/ANDROID_BRANCH/xwords4/android/XWords4/res/values/strings.xml
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [--loc <path_to_strings.xml>]*" >&2
|
||||
echo "usage: $0 (--loc <path_to_strings.xml>)+ [--list-only] [--pairs-only]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
list_ids() {
|
||||
XML_FILE=$1
|
||||
xmlstarlet sel -T -t -m "/resources/string" -v @name -o " " $XML_FILE
|
||||
xmlstarlet sel -T -t -m "/resources/string" -v @name -n $XML_FILE
|
||||
}
|
||||
|
||||
list_pairs() {
|
||||
XML_FILE=$1
|
||||
#xmlstarlet sel -t -m "//string" -v @name -o ':' -v . -n $XML_FILE | tr -d '\n' | sed 's, *, ,g'
|
||||
for NAME in $(list_ids $XML_FILE); do
|
||||
xmlstarlet sel -t -m "//string[@name='$NAME']" -v @name -o ':' -v . $XML_FILE \
|
||||
| tr -d '\n' | sed 's, *, ,g'
|
||||
echo ""
|
||||
done
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
|
@ -26,6 +38,12 @@ while [ $# -gt 0 ]; do
|
|||
LOCS="$LOCS $2"
|
||||
shift
|
||||
;;
|
||||
--list-only)
|
||||
LIST_ONLY=1
|
||||
;;
|
||||
--pairs-only)
|
||||
PAIRS_ONLY=1
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
|
@ -33,9 +51,27 @@ while [ $# -gt 0 ]; do
|
|||
shift
|
||||
done
|
||||
|
||||
[ -n "$LOCS" ] || usage
|
||||
|
||||
if [ -n "$LIST_ONLY" ]; then
|
||||
for LOC in $LOCS; do
|
||||
list_ids $LOC
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -n "$PAIRS_ONLY" ]; then
|
||||
for LOC in $LOCS; do
|
||||
list_pairs $LOC
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# echo "checking $ENG for ids not in any .java file"
|
||||
for ID in $(list_ids $ENG); do
|
||||
ENG_IDS[$ID]=1
|
||||
for LOC in $LOCS; do
|
||||
for ID in $(list_ids $LOC); do
|
||||
ENG_IDS[$ID]=1
|
||||
done
|
||||
done
|
||||
|
||||
if [ -n "$SEARCH_SOURCE" ]; then
|
||||
|
|
|
@ -748,11 +748,7 @@ board_commitTurn( BoardCtxt* board )
|
|||
if ( board->gameOver || turn < 0 ) {
|
||||
/* do nothing */
|
||||
} else if ( turn != board->selPlayer ) {
|
||||
if ( board->selInfo->tradeInProgress ) {
|
||||
result = exitTradeMode( board );
|
||||
} else {
|
||||
util_userError( board->util, ERR_NOT_YOUR_TURN );
|
||||
}
|
||||
util_userError( board->util, ERR_NOT_YOUR_TURN );
|
||||
} else if ( 0 == model_getNumTilesTotal( board->model, turn ) ) {
|
||||
/* game's over but still undoable so turn hasn't changed; do
|
||||
nothing */
|
||||
|
@ -761,14 +757,14 @@ board_commitTurn( BoardCtxt* board )
|
|||
TileBit traySelBits = pti->traySelBits;
|
||||
result = XP_TRUE; /* there's at least the window to clean up
|
||||
after */
|
||||
/* server_commitTrade() changes selPlayer, so board_endTrade
|
||||
must be called first() */
|
||||
(void)board_endTrade( board );
|
||||
|
||||
if ( NO_TILES == traySelBits ) {
|
||||
util_userError( board->util, ERR_NO_EMPTY_TRADE );
|
||||
} else if ( util_userQuery( board->util, QUERY_COMMIT_TRADE,
|
||||
(XWStreamCtxt*)NULL ) ) {
|
||||
/* server_commitTrade() changes selPlayer, so board_endTrade
|
||||
must be called first() */
|
||||
(void)board_endTrade( board );
|
||||
(void)server_commitTrade( board->server, traySelBits );
|
||||
}
|
||||
} else {
|
||||
|
@ -1594,9 +1590,12 @@ board_flip( BoardCtxt* board )
|
|||
} /* board_flip */
|
||||
|
||||
XP_Bool
|
||||
board_inTrade( const BoardCtxt* board )
|
||||
board_inTrade( const BoardCtxt* board, XP_Bool* anySelected )
|
||||
{
|
||||
const PerTurnInfo* pti = &board->pti[board->selPlayer];
|
||||
if ( !!anySelected ) {
|
||||
*anySelected = 0 != pti->traySelBits;
|
||||
}
|
||||
return pti->tradeInProgress;
|
||||
}
|
||||
|
||||
|
@ -2099,7 +2098,7 @@ board_beginTrade( BoardCtxt* board )
|
|||
XP_Bool
|
||||
board_endTrade( BoardCtxt* board )
|
||||
{
|
||||
XP_Bool result = board_inTrade( board );
|
||||
XP_Bool result = board_inTrade( board, NULL );
|
||||
if ( result ) {
|
||||
PerTurnInfo* pti = board->selInfo;
|
||||
invalSelTradeWindow( board );
|
||||
|
|
|
@ -100,7 +100,7 @@ XP_Bool board_draw( BoardCtxt* board );
|
|||
|
||||
XP_Bool board_get_flipped( const BoardCtxt* board );
|
||||
XP_Bool board_flip( BoardCtxt* board );
|
||||
XP_Bool board_inTrade( const BoardCtxt* board );
|
||||
XP_Bool board_inTrade( const BoardCtxt* board, XP_Bool* anySelected );
|
||||
XP_Bool board_get_showValues( const BoardCtxt* board );
|
||||
XP_Bool board_toggle_showValues( BoardCtxt* board );
|
||||
XP_Bool board_replaceTiles( BoardCtxt* board );
|
||||
|
|
|
@ -283,7 +283,7 @@ game_getState( const XWGame* game, GameStateInfo* gsi )
|
|||
gsi->visTileCount = board_visTileCount( game->board );
|
||||
gsi->canHint = board_canHint( game->board );
|
||||
gsi->canRedo = board_canTogglePending( game->board );
|
||||
gsi->inTrade = board_inTrade( game->board );
|
||||
gsi->inTrade = board_inTrade( game->board, &gsi->tradeTilesSelected );
|
||||
gsi->gameIsConnected = !!game->comms && comms_canChat( game->comms );
|
||||
gsi->canShuffle = board_canShuffle( game->board );
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ typedef struct _GameStateInfo {
|
|||
XP_Bool canHint;
|
||||
XP_Bool canRedo;
|
||||
XP_Bool inTrade;
|
||||
XP_Bool tradeTilesSelected;
|
||||
XP_Bool gameIsConnected;
|
||||
XP_Bool canShuffle;
|
||||
} GameStateInfo;
|
||||
|
|
|
@ -2135,6 +2135,8 @@ server_commitTrade( ServerCtxt* server, TileBit selBits )
|
|||
pool_replaceTiles( server->pool, &oldTiles );
|
||||
model_makeTileTrade( server->vol.model, server->nv.currentTurn,
|
||||
&oldTiles, &newTiles );
|
||||
sortTilesIf( server, turn );
|
||||
|
||||
nextTurn( server, PICK_NEXT );
|
||||
return XP_TRUE;
|
||||
} /* server_commitTrade */
|
||||
|
|
45
xwords4/scripts/git-cat.sh
Executable file
45
xwords4/scripts/git-cat.sh
Executable file
|
@ -0,0 +1,45 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -u -e
|
||||
|
||||
REV=HEAD
|
||||
BRANCH=""
|
||||
FILES=""
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [--branch BRANCH | --rev REV ] path/to/file [path/to/file]*"
|
||||
exit 0
|
||||
}
|
||||
|
||||
while [ $# -ge 1 ]; do
|
||||
case $1 in
|
||||
--branch)
|
||||
shift
|
||||
[ $# -gt 1 ] || usage "--branch requires a parameter"
|
||||
BRANCH=$1
|
||||
;;
|
||||
--rev)
|
||||
shift
|
||||
[ $# -gt 1 ] || usage "--rev requires a parameter"
|
||||
REV=$1
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
FILES="$FILES $1"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[ -n "$FILES" ] || usage
|
||||
|
||||
if [ -n "$BRANCH" ]; then
|
||||
REV=$(git log $BRANCH | grep '^commit' | head -n 1 | awk '{print $2}')
|
||||
fi
|
||||
|
||||
for FILE in $FILES; do
|
||||
FILE=$(git ls-files --full-name $FILE)
|
||||
git show $REV:$FILE
|
||||
done
|
Loading…
Reference in a new issue