diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java index e60f5f643..6a9ebc811 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java @@ -525,6 +525,19 @@ public class DelegateBase implements DlgClickNotify, } } + protected Dialog buildNamerDlg( GameNamer namer, int titleID, + OnClickListener lstnr1, OnClickListener lstnr2, + DlgID dlgID ) + { + Dialog dialog = makeAlertBuilder() + .setTitle( titleID ) + .setPositiveButton( android.R.string.ok, lstnr1 ) + .setNegativeButton( android.R.string.cancel, lstnr2 ) + .setView( namer ) + .create(); + return dialog; + } + protected AlertDialog.Builder makeAlertBuilder() { return LocUtils.makeAlertBuilder( m_activity ); diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java index 29f97e74b..358fcf96f 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java @@ -2671,19 +2671,6 @@ public class GamesListDelegate extends ListDelegateBase return namer; } - private Dialog buildNamerDlg( GameNamer namer, int titleID, - OnClickListener lstnr1, OnClickListener lstnr2, - DlgID dlgID ) - { - Dialog dialog = makeAlertBuilder() - .setTitle( titleID ) - .setPositiveButton( android.R.string.ok, lstnr1 ) - .setNegativeButton( android.R.string.cancel, lstnr2 ) - .setView( namer ) - .create(); - return dialog; - } - private void showNewGroupIf() { long[] games = m_mySIS.moveAfterNewGroup; diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java index 4d6a0f043..060d538e1 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java @@ -20,39 +20,32 @@ package org.eehouse.android.xw4; import android.app.Activity; -import android.app.AlertDialog; +import android.app.Dialog; import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; 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.TextView; -import android.widget.ListView; + +import java.util.HashMap; +import java.util.Map; import org.eehouse.android.xw4.DlgDelegate.Action; import org.eehouse.android.xw4.ExpandImageButton.ExpandChangeListener; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet; import org.eehouse.android.xw4.jni.CommsAddrRec; -import org.eehouse.android.xw4.jni.GameSummary; import org.eehouse.android.xw4.jni.XwJNI; import org.eehouse.android.xw4.loc.LocUtils; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - public class KnownPlayersDelegate extends DelegateBase { private static final String TAG = KnownPlayersDelegate.class.getSimpleName(); private Activity mActivity; private ViewGroup mList; + private Map mChildren; protected KnownPlayersDelegate( Delegator delegator, Bundle sis ) { @@ -85,29 +78,77 @@ public class KnownPlayersDelegate extends DelegateBase { return handled; } + @Override + protected Dialog makeDialog( DBAlert alert, Object[] params ) + { + Dialog dialog = null; + + DlgID dlgID = alert.getDlgID(); + switch ( dlgID ) { + case RENAME_PLAYER: + final String oldName = (String)params[0]; + final GameNamer namer = (GameNamer)inflate( R.layout.rename_game ); + namer.setName( oldName ); + namer.setLabel( "some label" ); + + OnClickListener lstnr = new OnClickListener() { + @Override + public void onClick( DialogInterface dlg, int item ) { + String newName = namer.getName(); + if ( ! newName.equals(oldName) && 0 < newName.length() ) { + XwJNI.kplr_renamePlayer( oldName, newName ); + renameInPlace( oldName, newName ); + } + } + }; + dialog = buildNamerDlg( namer, R.string.game_name_group_title, + lstnr, null, dlgID ); + break; + } + + if ( null == dialog ) { + dialog = super.makeDialog( alert, params ); + } + return dialog; + } + private void populateList() { String[] players = XwJNI.kplr_getPlayers(); if ( null == players ) { finish(); } else { + mChildren = new HashMap<>(); for ( String player : players ) { - View child = makePlayerElem( player ); + ViewGroup child = makePlayerElem( player ); if ( null != child ) { mList.addView( child ); + mChildren.put( player, child ); } } } } - private View makePlayerElem( final String player ) + private void setName( ViewGroup item, String name ) { - View view = null; + TextView tv = (TextView)item.findViewById( R.id.player_name ); + tv.setText( name ); + } + + private void renameInPlace( String oldName, String newName ) + { + ViewGroup child = mChildren.remove( oldName ); + setName( child, newName ); + mChildren.put( newName, child ); + } + + private ViewGroup makePlayerElem( final String player ) + { + ViewGroup view = null; CommsAddrRec addr = XwJNI.kplr_getAddr( player ); if ( null != addr ) { final ViewGroup item = (ViewGroup)LocUtils.inflate( mActivity, R.layout.knownplayrs_item ); - TextView tv = (TextView)item.findViewById( R.id.player_name ); - tv.setText( player ); + setName( item, player ); view = item; // Iterate over address types @@ -132,7 +173,7 @@ public class KnownPlayersDelegate extends DelegateBase { .setOnClickListener( new View.OnClickListener() { @Override public void onClick( View view ) { - Utils.notImpl( mActivity ); + showDialogFragment( DlgID.RENAME_PLAYER, player ); } } ); item.findViewById( R.id.player_delete ) diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java index 6fbcb57dd..419a221a9 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java @@ -178,6 +178,13 @@ public class XwJNI { : null; } + public static void kplr_renamePlayer( String oldName, String newName ) + { + if ( BuildConfig.HAVE_KNOWN_PLAYERS ) { + kplr_renamePlayer( getJNI().m_ptrGlobals, oldName, newName ); + } + } + public static void kplr_deletePlayer( String player ) { if ( BuildConfig.HAVE_KNOWN_PLAYERS ) { @@ -708,6 +715,8 @@ public class XwJNI { private static native void dvc_parseMQTTPacket( long jniState, byte[] buf ); private static native String[] kplr_getPlayers( long jniState ); + private static native void kplr_renamePlayer( long jniState, String oldName, + String newName ); private static native void kplr_deletePlayer( long jniState, String player ); private static native CommsAddrRec kplr_getAddr( long jniState, String name ); diff --git a/xwords4/android/jni/xwjni.c b/xwords4/android/jni/xwjni.c index 626c134e8..df312fa9a 100644 --- a/xwords4/android/jni/xwjni.c +++ b/xwords4/android/jni/xwjni.c @@ -790,6 +790,19 @@ Java_org_eehouse_android_xw4_jni_XwJNI_kplr_1getPlayers return jnames; } +JNIEXPORT void JNICALL +Java_org_eehouse_android_xw4_jni_XwJNI_kplr_1renamePlayer +( JNIEnv* env, jclass C, jlong jniGlobalPtr, jstring jOldName, jstring jNewName ) +{ + DVC_HEADER(jniGlobalPtr); + const char* oldName = (*env)->GetStringUTFChars( env, jOldName, NULL ); + const char* newName = (*env)->GetStringUTFChars( env, jNewName, NULL ); + kplr_renamePlayer( globalState->dutil, env, oldName, newName ); + (*env)->ReleaseStringUTFChars( env, jOldName, oldName ); + (*env)->ReleaseStringUTFChars( env, jNewName, newName ); + DVC_HEADER_END(); +} + JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_kplr_1deletePlayer ( JNIEnv* env, jclass C, jlong jniGlobalPtr, jstring jName ) diff --git a/xwords4/common/knownplyr.c b/xwords4/common/knownplyr.c index 31ecb503b..304aaf7b9 100644 --- a/xwords4/common/knownplyr.c +++ b/xwords4/common/knownplyr.c @@ -264,17 +264,28 @@ kplr_getNames( XW_DUtilCtxt* dutil, XWEnv xwe, releaseState( dutil, xwe, state ); } +static KnownPlayer* +findByName( KPState* state, const XP_UCHAR* name ) +{ + KnownPlayer* result = NULL; + for ( KnownPlayer* kp = state->players; !!kp && !result; kp = kp->next ) { + if ( 0 == XP_STRCMP( kp->name, name ) ) { + result = kp; + } + } + return result; +} + XP_Bool kplr_getAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name, CommsAddrRec* addr ) { KPState* state = loadState( dutil, xwe ); XP_Bool found = XP_FALSE; - for ( KnownPlayer* kp = state->players; !!kp && !found; kp = kp->next ) { - found = 0 == XP_STRCMP( kp->name, name ); - if ( found ) { - *addr = kp->addr; - } + KnownPlayer* kp = findByName( state, name ); + found = NULL != kp; + if ( found ) { + *addr = kp->addr; } releaseState( dutil, xwe, state ); LOG_RETURNF( "%s", boolToStr(found) ); @@ -288,6 +299,20 @@ freeKP( XW_DUtilCtxt* dutil, KnownPlayer* kp ) XP_FREE( dutil->mpool, kp ); } +void +kplr_renamePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* oldName, + const XP_UCHAR* newName ) +{ + KPState* state = loadState( dutil, xwe ); + KnownPlayer* kp = findByName( state, oldName ); + if ( !!kp ) { + XP_FREEP( dutil->mpool, &kp->name ); + kp->name = copyString( dutil->mpool, newName ); + state->dirty = XP_TRUE; + } + releaseState( dutil, xwe, state ); +} + void kplr_deletePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name ) { diff --git a/xwords4/common/knownplyr.h b/xwords4/common/knownplyr.h index 16b4cb77f..bd9fbe3ed 100644 --- a/xwords4/common/knownplyr.h +++ b/xwords4/common/knownplyr.h @@ -36,6 +36,8 @@ void kplr_getNames( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR** players, XP_U16* nFound ); XP_Bool kplr_getAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name, CommsAddrRec* addr ); +void kplr_renamePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* oldName, + const XP_UCHAR* newName ); void kplr_deletePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name ); XP_Bool kplr_addAddrs( XW_DUtilCtxt* dutil, XWEnv xwe, const CurGameInfo* gi,