mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-15 08:47:56 +01:00
Display "legal phonies" using same code as studylist words
Converted studylist to Kotlin, then made most of it a superclass from which legal phonies display also inherits
This commit is contained in:
parent
cb540c23c0
commit
21990ece1c
19 changed files with 777 additions and 597 deletions
|
@ -65,7 +65,6 @@ public class DlgDelegate {
|
|||
LAUNCH_AFTER_DEL,
|
||||
CLEAR_INT_STATS, // debug only
|
||||
RESTART,
|
||||
LPS_CLEAR,
|
||||
|
||||
// BoardDelegate
|
||||
UNDO_LAST_ACTION,
|
||||
|
|
|
@ -1460,11 +1460,6 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
openWithChecks( rowid, summary );
|
||||
break;
|
||||
|
||||
case LPS_CLEAR:
|
||||
int nDeleted = XwJNI.dvc_clearLegalPhonies();
|
||||
Utils.showToast( m_activity, R.string.cleared_lps_fmt, nDeleted );
|
||||
break;
|
||||
|
||||
case BACKUP_DO:
|
||||
showDialogFragment( DlgID.BACKUP_LOADSTORE );
|
||||
break;
|
||||
|
@ -1826,8 +1821,8 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
enable = nothingSelected && Utils.isGooglePlayApp( m_activity );
|
||||
Utils.setItemVisible( menu, R.id.games_menu_rateme, enable );
|
||||
|
||||
enable = BuildConfig.NON_RELEASE && XwJNI.dvc_haveLegalPhonies();
|
||||
Utils.setItemVisible( menu, R.id.games_submenu_legalPhonies, enable );
|
||||
enable = LegalPhoniesDelegate.haveLegalPhonies(m_activity);
|
||||
Utils.setItemVisible( menu, R.id.games_menu_legalPhonies, enable );
|
||||
|
||||
enable = nothingSelected && XWPrefs.getStudyEnabled( m_activity )
|
||||
&& 0 < DBUtils.studyListLangs( m_activity ).length;
|
||||
|
@ -1921,14 +1916,8 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
}
|
||||
break;
|
||||
|
||||
case R.id.games_menu_clearLPs:
|
||||
makeConfirmThenBuilder( Action.LPS_CLEAR,
|
||||
R.string.confirm_clear_lps )
|
||||
.show();
|
||||
break;
|
||||
case R.id.games_menu_listLPs:
|
||||
String txt = XwJNI.dvc_listLegalPhonies();
|
||||
makeOkOnlyBuilder( txt ).show();
|
||||
case R.id.games_menu_legalPhonies:
|
||||
LegalPhoniesDelegate.launch( getDelegator() );
|
||||
break;
|
||||
|
||||
case R.id.games_menu_study:
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
|
||||
/*
|
||||
* Copyright 2024 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.Context
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Spinner
|
||||
import org.eehouse.android.xw4.jni.GameSummary
|
||||
|
||||
import java.util.HashMap
|
||||
|
||||
abstract class IsoWordsBase(delegator: Delegator, sis: Bundle?,
|
||||
private val CHECKED_KEY: String )
|
||||
: ListDelegateBase(delegator, sis, R.layout.studylist, R.menu.studylist),
|
||||
SelectableItem,
|
||||
View.OnLongClickListener, View.OnClickListener,
|
||||
AdapterView.OnItemSelectedListener
|
||||
{
|
||||
val m_activity = delegator.getActivity()
|
||||
|
||||
var m_pickView: LabeledSpinner? = null
|
||||
var m_spinner: Spinner? = null
|
||||
var m_langCodes: Array<Utils.ISOCode>? = null
|
||||
var m_words: Array<String>? = arrayOf()
|
||||
val m_checkeds = HashSet<String>()
|
||||
var m_langPosition: Int = 0
|
||||
var m_adapter: SLWordsAdapter? = null
|
||||
private var m_origTitle: String? = null
|
||||
|
||||
// Subclasses must override these
|
||||
abstract fun getData(context: Context): HashMap<Utils.ISOCode, Array<String>>
|
||||
abstract fun clearWords(isoCode: Utils.ISOCode, words: Array<String> )
|
||||
abstract fun getTitleID(): Int
|
||||
|
||||
override fun init( sis: Bundle? )
|
||||
{
|
||||
m_pickView = findViewById( R.id.pick_lang ) as LabeledSpinner
|
||||
m_spinner = m_pickView?.getSpinner()
|
||||
|
||||
getBundledData( sis )
|
||||
|
||||
initOrFinish( getArguments() )
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu( menu: Menu): Boolean
|
||||
{
|
||||
val nSel = m_checkeds.size
|
||||
Utils.setItemVisible( menu, R.id.slmenu_copy_sel, 0 < nSel )
|
||||
Utils.setItemVisible( menu, R.id.slmenu_clear_sel, 0 < nSel )
|
||||
Utils.setItemVisible( menu, R.id.slmenu_select_all,
|
||||
m_words!!.size > nSel )
|
||||
Utils.setItemVisible( menu, R.id.slmenu_deselect_all, 0 < nSel )
|
||||
|
||||
val enable = 1 == nSel
|
||||
if ( enable ) {
|
||||
val title = getString( R.string.button_lookup_fmt,
|
||||
getSelWords()!![0] )
|
||||
menu.findItem( R.id.slmenu_lookup_sel ).setTitle( title )
|
||||
}
|
||||
Utils.setItemVisible( menu, R.id.slmenu_lookup_sel, enable )
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override protected fun handleBackPressed(): Boolean
|
||||
{
|
||||
val handled = 0 < m_checkeds.size
|
||||
if ( handled ) {
|
||||
clearSels()
|
||||
}
|
||||
return handled
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected( item: MenuItem): Boolean
|
||||
{
|
||||
var handled = true
|
||||
when ( item.getItemId() ) {
|
||||
R.id.slmenu_copy_sel -> {
|
||||
makeNotAgainBuilder( R.string.key_na_studycopy,
|
||||
DlgDelegate.Action.SL_COPY_ACTION,
|
||||
R.string.not_again_studycopy )
|
||||
.show()
|
||||
}
|
||||
R.id.slmenu_clear_sel -> {
|
||||
val msg = getQuantityString( R.plurals.confirm_studylist_clear_fmt,
|
||||
m_checkeds.size, m_checkeds.size )
|
||||
makeConfirmThenBuilder( DlgDelegate.Action.SL_CLEAR_ACTION, msg ).show()
|
||||
}
|
||||
|
||||
R.id.slmenu_select_all -> {
|
||||
m_checkeds.addAll( m_words!! )
|
||||
makeAdapter()
|
||||
setTitleBar()
|
||||
}
|
||||
R.id.slmenu_deselect_all -> clearSels()
|
||||
|
||||
R.id.slmenu_lookup_sel -> {
|
||||
val oneWord = arrayOf( getSelWords()!![0] )
|
||||
launchLookup( oneWord, m_langCodes!![m_langPosition], true )
|
||||
}
|
||||
else -> handled = false
|
||||
}
|
||||
return handled
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState( outState: Bundle )
|
||||
{
|
||||
outState.putSerializable( CHECKED_KEY, m_checkeds as HashSet )
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
//////////////////////////////////////////////////
|
||||
override fun onPosButton(action: DlgDelegate.Action, vararg params: Any ): Boolean
|
||||
{
|
||||
Assert.assertVarargsNotNullNR(params)
|
||||
var handled = true
|
||||
when ( action ) {
|
||||
DlgDelegate.Action.SL_CLEAR_ACTION -> {
|
||||
var selWords: Array<String>? = getSelWords()
|
||||
if ( null != selWords ) {
|
||||
clearWords( m_langCodes!![m_langPosition], selWords )
|
||||
clearSels()
|
||||
}
|
||||
initOrFinish()
|
||||
}
|
||||
DlgDelegate.Action.SL_COPY_ACTION -> {
|
||||
var selWords = getSelWords()
|
||||
Utils.stringToClip( m_activity, TextUtils.join( "\n", selWords!! ) )
|
||||
|
||||
val msg = getQuantityString( R.plurals.paste_done_fmt,
|
||||
selWords.size, selWords.size )
|
||||
showToast( msg )
|
||||
}
|
||||
else -> {
|
||||
Log.d( TAG, "not handling: %s", action )
|
||||
handled = false
|
||||
}
|
||||
}
|
||||
return handled
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// SelectableItem interface
|
||||
//////////////////////////////////////////////////
|
||||
override fun itemClicked( clicked: SelectableItem.LongClickHandler,
|
||||
summary: GameSummary
|
||||
)
|
||||
{
|
||||
m_checkeds.add( (clicked as XWListItem).getText() )
|
||||
}
|
||||
|
||||
override public fun itemToggled( toggled: SelectableItem.LongClickHandler,
|
||||
selected: Boolean )
|
||||
{
|
||||
val word = (toggled as XWListItem).getText()
|
||||
if ( selected ) {
|
||||
m_checkeds.add( word )
|
||||
} else {
|
||||
m_checkeds.remove( word )
|
||||
}
|
||||
setTitleBar()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// AdapterView.OnItemSelectedListener interface
|
||||
//////////////////////////////////////////////////
|
||||
override fun onItemSelected( parent: AdapterView<*>?, view: View,
|
||||
position: Int, id: Long )
|
||||
{
|
||||
m_langPosition = position
|
||||
m_checkeds.clear()
|
||||
loadList() // because language has changed
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// View.OnClickListener interface
|
||||
//////////////////////////////////////////////////
|
||||
override fun onClick( view: View )
|
||||
{
|
||||
val item = view as XWListItem
|
||||
val words: Array<String> = arrayOf(m_words!![item.getPosition()])
|
||||
launchLookup( words, m_langCodes!![m_langPosition], true )
|
||||
}
|
||||
|
||||
override fun getSelected( obj: SelectableItem.LongClickHandler ): Boolean
|
||||
{
|
||||
return m_checkeds.contains( (obj as XWListItem).getText() )
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// View.OnLongClickListener interface
|
||||
//////////////////////////////////////////////////
|
||||
override fun onLongClick( view: View ): Boolean
|
||||
{
|
||||
val success = view is SelectableItem.LongClickHandler
|
||||
if ( success ) {
|
||||
(view as SelectableItem.LongClickHandler).longClicked()
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
private fun initOrFinish( args: Bundle? = null )
|
||||
{
|
||||
val data = getData(m_activity)
|
||||
m_langCodes = data.keys.toTypedArray()
|
||||
when ( m_langCodes!!.size ) {
|
||||
0 -> finish()
|
||||
1 -> {
|
||||
m_pickView!!.setVisibility( View.GONE )
|
||||
m_langPosition = 0
|
||||
loadList()
|
||||
}
|
||||
else -> {
|
||||
var startLang: String? = null
|
||||
var startIndex = -1
|
||||
if ( null != args ) {
|
||||
startLang = args.getString( START_LANG )
|
||||
}
|
||||
|
||||
val siz = m_langCodes!!.size
|
||||
val myNames = ArrayList<String>()
|
||||
for ( ii in 0 ..< siz ) {
|
||||
val isoCode = m_langCodes!![ii]
|
||||
myNames.add( DictLangCache.getLangNameForISOCode( m_activity,
|
||||
isoCode ))
|
||||
if ( isoCode.equals( startLang ) ) {
|
||||
startIndex = ii
|
||||
}
|
||||
}
|
||||
|
||||
val adapter = ArrayAdapter<String>( m_activity,
|
||||
android.R.layout.simple_spinner_item,
|
||||
myNames )
|
||||
adapter.setDropDownViewResource( android.R.layout.
|
||||
simple_spinner_dropdown_item )
|
||||
m_spinner!!.setAdapter( adapter )
|
||||
m_spinner!!.setOnItemSelectedListener( this )
|
||||
if ( -1 != startIndex ) {
|
||||
m_spinner!!.setSelection( startIndex )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBundledData( sis: Bundle? )
|
||||
{
|
||||
if ( null != sis ) {
|
||||
val checkeds = sis.getSerializable( CHECKED_KEY ) as HashSet<String>
|
||||
if ( null != checkeds ) {
|
||||
m_checkeds.clear()
|
||||
m_checkeds.addAll(checkeds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearSels()
|
||||
{
|
||||
m_checkeds.clear()
|
||||
makeAdapter()
|
||||
setTitleBar()
|
||||
}
|
||||
|
||||
private fun setTitleBar()
|
||||
{
|
||||
val nSels = m_checkeds.size
|
||||
setTitle( if ( 0 == nSels ) {
|
||||
m_origTitle
|
||||
} else {
|
||||
getString( R.string.sel_items_fmt, nSels )
|
||||
} )
|
||||
invalidateOptionsMenuIf()
|
||||
}
|
||||
|
||||
private fun getSelWords(): Array<String>?
|
||||
{
|
||||
val nSels = m_checkeds.size
|
||||
var result: Array<String>? = null
|
||||
if ( nSels == m_words!!.size ) {
|
||||
result = m_words
|
||||
} else {
|
||||
val tmp = m_checkeds
|
||||
result = tmp!!.toTypedArray()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
protected fun loadList()
|
||||
{
|
||||
val isoCode = m_langCodes!![m_langPosition]
|
||||
val data = getData( m_activity )
|
||||
m_words = data.get( isoCode )
|
||||
|
||||
makeAdapter()
|
||||
|
||||
val langName = DictLangCache.getLangNameForISOCode( m_activity, isoCode )
|
||||
m_origTitle = getString( getTitleID(), langName )
|
||||
setTitleBar()
|
||||
}
|
||||
|
||||
private fun makeAdapter()
|
||||
{
|
||||
m_adapter = SLWordsAdapter()
|
||||
setListAdapter( m_adapter )
|
||||
}
|
||||
|
||||
inner class SLWordsAdapter() : XWListAdapter(m_words!!.size) {
|
||||
|
||||
override fun getView( position: Int, convertView: View?,
|
||||
parent: ViewGroup? ): View {
|
||||
val item = XWListItem.inflate( m_activity, this@IsoWordsBase )
|
||||
item.setPosition( position )
|
||||
val word = m_words!![position]
|
||||
item.setText( word )
|
||||
item.setSelected( m_checkeds.contains( word ) )
|
||||
item.setOnLongClickListener( this@IsoWordsBase )
|
||||
item.setOnClickListener( this@IsoWordsBase )
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = IsoWordsBase::class.java.getSimpleName()
|
||||
const val START_LANG = "START_LANG"
|
||||
|
||||
@JvmStatic
|
||||
protected fun mkBundle( isoCode: Utils.ISOCode? ): Bundle {
|
||||
val bundle = Bundle()
|
||||
if ( null != isoCode ) {
|
||||
bundle.putString( START_LANG, isoCode.toString() )
|
||||
}
|
||||
return bundle
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */ /*
|
||||
* Copyright 2014 - 2016 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.Context
|
||||
import android.os.Bundle
|
||||
import org.eehouse.android.xw4.Utils.ISOCode
|
||||
import org.eehouse.android.xw4.jni.XwJNI
|
||||
|
||||
class LegalPhoniesDelegate(delegator: Delegator, sis: Bundle?) :
|
||||
IsoWordsBase(delegator, sis, "CHECKED_KEY_LP")
|
||||
{
|
||||
companion object {
|
||||
private val TAG = LegalPhoniesDelegate::class.java.getSimpleName()
|
||||
@JvmStatic
|
||||
public fun launch( delegator: Delegator )
|
||||
{
|
||||
launch( delegator, null )
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun launch( delegator: Delegator, isoCode: Utils.ISOCode? )
|
||||
= delegator.addFragment( LegalPhoniesFrag.newInstance( delegator ),
|
||||
mkBundle(isoCode) )
|
||||
|
||||
@JvmStatic
|
||||
public fun haveLegalPhonies(context: Context): Boolean
|
||||
= !getDataPrv(context).isEmpty()
|
||||
|
||||
private fun getDataPrv( context: Context ): HashMap<ISOCode, Array<String>> {
|
||||
val result = HashMap<ISOCode, Array<String>>()
|
||||
|
||||
for ( code in XwJNI.dvc_getLegalPhonyCodes() ) {
|
||||
val strings = XwJNI.dvc_getLegalPhoniesFor( code )
|
||||
result.put(code, strings)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
override fun getData( context: Context ): HashMap<ISOCode, Array<String>>
|
||||
= getDataPrv(context)
|
||||
|
||||
override fun clearWords( isoCode: ISOCode, words: Array<String> )
|
||||
{
|
||||
for ( word in words ) {
|
||||
XwJNI.dvc_clearLegalPhony(isoCode, word)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitleID(): Int = R.string.legalphonies_title_fmt
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
|
||||
/*
|
||||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */ /*
|
||||
* Copyright 2014 - 2016 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
|
@ -17,23 +16,18 @@
|
|||
* 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
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
import android.os.Bundle
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
public class StudyListFrag extends XWFragment {
|
||||
|
||||
public StudyListFrag() {}
|
||||
|
||||
public static XWFragment newInstance( Delegator parent )
|
||||
{
|
||||
return new StudyListFrag().setParentName( parent );
|
||||
internal class LegalPhoniesFrag : XWFragment() {
|
||||
override fun onCreate(sis: Bundle?) {
|
||||
super.onCreate(LegalPhoniesDelegate(this, sis), sis, true)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate( Bundle sis )
|
||||
{
|
||||
super.onCreate( new StudyListDelegate( this, sis ), sis, true );
|
||||
companion object {
|
||||
fun newInstance(parent: Delegator?): XWFragment {
|
||||
return LegalPhoniesFrag().setParentName(parent)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,430 +0,0 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
|
||||
/*
|
||||
* Copyright 2014 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.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.ClipboardManager;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Spinner;
|
||||
|
||||
|
||||
import org.eehouse.android.xw4.DlgDelegate.Action;
|
||||
import org.eehouse.android.xw4.Utils.ISOCode;
|
||||
import org.eehouse.android.xw4.jni.GameSummary;
|
||||
import org.eehouse.android.xw4.loc.LocUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
public class StudyListDelegate extends ListDelegateBase
|
||||
implements OnItemSelectedListener, SelectableItem,
|
||||
View.OnLongClickListener, View.OnClickListener,
|
||||
DBUtils.StudyListListener {
|
||||
private static final String TAG = StudyListDelegate.class.getSimpleName();
|
||||
|
||||
protected static final String START_LANG = "START_LANG";
|
||||
|
||||
private static final String CHECKED_KEY = "CHECKED_KEY";
|
||||
|
||||
private Activity m_activity;
|
||||
private Spinner m_spinner;
|
||||
private LabeledSpinner m_pickView;
|
||||
private ISOCode[] m_langCodes;
|
||||
private String[] m_words;
|
||||
private Set<String> m_checkeds;
|
||||
private int m_langPosition;
|
||||
private SLWordsAdapter m_adapter;
|
||||
private String m_origTitle;
|
||||
|
||||
protected StudyListDelegate( Delegator delegator, Bundle sis )
|
||||
{
|
||||
super( delegator, sis, R.layout.studylist, R.menu.studylist );
|
||||
m_activity = delegator.getActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init( Bundle sis )
|
||||
{
|
||||
m_pickView = (LabeledSpinner)findViewById( R.id.pick_lang );
|
||||
m_spinner = m_pickView.getSpinner();
|
||||
m_checkeds = new HashSet<>();
|
||||
m_words = new String[0];
|
||||
|
||||
getBundledData( sis );
|
||||
|
||||
initOrFinish( getArguments() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
DBUtils.addStudyListChangedListener( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
DBUtils.removeStudyListChangedListener( this );
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleBackPressed()
|
||||
{
|
||||
boolean handled = 0 < m_checkeds.size();
|
||||
if ( handled ) {
|
||||
clearSels();
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu( Menu menu )
|
||||
{
|
||||
int nSel = m_checkeds.size();
|
||||
Utils.setItemVisible( menu, R.id.slmenu_copy_sel, 0 < nSel );
|
||||
Utils.setItemVisible( menu, R.id.slmenu_clear_sel, 0 < nSel );
|
||||
Utils.setItemVisible( menu, R.id.slmenu_select_all,
|
||||
m_words.length > nSel );
|
||||
Utils.setItemVisible( menu, R.id.slmenu_deselect_all, 0 < nSel );
|
||||
boolean enable = 1 == nSel;
|
||||
if ( enable ) {
|
||||
String title = getString( R.string.button_lookup_fmt,
|
||||
getSelWords()[0] );
|
||||
menu.findItem( R.id.slmenu_lookup_sel ).setTitle( title );
|
||||
}
|
||||
Utils.setItemVisible( menu, R.id.slmenu_lookup_sel, enable );
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected( MenuItem item )
|
||||
{
|
||||
boolean handled = true;
|
||||
switch ( item.getItemId() ) {
|
||||
case R.id.slmenu_copy_sel:
|
||||
makeNotAgainBuilder( R.string.key_na_studycopy,
|
||||
Action.SL_COPY_ACTION,
|
||||
R.string.not_again_studycopy )
|
||||
.show();
|
||||
break;
|
||||
case R.id.slmenu_clear_sel:
|
||||
String msg = getQuantityString( R.plurals.confirm_studylist_clear_fmt,
|
||||
m_checkeds.size(), m_checkeds.size() );
|
||||
makeConfirmThenBuilder( Action.SL_CLEAR_ACTION, msg ).show();
|
||||
break;
|
||||
|
||||
case R.id.slmenu_select_all:
|
||||
for ( String word : m_words ) {
|
||||
m_checkeds.add( word );
|
||||
}
|
||||
makeAdapter();
|
||||
setTitleBar();
|
||||
break;
|
||||
case R.id.slmenu_deselect_all:
|
||||
clearSels();
|
||||
break;
|
||||
case R.id.slmenu_lookup_sel:
|
||||
String[] oneWord = new String[]{ getSelWords()[0] };
|
||||
launchLookup( oneWord, m_langCodes[m_langPosition], true );
|
||||
break;
|
||||
default:
|
||||
handled = false;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState( Bundle outState )
|
||||
{
|
||||
outState.putSerializable( CHECKED_KEY, (HashSet)m_checkeds );
|
||||
}
|
||||
|
||||
private void getBundledData( Bundle sis )
|
||||
{
|
||||
if ( null != sis ) {
|
||||
m_checkeds = (HashSet)sis.getSerializable( CHECKED_KEY );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// DBUtils.StudyListListener
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public void onWordAdded( String word, ISOCode isoCode )
|
||||
{
|
||||
if ( isoCode.equals( m_langCodes[m_langPosition] ) ) {
|
||||
loadList();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public boolean onPosButton( Action action, Object... params )
|
||||
{
|
||||
Assert.assertVarargsNotNullNR(params);
|
||||
boolean handled = true;
|
||||
switch ( action ) {
|
||||
case SL_CLEAR_ACTION:
|
||||
String[] selWords = getSelWords();
|
||||
if ( selWords.length == m_words.length ) {
|
||||
selWords = null; // all: easier on DB :-)
|
||||
}
|
||||
DBUtils.studyListClear( m_activity, m_langCodes[m_langPosition],
|
||||
selWords );
|
||||
initOrFinish( null );
|
||||
break;
|
||||
case SL_COPY_ACTION:
|
||||
selWords = getSelWords();
|
||||
Utils.stringToClip( m_activity, TextUtils.join( "\n", selWords ) );
|
||||
|
||||
String msg = getQuantityString( R.plurals.paste_done_fmt,
|
||||
selWords.length, selWords.length );
|
||||
showToast( msg );
|
||||
break;
|
||||
default:
|
||||
Log.d( TAG, "not handling: %s", action );
|
||||
handled = false;
|
||||
break;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// AdapterView.OnItemSelectedListener interface
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public void onItemSelected( AdapterView<?> parent, View view,
|
||||
int position, long id )
|
||||
{
|
||||
m_langPosition = position;
|
||||
m_checkeds.clear();
|
||||
loadList(); // because language has changed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected( AdapterView<?> parent )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// View.OnLongClickListener interface
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public boolean onLongClick( View view )
|
||||
{
|
||||
boolean success = view instanceof SelectableItem.LongClickHandler;
|
||||
if ( success ) {
|
||||
((SelectableItem.LongClickHandler)view).longClicked();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// View.OnClickListener interface
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public void onClick( View view )
|
||||
{
|
||||
XWListItem item = (XWListItem)view;
|
||||
String[] words = { m_words[item.getPosition()] };
|
||||
launchLookup( words, m_langCodes[m_langPosition], true );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// SelectableItem interface
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public void itemClicked( SelectableItem.LongClickHandler clicked,
|
||||
GameSummary summary )
|
||||
{
|
||||
m_checkeds.add( ((XWListItem)clicked).getText() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemToggled( SelectableItem.LongClickHandler toggled,
|
||||
boolean selected )
|
||||
{
|
||||
String word = ((XWListItem)toggled).getText();
|
||||
if ( selected ) {
|
||||
m_checkeds.add( word );
|
||||
} else {
|
||||
m_checkeds.remove( word );
|
||||
}
|
||||
setTitleBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSelected( SelectableItem.LongClickHandler obj )
|
||||
{
|
||||
return m_checkeds.contains( ((XWListItem)obj).getText() );
|
||||
}
|
||||
|
||||
private void loadList()
|
||||
{
|
||||
ISOCode isoCode = m_langCodes[m_langPosition];
|
||||
m_words = DBUtils.studyListWords( m_activity, isoCode );
|
||||
|
||||
makeAdapter();
|
||||
|
||||
String langName = DictLangCache.getLangNameForISOCode( m_activity, isoCode );
|
||||
m_origTitle = getString( R.string.studylist_title_fmt,
|
||||
langName );
|
||||
setTitleBar();
|
||||
}
|
||||
|
||||
private void makeAdapter()
|
||||
{
|
||||
m_adapter = new SLWordsAdapter();
|
||||
setListAdapter( m_adapter );
|
||||
}
|
||||
|
||||
private void initOrFinish( Bundle args )
|
||||
{
|
||||
m_langCodes = DBUtils.studyListLangs( m_activity );
|
||||
if ( 0 == m_langCodes.length ) {
|
||||
finish();
|
||||
} else if ( 1 == m_langCodes.length ) {
|
||||
m_pickView.setVisibility( View.GONE );
|
||||
m_langPosition = 0;
|
||||
loadList();
|
||||
} else {
|
||||
String startLang = null;
|
||||
int startIndex = -1;
|
||||
if ( null != args ) {
|
||||
startLang = args.getString( START_LANG );
|
||||
}
|
||||
|
||||
String[] myNames = new String[m_langCodes.length];
|
||||
for ( int ii = 0; ii < m_langCodes.length; ++ii ) {
|
||||
ISOCode isoCode = m_langCodes[ii];
|
||||
myNames[ii] = DictLangCache.getLangNameForISOCode( m_activity, isoCode );
|
||||
if ( isoCode.equals( startLang ) ) {
|
||||
startIndex = ii;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayAdapter<String> adapter = new
|
||||
ArrayAdapter<String>( m_activity,
|
||||
android.R.layout.simple_spinner_item,
|
||||
myNames );
|
||||
adapter.setDropDownViewResource( android.R.layout.
|
||||
simple_spinner_dropdown_item );
|
||||
m_spinner.setAdapter( adapter );
|
||||
m_spinner.setOnItemSelectedListener( this );
|
||||
if ( -1 != startIndex ) {
|
||||
m_spinner.setSelection( startIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setTitleBar()
|
||||
{
|
||||
String newTitle;
|
||||
int nSels = m_checkeds.size();
|
||||
if ( 0 == nSels ) {
|
||||
newTitle = m_origTitle;
|
||||
} else {
|
||||
newTitle = getString( R.string.sel_items_fmt, nSels );
|
||||
}
|
||||
setTitle( newTitle );
|
||||
|
||||
invalidateOptionsMenuIf();
|
||||
}
|
||||
|
||||
private String[] getSelWords()
|
||||
{
|
||||
String[] result;
|
||||
int nSels = m_checkeds.size();
|
||||
if ( nSels == m_words.length ) {
|
||||
result = m_words;
|
||||
} else {
|
||||
result = m_checkeds.toArray( new String[nSels] );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void clearSels()
|
||||
{
|
||||
m_checkeds.clear();
|
||||
makeAdapter();
|
||||
setTitleBar();
|
||||
}
|
||||
|
||||
public static void launch( Delegator delegator )
|
||||
{
|
||||
launch( delegator, null );
|
||||
}
|
||||
|
||||
public static void launch( Delegator delegator, ISOCode isoCode )
|
||||
{
|
||||
Activity activity = delegator.getActivity();
|
||||
if ( null == isoCode ) {
|
||||
Assert.assertTrueNR( 0 < DBUtils.studyListLangs( activity ).length );
|
||||
} else {
|
||||
Assert.assertTrueNR( 0 < DBUtils
|
||||
.studyListWords( activity, isoCode ).length );
|
||||
}
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
if ( null != isoCode ) {
|
||||
bundle.putString( START_LANG, isoCode.toString() );
|
||||
}
|
||||
|
||||
delegator.addFragment( StudyListFrag.newInstance( delegator ),
|
||||
bundle );
|
||||
}
|
||||
|
||||
private class SLWordsAdapter extends XWListAdapter {
|
||||
|
||||
public SLWordsAdapter()
|
||||
{
|
||||
super( m_words.length );
|
||||
}
|
||||
|
||||
public View getView( int position, View convertView, ViewGroup parent ){
|
||||
XWListItem item =
|
||||
XWListItem.inflate( m_activity, StudyListDelegate.this );
|
||||
item.setPosition( position );
|
||||
String word = m_words[position];
|
||||
item.setText( word );
|
||||
item.setSelected( m_checkeds.contains( word ) );
|
||||
item.setOnLongClickListener( StudyListDelegate.this );
|
||||
item.setOnClickListener( StudyListDelegate.this );
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
|
||||
/*
|
||||
* Copyright 2014 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.Context
|
||||
import android.os.Bundle
|
||||
|
||||
import java.util.HashMap
|
||||
|
||||
import org.eehouse.android.xw4.Utils.ISOCode
|
||||
|
||||
class StudyListDelegate(delegator: Delegator, sis: Bundle?) :
|
||||
IsoWordsBase(delegator, sis, "CHECKED_KEY"),
|
||||
DBUtils.StudyListListener {
|
||||
|
||||
companion object {
|
||||
private val TAG = StudyListDelegate::class.java.getSimpleName()
|
||||
|
||||
@JvmStatic
|
||||
public fun launch( delegator: Delegator )
|
||||
{
|
||||
launch( delegator, null )
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun launch( delegator: Delegator, isoCode: ISOCode? )
|
||||
{
|
||||
val activity = delegator.getActivity()
|
||||
if ( null == isoCode ) {
|
||||
Assert.assertTrueNR( 0 < DBUtils.studyListLangs( activity ).size )
|
||||
} else {
|
||||
Assert.assertTrueNR( 0 < DBUtils
|
||||
.studyListWords( activity, isoCode ).size )
|
||||
}
|
||||
|
||||
delegator.addFragment( StudyListFrag.newInstance( delegator ),
|
||||
mkBundle( isoCode ) )
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume()
|
||||
{
|
||||
super.onResume()
|
||||
DBUtils.addStudyListChangedListener( this )
|
||||
}
|
||||
|
||||
override fun onPause()
|
||||
{
|
||||
DBUtils.removeStudyListChangedListener( this )
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// DBUtils.StudyListListener
|
||||
//////////////////////////////////////////////////
|
||||
override fun onWordAdded( word: String, isoCode: ISOCode )
|
||||
{
|
||||
if ( isoCode.equals( m_langCodes!![m_langPosition] ) ) {
|
||||
loadList()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Abstract methods from superclass
|
||||
//////////////////////////////////////////////////
|
||||
override fun getData( context: Context ): HashMap<ISOCode, Array<String>> {
|
||||
val result = HashMap<ISOCode, Array<String>>()
|
||||
|
||||
val codes = DBUtils.studyListLangs( m_activity )
|
||||
for ( code in codes ) {
|
||||
val words = DBUtils.studyListWords( m_activity, code )
|
||||
result.put(code, words)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun clearWords( isoCode: ISOCode, words: Array<String> ) {
|
||||
DBUtils.studyListClear( m_activity, isoCode, words )
|
||||
}
|
||||
|
||||
override fun getTitleID(): Int = R.string.studylist_title_fmt
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */ /*
|
||||
* Copyright 2014 - 2016 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.os.Bundle
|
||||
|
||||
class StudyListFrag : XWFragment() {
|
||||
override fun onCreate(sis: Bundle?) {
|
||||
super.onCreate(StudyListDelegate(this, sis), sis, true)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(parent: Delegator?): XWFragment {
|
||||
return StudyListFrag().setParentName(parent)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
|
||||
|
||||
abstract class XWFragment extends Fragment implements Delegator {
|
||||
public abstract class XWFragment extends Fragment implements Delegator {
|
||||
private static final String TAG = XWFragment.class.getSimpleName();
|
||||
private static final String PARENT_NAME = "PARENT_NAME";
|
||||
private static final String COMMIT_ID = "COMMIT_ID";
|
||||
|
|
|
@ -23,6 +23,7 @@ package org.eehouse.android.xw4.jni;
|
|||
import android.graphics.Rect;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eehouse.android.xw4.Assert;
|
||||
|
@ -189,19 +190,27 @@ public class XwJNI {
|
|||
dvc_onWebSendResult( getJNI().m_ptrGlobals, resultKey, succeeded, result );
|
||||
}
|
||||
|
||||
public static boolean dvc_haveLegalPhonies()
|
||||
public static ISOCode[] dvc_getLegalPhonyCodes()
|
||||
{
|
||||
return dvc_haveLegalPhonies( getJNI().m_ptrGlobals );
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
dvc_getLegalPhonyCodes(getJNI().m_ptrGlobals, list );
|
||||
ISOCode[] result = new ISOCode[list.size()];
|
||||
for ( int ii = 0; ii < result.length; ++ii ) {
|
||||
result[ii] = new ISOCode(list.get(ii));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String dvc_listLegalPhonies()
|
||||
public static String[] dvc_getLegalPhoniesFor( ISOCode code )
|
||||
{
|
||||
return dvc_listLegalPhonies( getJNI().m_ptrGlobals );
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
dvc_getLegalPhoniesFor( getJNI().m_ptrGlobals, code.toString(), list );
|
||||
return list.toArray( new String[list.size()] );
|
||||
}
|
||||
|
||||
public static int dvc_clearLegalPhonies()
|
||||
public static void dvc_clearLegalPhony( ISOCode code, String phony )
|
||||
{
|
||||
return dvc_clearLegalPhonies( getJNI().m_ptrGlobals );
|
||||
dvc_clearLegalPhony( getJNI().m_ptrGlobals, code.toString(), phony );
|
||||
}
|
||||
|
||||
public static boolean hasKnownPlayers()
|
||||
|
@ -540,8 +549,8 @@ public class XwJNI {
|
|||
|
||||
XP_KEY_LAST
|
||||
};
|
||||
public static native boolean board_handleKey( GamePtr gamePtr, XP_Key key,
|
||||
boolean up, boolean[] handled );
|
||||
// public static native boolean board_handleKey( GamePtr gamePtr, XP_Key key,
|
||||
// boolean up, boolean[] handled );
|
||||
// public static native boolean board_handleKeyDown( XP_Key key,
|
||||
// boolean[] handled );
|
||||
// public static native boolean board_handleKeyRepeat( XP_Key key,
|
||||
|
@ -833,9 +842,13 @@ public class XwJNI {
|
|||
private static native void dvc_onWebSendResult( long jniState, int resultKey,
|
||||
boolean succeeded,
|
||||
String result );
|
||||
private static native boolean dvc_haveLegalPhonies( long jniState );
|
||||
private static native String dvc_listLegalPhonies( long jniState );
|
||||
private static native int dvc_clearLegalPhonies( long jniState );
|
||||
private static native void dvc_getLegalPhonyCodes(long jniState,
|
||||
ArrayList<String> list);
|
||||
private static native void dvc_getLegalPhoniesFor( long jniState, String code,
|
||||
ArrayList<String> list );
|
||||
private static native void
|
||||
dvc_clearLegalPhony( long jniState, String code, String phony );
|
||||
|
||||
private static native String[] kplr_getPlayers( long jniState, boolean byDate );
|
||||
private static native boolean kplr_renamePlayer( long jniState, String oldName,
|
||||
String newName );
|
||||
|
|
|
@ -33,18 +33,9 @@
|
|||
android:icon="@drawable/dict__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_submenu_legalPhonies"
|
||||
<item android:id="@+id/games_menu_legalPhonies"
|
||||
android:title="@string/gamel_menu_legalPhonies"
|
||||
>
|
||||
<menu>
|
||||
<item android:id="@+id/games_menu_clearLPs"
|
||||
android:title="@string/gamel_menu_clearLPs"
|
||||
/>
|
||||
<item android:id="@+id/games_menu_listLPs"
|
||||
android:title="@string/gamel_menu_listLPs"
|
||||
/>
|
||||
</menu>
|
||||
</item>
|
||||
/>
|
||||
|
||||
<item android:id="@+id/games_menu_study"
|
||||
android:title="@string/gamel_menu_study"
|
||||
|
|
|
@ -548,7 +548,7 @@
|
|||
<!-- The third button in the "Phonies found" dialog. Means we'll
|
||||
accept the phonies AND will record them so they'll be
|
||||
accepted from now on. -->
|
||||
<string name="buttonYesAnd">Yes/Save</string>
|
||||
<string name="buttonYesAnd">Yes & Save</string>
|
||||
|
||||
<!--
|
||||
############################################################
|
||||
|
|
|
@ -13,10 +13,9 @@
|
|||
<string name="gamel_menu_clearLPs">Clear all</string>
|
||||
<string name="gamel_menu_listLPs">Show all</string>
|
||||
|
||||
<string name="cleared_lps_fmt">Cleared %1$d legal phonies</string>
|
||||
|
||||
|
||||
<string name="confirm_clear_lps">Are you sure you want to clear
|
||||
saved “legal phonies”?\n\nThis action cannot be undone.</string>
|
||||
|
||||
<string name="legalphonies_title_fmt">Legal phonies for %1$s</string>
|
||||
</resources>
|
||||
|
|
|
@ -429,6 +429,16 @@ setIntInArray( JNIEnv* env, jintArray arr, int index, int val )
|
|||
(*env)->ReleaseIntArrayElements( env, arr, ints, 0 );
|
||||
}
|
||||
|
||||
void
|
||||
addStrToList( JNIEnv* env, jobject list, const XP_UCHAR* str )
|
||||
{
|
||||
jmethodID mid = getMethodID( env, list, "add", "(Ljava/lang/Object;)Z" );
|
||||
|
||||
jstring jstr = (*env)->NewStringUTF( env, str );
|
||||
(*env)->CallBooleanMethod( env, list, mid, jstr );
|
||||
deleteLocalRef( env, jstr );
|
||||
}
|
||||
|
||||
jobjectArray
|
||||
makeStringArray( JNIEnv* env, const int count, const XP_UCHAR* const* vals )
|
||||
{
|
||||
|
@ -602,15 +612,15 @@ addrTypesToJ( JNIEnv* env, const CommsAddrRec* addr )
|
|||
makeObjectEmptyConstr( env, PKG_PATH("jni/CommsAddrRec$CommsConnTypeSet") );
|
||||
XP_ASSERT( !!result );
|
||||
|
||||
jmethodID mid2 = getMethodID( env, result, "add",
|
||||
jmethodID mid = getMethodID( env, result, "add",
|
||||
"(Ljava/lang/Object;)Z" );
|
||||
XP_ASSERT( !!mid2 );
|
||||
XP_ASSERT( !!mid );
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) {
|
||||
jobject jtyp = intToJEnum( env, typ,
|
||||
PKG_PATH("jni/CommsAddrRec$CommsConnType") );
|
||||
XP_ASSERT( !!jtyp );
|
||||
(*env)->CallBooleanMethod( env, result, mid2, jtyp );
|
||||
(*env)->CallBooleanMethod( env, result, mid, jtyp );
|
||||
deleteLocalRef( env, jtyp );
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -75,6 +75,8 @@ void setIntArray( JNIEnv* env, jobject jowner, const char* ownerField,
|
|||
int getIntsFromArray( JNIEnv* env, int dest[], jintArray arr, int count, bool del );
|
||||
void setIntInArray( JNIEnv* env, jintArray arr, int index, int val );
|
||||
|
||||
void addStrToList( JNIEnv* env, jobject list, const XP_UCHAR* str );
|
||||
|
||||
jbyteArray makeByteArray( JNIEnv* env, int size, const jbyte* vals );
|
||||
jobjectArray makeByteArrayArray( JNIEnv* env, int siz );
|
||||
|
||||
|
|
|
@ -794,48 +794,60 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1onWebSendResult
|
|||
DVC_HEADER_END();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1haveLegalPhonies
|
||||
( JNIEnv* env, jclass C, jlong jniGlobalPtr )
|
||||
typedef struct _CollectState {
|
||||
JNIEnv* env;
|
||||
jobject list;
|
||||
} CollectState;
|
||||
|
||||
static void
|
||||
wordCollector( const XP_UCHAR* str, void* closure )
|
||||
{
|
||||
jboolean jresult;
|
||||
DVC_HEADER(jniGlobalPtr);
|
||||
jresult = dvc_haveLegalPhonies( globalState->dutil, env );
|
||||
DVC_HEADER_END();
|
||||
return jresult;
|
||||
CollectState* cs = (CollectState*)closure;
|
||||
addStrToList( cs->env, cs->list, str );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1listLegalPhonies
|
||||
( JNIEnv* env, jclass C, jlong jniGlobalPtr )
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1getLegalPhonyCodes
|
||||
(JNIEnv* env, jclass C, jlong jniGlobalPtr, jobject list)
|
||||
{
|
||||
jstring jresult;
|
||||
DVC_HEADER(jniGlobalPtr);
|
||||
#ifdef MEM_DEBUG
|
||||
MemPoolCtx* mpool = GETMPOOL( globalState );
|
||||
#endif
|
||||
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(mpool) globalState->vtMgr,
|
||||
NULL, 0, NULL, NULL );
|
||||
dvc_listLegalPhonies( globalState->dutil, env, stream );
|
||||
jresult = streamToJString( env, stream );
|
||||
stream_destroy( stream );
|
||||
CollectState cs = {
|
||||
.env = env,
|
||||
.list = list,
|
||||
};
|
||||
dvc_getIsoCodes( globalState->dutil, env, wordCollector, &cs );
|
||||
|
||||
DVC_HEADER_END();
|
||||
return jresult;
|
||||
}
|
||||
#endif
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1clearLegalPhonies
|
||||
( JNIEnv* env, jclass C, jlong jniGlobalPtr )
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1getLegalPhoniesFor
|
||||
(JNIEnv* env, jclass C, jlong jniGlobalPtr, jstring jcode, jobject list)
|
||||
{
|
||||
jint result;
|
||||
DVC_HEADER(jniGlobalPtr);
|
||||
result = dvc_clearLegalPhonies( globalState->dutil, env );
|
||||
|
||||
const char* code = (*env)->GetStringUTFChars( env, jcode, NULL );
|
||||
|
||||
CollectState cs = {
|
||||
.env = env,
|
||||
.list = list,
|
||||
};
|
||||
dvc_getPhoniesFor( globalState->dutil, env, code, wordCollector, &cs );
|
||||
(*env)->ReleaseStringUTFChars( env, jcode, code );
|
||||
DVC_HEADER_END();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1clearLegalPhony
|
||||
(JNIEnv* env, jclass C, jlong jniGlobalPtr, jstring jcode, jstring jphony)
|
||||
{
|
||||
DVC_HEADER(jniGlobalPtr);
|
||||
const char* code = (*env)->GetStringUTFChars( env, jcode, NULL );
|
||||
const char* phony = (*env)->GetStringUTFChars( env, jphony, NULL );
|
||||
dvc_clearLegalPhony( globalState->dutil, env, code, phony );
|
||||
(*env)->ReleaseStringUTFChars( env, jcode, code );
|
||||
(*env)->ReleaseStringUTFChars( env, jphony, phony );
|
||||
DVC_HEADER_END();
|
||||
return result;
|
||||
}
|
||||
|
||||
# ifdef XWFEATURE_KNOWNPLAYERS
|
||||
|
|
|
@ -722,10 +722,12 @@ dvc_onWebSendResult( XW_DUtilCtxt* dutil, XWEnv xwe, XP_U32 resultKey,
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct _FindIsoState {
|
||||
typedef struct _PhoniesMapState {
|
||||
XW_DUtilCtxt* dutil;
|
||||
const XP_UCHAR* isoCode;
|
||||
PhoniesDataCodes* found;
|
||||
} FindIsoState;
|
||||
const XP_UCHAR* phony;
|
||||
const DLHead* found;
|
||||
} PhoniesMapState;
|
||||
|
||||
static ForEachAct
|
||||
findIsoProc( const DLHead* elem, void* closure )
|
||||
|
@ -733,9 +735,9 @@ findIsoProc( const DLHead* elem, void* closure )
|
|||
ForEachAct result = FEA_OK;
|
||||
PhoniesDataCodes* pdc = (PhoniesDataCodes*)elem;
|
||||
|
||||
FindIsoState* fis = (FindIsoState*)closure;
|
||||
if ( 0 == XP_STRCMP( fis->isoCode, pdc->isoCode ) ) {
|
||||
fis->found = pdc;
|
||||
PhoniesMapState* pms = (PhoniesMapState*)closure;
|
||||
if ( 0 == XP_STRCMP( pms->isoCode, pdc->isoCode ) ) {
|
||||
pms->found = elem;
|
||||
result = FEA_EXIT;
|
||||
}
|
||||
return result;
|
||||
|
@ -744,11 +746,11 @@ findIsoProc( const DLHead* elem, void* closure )
|
|||
static PhoniesDataCodes*
|
||||
findForIso( XW_DUtilCtxt* XP_UNUSED_DBG(dutil), DevCtxt* dc, const XP_UCHAR* isoCode )
|
||||
{
|
||||
FindIsoState fis = {
|
||||
PhoniesMapState ms = {
|
||||
.isoCode = isoCode,
|
||||
};
|
||||
dll_map( &dc->pd->links, findIsoProc, NULL, &fis );
|
||||
PhoniesDataCodes* pdc = fis.found;
|
||||
dll_map( &dc->pd->links, findIsoProc, NULL, &ms );
|
||||
PhoniesDataCodes* pdc = (PhoniesDataCodes*)ms.found;
|
||||
|
||||
if ( !pdc ) {
|
||||
pdc = XP_CALLOC( dutil->mpool, sizeof(*pdc) );
|
||||
|
@ -885,19 +887,13 @@ dvc_haveLegalPhonies( XW_DUtilCtxt* dutil, XWEnv xwe )
|
|||
return result;
|
||||
}
|
||||
|
||||
typedef struct _FreeState {
|
||||
XW_DUtilCtxt* dutil;
|
||||
XP_U16 count;
|
||||
} FreeState;
|
||||
|
||||
static void
|
||||
freeOnePhony( DLHead* elem, void* closure )
|
||||
{
|
||||
FreeState* fs = (FreeState*)closure;
|
||||
++fs->count;
|
||||
PhoniesMapState* ms = (PhoniesMapState*)closure;
|
||||
const PhoniesDataStrs* pds = (PhoniesDataStrs*)elem;
|
||||
XP_FREE( fs->dutil->mpool, pds->phony );
|
||||
XP_FREE( fs->dutil->mpool, elem );
|
||||
XP_FREE( ms->dutil->mpool, pds->phony );
|
||||
XP_FREE( ms->dutil->mpool, elem );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -908,86 +904,110 @@ freeOneCode( DLHead* elem, void* closure)
|
|||
dll_removeAll( &pdc->head->links, freeOnePhony, closure );
|
||||
|
||||
#ifdef MEM_DEBUG
|
||||
FreeState* fs = (FreeState*)closure;
|
||||
PhoniesMapState* ms = (PhoniesMapState*)closure;
|
||||
#endif
|
||||
XP_FREE( fs->dutil->mpool, pdc->isoCode );
|
||||
XP_FREE( fs->dutil->mpool, elem );
|
||||
XP_FREE( ms->dutil->mpool, pdc->isoCode );
|
||||
XP_FREE( ms->dutil->mpool, elem );
|
||||
}
|
||||
|
||||
static DevCtxt*
|
||||
freePhonyState( XW_DUtilCtxt* dutil, XWEnv xwe, XP_U16* lenP )
|
||||
freePhonyState( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||||
{
|
||||
FreeState fs = { .dutil = dutil, };
|
||||
PhoniesMapState ms = { .dutil = dutil, };
|
||||
DevCtxt* dc = load( dutil, xwe );
|
||||
dll_removeAll( &dc->pd->links, freeOneCode, &fs );
|
||||
if ( !!lenP ) {
|
||||
*lenP = fs.count;
|
||||
}
|
||||
dll_removeAll( &dc->pd->links, freeOneCode, &ms );
|
||||
dc->pd = NULL;
|
||||
return dc;
|
||||
}
|
||||
|
||||
XP_U16
|
||||
dvc_clearLegalPhonies( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||||
static ForEachAct
|
||||
clearPhonyProc( const DLHead* elem, void* closure )
|
||||
{
|
||||
DevCtxt* dc = load( dutil, xwe );
|
||||
XP_U16 len = dll_length( &dc->pd->links );
|
||||
freePhonyState( dutil, xwe, &len );
|
||||
storePhoniesData( dutil, xwe, dc );
|
||||
return len;
|
||||
ForEachAct result = FEA_OK;
|
||||
const PhoniesDataStrs* pds = (PhoniesDataStrs*)elem;
|
||||
PhoniesMapState* ms = (PhoniesMapState*)closure;
|
||||
if ( 0 == XP_STRCMP( ms->phony, pds->phony ) ) {
|
||||
result = FEA_EXIT | FEA_REMOVE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static ForEachAct
|
||||
listPhoniesProc( const DLHead* elem, void* closure )
|
||||
void
|
||||
dvc_clearLegalPhony( XW_DUtilCtxt* dutil, XWEnv xwe,
|
||||
const XP_UCHAR* isoCode,
|
||||
const XP_UCHAR* phony )
|
||||
{
|
||||
const PhoniesDataStrs* pds = (PhoniesDataStrs*)elem;
|
||||
XWStreamCtxt* stream = (XWStreamCtxt*)closure;
|
||||
DevCtxt* dc = load( dutil, xwe );
|
||||
PhoniesDataCodes* pdc = findForIso( dutil, dc, isoCode );
|
||||
|
||||
stream_catString( stream, "- " );
|
||||
stream_catString( stream, pds->phony );
|
||||
stream_catString( stream, "\n" );
|
||||
PhoniesMapState ms = { .dutil = dutil, .phony = phony, };
|
||||
pdc->head = (PhoniesDataStrs*)
|
||||
dll_map( &pdc->head->links, clearPhonyProc, freeOnePhony, &ms );
|
||||
if ( !pdc->head ) {
|
||||
dc->pd = (PhoniesDataCodes*)dll_remove( &dc->pd->links, &pdc->links );
|
||||
freeOneCode( &pdc->links, &ms );
|
||||
}
|
||||
storePhoniesData( dutil, xwe, dc );
|
||||
}
|
||||
|
||||
typedef struct _GetWordsState {
|
||||
WordCollector proc;
|
||||
void* closure;
|
||||
} GetWordsState;
|
||||
|
||||
static ForEachAct
|
||||
getIsosProc( const DLHead* elem, void* closure )
|
||||
{
|
||||
const PhoniesDataCodes* pdc = (PhoniesDataCodes*)elem;
|
||||
GetWordsState* gws = (GetWordsState*)closure;
|
||||
(*gws->proc)( pdc->isoCode, gws->closure );
|
||||
return FEA_OK;
|
||||
}
|
||||
|
||||
static ForEachAct
|
||||
listIsosProc( const DLHead* elem, void* closure )
|
||||
getWordsProc( const DLHead* elem, void* closure )
|
||||
{
|
||||
const PhoniesDataCodes* pdc = (PhoniesDataCodes*)elem;
|
||||
XWStreamCtxt* stream = (XWStreamCtxt*)closure;
|
||||
|
||||
stream_catString( stream, pdc->isoCode );
|
||||
stream_catString( stream, ":\n" );
|
||||
|
||||
dll_map( &pdc->head->links, listPhoniesProc, NULL, stream );
|
||||
|
||||
const PhoniesDataStrs* pds = (PhoniesDataStrs*)elem;
|
||||
GetWordsState* gws = (GetWordsState*)closure;
|
||||
(*gws->proc)( pds->phony, gws->closure );
|
||||
return FEA_OK;
|
||||
}
|
||||
|
||||
void
|
||||
dvc_listLegalPhonies( XW_DUtilCtxt* dutil, XWEnv xwe, XWStreamCtxt* stream )
|
||||
dvc_getIsoCodes( XW_DUtilCtxt* dutil, XWEnv xwe,
|
||||
WordCollector proc, void* closure )
|
||||
{
|
||||
DevCtxt* dc = load( dutil, xwe );
|
||||
dll_map( &dc->pd->links, listIsosProc, NULL, stream );
|
||||
stream_putU8( stream, '\0' );
|
||||
}
|
||||
#endif
|
||||
GetWordsState gws = {
|
||||
.proc = proc,
|
||||
.closure = closure,
|
||||
};
|
||||
|
||||
typedef struct _FindPhonyData {
|
||||
XP_Bool found;
|
||||
const XP_UCHAR* isoCode;
|
||||
const XP_UCHAR* phony;
|
||||
} FindPhonyData;
|
||||
DevCtxt* dc = load( dutil, xwe );
|
||||
dll_map( &dc->pd->links, getIsosProc, NULL, &gws );
|
||||
}
|
||||
|
||||
void
|
||||
dvc_getPhoniesFor( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* code,
|
||||
WordCollector proc, void* closure )
|
||||
{
|
||||
GetWordsState gws = {
|
||||
.proc = proc,
|
||||
.closure = closure,
|
||||
};
|
||||
|
||||
DevCtxt* dc = load( dutil, xwe );
|
||||
PhoniesDataCodes* pdc = findForIso( dutil, dc, code );
|
||||
dll_map( &pdc->head->links, getWordsProc, NULL, &gws );
|
||||
}
|
||||
|
||||
static ForEachAct
|
||||
findPhonyProc2( const DLHead* elem, void* closure )
|
||||
{
|
||||
ForEachAct result = FEA_OK;
|
||||
FindPhonyData* fpd = (FindPhonyData*)closure;
|
||||
PhoniesMapState* ms = (PhoniesMapState*)closure;
|
||||
const PhoniesDataStrs* pds = (PhoniesDataStrs*)elem;
|
||||
if ( 0 == XP_STRCMP( fpd->phony, pds->phony ) ) {
|
||||
fpd->found = XP_TRUE;
|
||||
if ( 0 == XP_STRCMP( ms->phony, pds->phony ) ) {
|
||||
ms->found = elem;
|
||||
result |= FEA_EXIT;
|
||||
}
|
||||
return result;
|
||||
|
@ -997,9 +1017,9 @@ static ForEachAct
|
|||
findPhonyProc1( const DLHead* elem, void* closure )
|
||||
{
|
||||
ForEachAct result = FEA_OK;
|
||||
FindPhonyData* fpd = (FindPhonyData*)closure;
|
||||
PhoniesMapState* ms = (PhoniesMapState*)closure;
|
||||
const PhoniesDataCodes* pdc = (PhoniesDataCodes*)elem;
|
||||
if ( 0 == XP_STRCMP( fpd->isoCode, pdc->isoCode ) ) {
|
||||
if ( 0 == XP_STRCMP( ms->isoCode, pdc->isoCode ) ) {
|
||||
dll_map( &pdc->head->links, findPhonyProc2, NULL, closure );
|
||||
result |= FEA_EXIT;
|
||||
}
|
||||
|
@ -1012,14 +1032,13 @@ dvc_isLegalPhony( XW_DUtilCtxt* dutil, XWEnv xwe,
|
|||
{
|
||||
DevCtxt* dc = load( dutil, xwe );
|
||||
|
||||
FindPhonyData fpd = {
|
||||
PhoniesMapState ms = {
|
||||
.isoCode = isoCode,
|
||||
.phony = phony,
|
||||
.found = XP_FALSE,
|
||||
};
|
||||
dll_map( &dc->pd->links, findPhonyProc1, NULL, &fpd );
|
||||
dll_map( &dc->pd->links, findPhonyProc1, NULL, &ms );
|
||||
|
||||
return fpd.found;
|
||||
return NULL != ms.found;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1095,7 +1114,7 @@ dvc_init( XW_DUtilCtxt* dutil, XWEnv xwe )
|
|||
void
|
||||
dvc_cleanup( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||||
{
|
||||
DevCtxt* dc = freePhonyState( dutil, xwe, NULL );
|
||||
DevCtxt* dc = freePhonyState( dutil, xwe );
|
||||
|
||||
pthread_mutex_destroy( &dc->webSendMutex );
|
||||
|
||||
|
|
|
@ -68,10 +68,14 @@ void dvc_addLegalPhony( XW_DUtilCtxt* dutil, XWEnv xwe,
|
|||
XP_Bool dvc_isLegalPhony( XW_DUtilCtxt* dutil, XWEnv xwe,
|
||||
const XP_UCHAR* isoCode, const XP_UCHAR* phony );
|
||||
XP_Bool dvc_haveLegalPhonies( XW_DUtilCtxt* dutil, XWEnv xwe );
|
||||
XP_U16 dvc_clearLegalPhonies( XW_DUtilCtxt* dutil, XWEnv xwe );
|
||||
#ifdef DEBUG
|
||||
void dvc_listLegalPhonies( XW_DUtilCtxt* dutil, XWEnv xwe, XWStreamCtxt* stream );
|
||||
#endif
|
||||
void dvc_clearLegalPhony( XW_DUtilCtxt* dutil, XWEnv xwe,
|
||||
const XP_UCHAR* isoCode, const XP_UCHAR* phony );
|
||||
|
||||
typedef void (*WordCollector)(const XP_UCHAR* str, void* closure);
|
||||
void dvc_getIsoCodes( XW_DUtilCtxt* dutil, XWEnv env, WordCollector proc,
|
||||
void* closure );
|
||||
void dvc_getPhoniesFor( XW_DUtilCtxt* dutil, XWEnv env, const XP_UCHAR* code,
|
||||
WordCollector proc, void* closure );
|
||||
|
||||
/* All platforms need to call this shortly after setting up their XW_DUtilCtxt */
|
||||
void dvc_init( XW_DUtilCtxt* dutil, XWEnv xwe );
|
||||
|
|
|
@ -2508,6 +2508,20 @@ testStreams( LaunchParams* params )
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
testPhonies( LaunchParams* params )
|
||||
{
|
||||
XW_DUtilCtxt* dutil = params->dutil;
|
||||
dvc_addLegalPhony( dutil, NULL_XWE, "en", "QI" );
|
||||
dvc_addLegalPhony( dutil, NULL_XWE, "de", "PUTZ" );
|
||||
XP_ASSERT( dvc_isLegalPhony( dutil, NULL_XWE, "en", "QI" ) );
|
||||
XP_ASSERT( !dvc_isLegalPhony( dutil, NULL_XWE, "fr", "QI" ) );
|
||||
XP_ASSERT( !dvc_isLegalPhony( dutil, NULL_XWE, "de", "QI" ) );
|
||||
XP_ASSERT( dvc_haveLegalPhonies( dutil, NULL_XWE ) );
|
||||
dvc_clearLegalPhony( dutil, NULL_XWE, "en", "QI" );
|
||||
XP_ASSERT( !dvc_isLegalPhony( dutil, NULL_XWE, "en", "QI" ) );
|
||||
}
|
||||
|
||||
static void
|
||||
freeParams( LaunchParams* params )
|
||||
{
|
||||
|
@ -3437,6 +3451,7 @@ main( int argc, char** argv )
|
|||
mainParams.pDb = gdb_open( mainParams.dbName );
|
||||
|
||||
dvc_init( mainParams.dutil, NULL_XWE );
|
||||
testPhonies( &mainParams );
|
||||
|
||||
if ( mainParams.useCurses ) {
|
||||
/* if ( mainParams.needsNewGame ) { */
|
||||
|
|
Loading…
Add table
Reference in a new issue