diff --git a/xwords4/android/XWords4/jni/xwjni.c b/xwords4/android/XWords4/jni/xwjni.c index e6dfc2895..601d0ae6a 100644 --- a/xwords4/android/XWords4/jni/xwjni.c +++ b/xwords4/android/XWords4/jni/xwjni.c @@ -1256,14 +1256,13 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1endGame } JNIEXPORT jstring JNICALL -Java_org_eehouse_android_xw4_jni_XwJNI_server_1listWordsPlayed +Java_org_eehouse_android_xw4_jni_XwJNI_model_1getWordsPlayed ( JNIEnv* env, jclass C, jint gamePtr, jint nMoves ) { jstring result; XWJNI_START_GLOBALS(); - XP_ASSERT( !!state->game.server ); XWStreamCtxt* stream = and_empty_stream( MPPARM(mpool) globals ); - server_listWordsPlayed( state->game.server, stream, nMoves ); + model_getWordsPlayed( state->game.model, nMoves, stream ); result = streamToJString( MPPARM(mpool) env, stream ); (*env)->DeleteLocalRef( env, result ); stream_destroy( stream ); @@ -1271,7 +1270,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1listWordsPlayed return result; } - JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_server_1sendChat ( JNIEnv* env, jclass C, jint gamePtr, jstring jmsg ) diff --git a/xwords4/android/XWords4/res/layout/wordlist_view.xml b/xwords4/android/XWords4/res/layout/wordlist_view.xml index 2fc096058..2fd980698 100644 --- a/xwords4/android/XWords4/res/layout/wordlist_view.xml +++ b/xwords4/android/XWords4/res/layout/wordlist_view.xml @@ -5,6 +5,21 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + + + + + 4.4 beta 34 //%1$s/newgame.php - - http://%1$s.thefreedictionary.com/_/dict.aspx?word=%2$s - For debugging You should never need these... @@ -152,19 +149,19 @@ - English - French - German - Turkish - Arabic - Spanish - Swedish - Polish - Danish - Italian - Dutch - Catalan - Portuguese + English + French + German + Turkish + Arabic + Spanish + Swedish + Polish + Danish + Italian + Dutch + Catalan + Portuguese Russian @@ -173,6 +170,45 @@ Slovak + + + en + fr + de + + + es + + + + it + + ca + + + + + + + + + + + + + Dictionary.com + :en: + http://dictionary.com/browse/%2$s --> + + TheFreeDictionary.com + :en:es: + http://%1$s.thefreedictionary.com/_/dict.aspx?word=%2$s + + Google + + http://www.google.com/search?nl=%1$s\u0026q=%2$s + + @string/game_summary_field_empty @string/game_summary_field_language diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml index b05c2b52c..270963d3f 100644 --- a/xwords4/android/XWords4/res/values/strings.xml +++ b/xwords4/android/XWords4/res/values/strings.xml @@ -1769,5 +1769,9 @@ Tap to lookup Done + Pick a site + Pick a site + Tap word to search + diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java index fe4a7fcf2..e56766b30 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java @@ -48,10 +48,12 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.EditText; import android.widget.ListView; +import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import junit.framework.Assert; import android.content.res.Configuration; +import android.content.res.Resources; import android.content.pm.ActivityInfo; import android.net.Uri; @@ -143,6 +145,10 @@ public class BoardActivity extends XWActivity private String m_room; private String m_toastStr; private String[] m_words; + private String[] m_langCodes; + private String[] m_lookupUrls; + private String[] m_lookupNames; + private int m_missing; private boolean m_haveInvited = false; @@ -242,15 +248,13 @@ public class BoardActivity extends XWActivity }; ab.setNegativeButton( R.string.button_no, lstnr ); } else if ( DLG_SCORES_BLK == id ) { - if ( curLangSupported() ) { - lstnr = new DialogInterface.OnClickListener() { - public void onClick( DialogInterface dialog, - int whichButton ) { - m_jniThread.handle( JNICmd.CMD_WORDS ); - } - }; - ab.setNegativeButton( R.string.button_lookup, lstnr ); - } + lstnr = new DialogInterface.OnClickListener() { + public void onClick( DialogInterface dialog, + int whichButton ) { + m_jniThread.handle( JNICmd.CMD_WORDS ); + } + }; + ab.setNegativeButton( R.string.button_lookup, lstnr ); } dialog = ab.create(); @@ -322,26 +326,9 @@ public class BoardActivity extends XWActivity } break; case DLG_WORDPICK: - LinearLayout layout = - (LinearLayout)Utils.inflate( this, R.layout.wordlist_view ); - ListView list = (ListView)layout.findViewById( R.id.words ); - ArrayAdapter adapter = - new ArrayAdapter( this, - //android.R.layout.select_dialog_item, - android.R.layout.simple_list_item_1, - m_words ) ; - list.setAdapter( adapter ); - OnItemClickListener oicl = new OnItemClickListener() { - public void onItemClick(AdapterView parent, - View view, - int position, long id ) { - lookupWord( m_words[position] ); - } - }; - list.setOnItemClickListener( oicl ); dialog = new AlertDialog.Builder( this ) .setTitle( R.string.title_lookup ) - .setView( layout ) + .setView( buildLookupDlg() ) .setNegativeButton( R.string.button_done, null ) .create(); Utils.setRemoveOnDismiss( this, dialog, id ); @@ -1284,8 +1271,8 @@ public class BoardActivity extends XWActivity TextUtils.split( (String)msg.obj, "\n" ); if ( 0 == m_words.length ) { // drop it - } else if ( 1 == m_words.length ) { - lookupWord( m_words[0] ); + // } else if ( 1 == m_words.length ) { + // lookupWord( m_words[0] ); } else { showDialog( DLG_WORDPICK ); } @@ -1562,9 +1549,42 @@ public class BoardActivity extends XWActivity } } - private void lookupWord( String word ) + private View buildLookupDlg() + { + initLookup(); + + LinearLayout layout = + (LinearLayout)Utils.inflate( this, R.layout.wordlist_view ); + + final Spinner spinner = + (Spinner)layout.findViewById( R.id.site_spinner ); + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_spinner_item, + m_lookupNames ); + spinner.setAdapter( adapter ); + + ListView list = (ListView)layout.findViewById( R.id.words ); + adapter = new ArrayAdapter( this, + //android.R.layout.select_dialog_item, + // android.R.layout.simple_list_item_1, + android.R.layout.select_dialog_item, + m_words ) ; + list.setAdapter( adapter ); + OnItemClickListener oicl = new OnItemClickListener() { + public void onItemClick(AdapterView parent, + View view, + int position, long id ) { + int urlPos = spinner.getSelectedItemPosition(); + lookupWord( m_words[position], m_lookupUrls[urlPos] ); + } + }; + list.setOnItemClickListener( oicl ); + + return layout; + } + + private void lookupWord( String word, String fmt ) { - String fmt = getString( R.string.word_lookupf ); String dict_url = String.format( fmt, curLangCode(), word ); Uri uri = Uri.parse( dict_url ); Intent intent = new Intent( Intent.ACTION_VIEW, uri ); @@ -1579,22 +1599,31 @@ public class BoardActivity extends XWActivity private String curLangCode() { - // from string-array name="language_names" in common_rsrc.xml - switch( m_gi.dictLang ) { - case 1: - return "en"; - case 2: - return "fr"; - case 3: - return "de"; - default: - return null; + initLookup(); + return m_langCodes[m_gi.dictLang]; + } + + private void initLookup() + { + if ( null == m_langCodes ) { + Resources res = getResources(); + m_langCodes = res.getStringArray( R.array.language_codes ); + + String[] urls = res.getStringArray( R.array.lookup_urls ); + ArrayList tmpUrls = new ArrayList(); + ArrayList tmpNames = new ArrayList(); + String langCode = + String.format( ":%s:", m_langCodes[m_gi.dictLang] ); + for ( int ii = 0; ii < urls.length; ii += 3 ) { + String codes = urls[ii+1]; + if ( 0 == codes.length() || codes.contains( langCode ) ) { + tmpNames.add( urls[ii] ); + tmpUrls.add( urls[ii+2] ); + } + } + m_lookupNames = tmpNames.toArray( new String[tmpNames.size()] ); + m_lookupUrls = tmpUrls.toArray( new String[tmpUrls.size()] ); } } - private boolean curLangSupported() - { - return null != curLangCode(); - } - } // class BoardActivity diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java index c95ac244f..a77ae330d 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java @@ -493,7 +493,7 @@ public class JNIThread extends Thread { break; case CMD_WORDS: - String words = XwJNI.server_listWordsPlayed( m_jniGamePtr, 1 ); + String words = XwJNI.model_getWordsPlayed( m_jniGamePtr, 1 ); Message.obtain( m_handler, GOT_WORDS, words ).sendToTarget(); break; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java index 1d3d951e1..c2d4e7fb6 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java @@ -209,7 +209,10 @@ public class XwJNI { public static native String model_writeGameHistory( int gamePtr, boolean gameOver ); public static native int model_getNMoves( int gamePtr ); - public static native String model_getPlayersLastScore( int gamePtr, int player ); + public static native String model_getPlayersLastScore( int gamePtr, + int player ); + public static native String model_getWordsPlayed( int gamePtr, + int nTurns ); // Server public static native void server_reset( int gamePtr ); @@ -221,8 +224,6 @@ public class XwJNI { public static native void server_initClientConnection( int gamePtr ); public static native void server_endGame( int gamePtr ); public static native void server_sendChat( int gamePtr, String msg ); - public static native String server_listWordsPlayed( int gamePtr, - int nMoves ); // hybrid to save work public static native boolean board_server_prefsChanged( int gamePtr, diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index 07526ab86..721e58679 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -1,4 +1,4 @@ -/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE"; -*- */ +/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */ /* * Copyright 2001-2011 by Eric House (xwords@eehouse.org). All rights * reserved. @@ -2170,12 +2170,10 @@ sendNoConn( CommsCtxt* comms, const MsgQueueElem* elem, XWHostID destID ) destID, elem->msg, elem->len ); if ( NULL != stream ) { XP_U16 len = stream_getSize( stream ); - XP_U8* buf = XP_MALLOC( comms->mpool, len ); - if ( buf != NULL ) { - stream_getBytes( stream, buf, len ); - success = (*comms->procs.sendNoConn)( buf, len, relayID, + if ( 0 < len ) { + success = (*comms->procs.sendNoConn)( stream_getPtr( stream ), + len, relayID, comms->procs.closure ); - XP_FREE( comms->mpool, buf ); } stream_destroy( stream ); } diff --git a/xwords4/common/model.c b/xwords4/common/model.c index 4f996ea60..92290be0a 100644 --- a/xwords4/common/model.c +++ b/xwords4/common/model.c @@ -2052,9 +2052,8 @@ recordWord( const XP_UCHAR* word, XP_Bool isLegal, void* closure ) return XP_TRUE; } -XP_Bool -model_getWordsPlayed( ModelCtxt* model, PoolContext* pool, - XP_U16 nTurns, XWStreamCtxt* stream ) +void +model_getWordsPlayed( ModelCtxt* model, XP_U16 nTurns, XWStreamCtxt* stream ) { XP_ASSERT( !!stream ); StackCtxt* stack = model->vol.stack; @@ -2067,7 +2066,7 @@ model_getWordsPlayed( ModelCtxt* model, PoolContext* pool, nTurns = nEntries; } - if ( model_undoLatestMoves( model, pool, nTurns, NULL, NULL ) ) { + if ( model_undoLatestMoves( model, NULL, nTurns, NULL, NULL ) ) { RecordWordsInfo info = { .stream = stream, .nWords = 0 }; WordNotifierInfo notifyInfo = { .proc = recordWord, .closure = &info, @@ -2083,7 +2082,6 @@ model_getWordsPlayed( ModelCtxt* model, PoolContext* pool, NULL ); } stack_destroy( tmpStack ); - return XP_TRUE; } XP_Bool diff --git a/xwords4/common/model.h b/xwords4/common/model.h index 5775b7c52..399f3df77 100644 --- a/xwords4/common/model.h +++ b/xwords4/common/model.h @@ -252,8 +252,8 @@ XP_S16 model_getPlayerScore( ModelCtxt* model, XP_S16 player ); XP_Bool model_getPlayersLastScore( ModelCtxt* model, XP_S16 player, XP_UCHAR* expl, XP_U16* explLen ); -XP_Bool model_getWordsPlayed( ModelCtxt* model, PoolContext* pool, - XP_U16 nTurns, XWStreamCtxt* stream ); +void model_getWordsPlayed( ModelCtxt* model, XP_U16 nTurns, + XWStreamCtxt* stream ); /* Have there been too many passes (so game should end)? */ XP_Bool model_recentPassCountOk( ModelCtxt* model ); diff --git a/xwords4/common/pool.c b/xwords4/common/pool.c index f8b35fda6..643a4baef 100644 --- a/xwords4/common/pool.c +++ b/xwords4/common/pool.c @@ -1,4 +1,4 @@ -/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */ +/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */ /* * Copyright 2000 by Eric House (xwords@eehouse.org). All rights reserved. * @@ -36,6 +36,13 @@ struct PoolContext { MPSLOT }; +#ifdef DEBUG +static void checkTilesLeft( const PoolContext* pool ); +#else +# define checkTilesLeft( pool ) +#endif + + PoolContext* pool_make( MPFORMAL_NOCOMMA ) { @@ -247,5 +254,18 @@ pool_initFromDict( PoolContext* pool, DictionaryCtxt* dict ) pool->blankIndex = -1; } #endif + checkTilesLeft( pool ); } /* pool_initFromDict */ +#ifdef DEBUG +static void +checkTilesLeft( const PoolContext* pool ) +{ + XP_U16 ii, count; + for ( count = 0, ii = 0; ii < pool->numFaces; ++ii ) { + count += pool->lettersLeft[ii]; + } + XP_ASSERT( count == pool->numTilesLeft ); +} +#endif + diff --git a/xwords4/common/server.c b/xwords4/common/server.c index d571e3d68..b8b637a47 100644 --- a/xwords4/common/server.c +++ b/xwords4/common/server.c @@ -2637,12 +2637,6 @@ server_formatRemainingTiles( ServerCtxt* server, XWStreamCtxt* stream, } } /* server_formatRemainingTiles */ -void -server_listWordsPlayed( ServerCtxt* server, XWStreamCtxt* stream, XP_U16 nMoves ) -{ - (void)model_getWordsPlayed( server->vol.model, server->pool, nMoves, stream ); -} - #define IMPOSSIBLY_LOW_SCORE -1000 void server_writeFinalScores( ServerCtxt* server, XWStreamCtxt* stream ) diff --git a/xwords4/common/server.h b/xwords4/common/server.h index e3c32a315..aa8e1351c 100644 --- a/xwords4/common/server.h +++ b/xwords4/common/server.h @@ -124,9 +124,6 @@ void server_formatDictCounts( ServerCtxt* server, XWStreamCtxt* stream, void server_formatRemainingTiles( ServerCtxt* server, XWStreamCtxt* stream, XP_S16 player ); -void server_listWordsPlayed( ServerCtxt* server, XWStreamCtxt* stream, - XP_U16 nMoves ); - void server_writeFinalScores( ServerCtxt* server, XWStreamCtxt* stream ); #ifdef CPLUS diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index 4acc1ac54..00fa196b4 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -1714,7 +1714,7 @@ gtk_util_playerScoreHeld( XW_UtilCtxt* uc, XP_U16 player ) XWStreamCtxt* stream = mem_stream_make( MEMPOOL globals->cGlobals.params->vtMgr, globals, CHANNEL_NONE, catOnClose ); - server_listWordsPlayed( globals->cGlobals.game.server, stream, 1000 ); + (void)model_getWordsPlayed( globals->cGlobals.game.model, 1000, stream ); stream_destroy( stream ); #else