diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteActivity.java index 3ec62eba2..b650a66a4 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteActivity.java @@ -1,6 +1,6 @@ /* -*- compile-command: "find-and-ant.sh debug install"; -*- */ /* - * Copyright 2009-2011 by Eric House (xwords@eehouse.org). All + * Copyright 2009-2014 by Eric House (xwords@eehouse.org). All * rights reserved. * * This program is free software; you can redistribute it and/or @@ -20,152 +20,17 @@ package org.eehouse.android.xw4; -import android.app.Activity; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.ListView; -import android.widget.TextView; -import android.os.Handler; -import junit.framework.Assert; +public class BTInviteActivity extends InviteActivity { -import org.eehouse.android.xw4.loc.LocUtils; - -public class BTInviteActivity extends InviteActivity - implements CompoundButton.OnCheckedChangeListener { - - private boolean m_firstScan; - private int m_checkCount; - - public static void launchForResult( Activity activity, int nMissing, - int requestCode ) - { - Intent intent = new Intent( activity, BTInviteActivity.class ); - intent.putExtra( INTENT_KEY_NMISSING, nMissing ); - activity.startActivityForResult( intent, requestCode ); - } + private BTInviteDelegate m_dlgt; @Override protected void onCreate( Bundle savedInstanceState ) { - super.onCreate( savedInstanceState, R.layout.btinviter, - R.id.button_invite, R.id.button_rescan, - R.id.button_clear, R.id.invite_desc, - R.string.invite_bt_desc_fmt ); - tryEnable(); - m_firstScan = true; - BTService.clearDevices( this, null ); // will return names + super.onCreate( savedInstanceState ); + m_dlgt = new BTInviteDelegate( this, savedInstanceState ); + m_dlgt.init(); } - - // MultiService.MultiEventListener interface - @Override - public void eventOccurred( MultiService.MultiEvent event, final Object ... args ) - { - switch( event ) { - case SCAN_DONE: - post( new Runnable() { - public void run() { - synchronized( BTInviteActivity.this ) { - stopProgress(); - - String[] btDevNames = null; - if ( 0 < args.length ) { - btDevNames = (String[])(args[0]); - if ( null != btDevNames - && 0 == btDevNames.length ) { - btDevNames = null; - } - } - - if ( null == btDevNames && m_firstScan ) { - BTService.scan( BTInviteActivity.this ); - } - setListAdapter( new BTDevsAdapter( btDevNames ) ); - m_checkCount = 0; - tryEnable(); - m_firstScan = false; - } - } - } ); - break; - default: - super.eventOccurred( event, args ); - } - } - - protected void scan() - { - startProgress( R.string.scan_progress ); - BTService.scan( this ); - } - - protected void clearSelected() - { - BTService.clearDevices( this, listSelected() ); - } - - protected String[] listSelected() - { - ListView list = (ListView)findViewById( android.R.id.list ); - String[] result = new String[m_checkCount]; - int count = list.getChildCount(); - int index = 0; - for ( int ii = 0; ii < count; ++ii ) { - CheckBox box = (CheckBox)list.getChildAt( ii ); - if ( box.isChecked() ) { - result[index++] = box.getText().toString(); - } - } - return result; - } - - protected void tryEnable() - { - m_okButton.setEnabled( m_checkCount == m_nMissing ); - m_clearButton.setEnabled( 0 < m_checkCount ); - } - - public void onCheckedChanged( CompoundButton buttonView, - boolean isChecked ) - { - if ( isChecked ) { - ++m_checkCount; - } else { - --m_checkCount; - } - DbgUtils.logf( "BTInviteActivity.onCheckedChanged( isChecked=%b ); " - + "count now %d", isChecked, m_checkCount ); - tryEnable(); - } - - private class BTDevsAdapter extends XWListAdapter { - private String[] m_devs; - public BTDevsAdapter( String[] devs ) - { - super( null == devs? 0 : devs.length ); - m_devs = devs; - } - - public Object getItem( int position) { return m_devs[position]; } - public View getView( final int position, View convertView, - ViewGroup parent ) { - CheckBox box = (CheckBox) - LocUtils.inflate( BTInviteActivity.this, R.layout.btinviter_item ); - box.setText( m_devs[position] ); - box.setOnCheckedChangeListener( BTInviteActivity.this ); - return box; - } - - } - } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java new file mode 100644 index 000000000..dc1d2a784 --- /dev/null +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java @@ -0,0 +1,172 @@ +/* -*- compile-command: "find-and-ant.sh debug install"; -*- */ +/* + * Copyright 2009-2011 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.ListActivity; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.ListView; +import android.widget.TextView; +import android.os.Handler; + +import junit.framework.Assert; + +public class BTInviteDelegate extends InviteDelegate + implements CompoundButton.OnCheckedChangeListener { + + private ListActivity m_activity; + private boolean m_firstScan; + private int m_checkCount; + + public static void launchForResult( Activity activity, int nMissing, + int requestCode ) + { + Intent intent = new Intent( activity, BTInviteActivity.class ); + intent.putExtra( INTENT_KEY_NMISSING, nMissing ); + activity.startActivityForResult( intent, requestCode ); + } + + protected BTInviteDelegate( ListActivity activity, Bundle savedInstanceState ) + { + super( activity, savedInstanceState ); + m_activity = activity; + } + + protected void init() + { + super.init( R.layout.btinviter, + R.id.button_invite, R.id.button_rescan, + R.id.button_clear, R.id.invite_desc, + R.string.invite_bt_desc_fmt ); + m_firstScan = true; + BTService.clearDevices( m_activity, null ); // will return names + } + + // MultiService.MultiEventListener interface + @Override + public void eventOccurred( MultiService.MultiEvent event, final Object ... args ) + { + switch( event ) { + case SCAN_DONE: + post( new Runnable() { + public void run() { + synchronized( BTInviteDelegate.this ) { + stopProgress(); + + String[] btDevNames = null; + if ( 0 < args.length ) { + btDevNames = (String[])(args[0]); + if ( null != btDevNames + && 0 == btDevNames.length ) { + btDevNames = null; + } + } + + if ( null == btDevNames && m_firstScan ) { + BTService.scan( m_activity ); + } + setListAdapter( new BTDevsAdapter( btDevNames ) ); + m_checkCount = 0; + tryEnable(); + m_firstScan = false; + } + } + } ); + break; + default: + super.eventOccurred( event, args ); + } + } + + protected void scan() + { + startProgress( R.string.scan_progress ); + BTService.scan( m_activity ); + } + + protected void clearSelected() + { + BTService.clearDevices( m_activity, listSelected() ); + } + + protected String[] listSelected() + { + ListView list = (ListView)findViewById( android.R.id.list ); + String[] result = new String[m_checkCount]; + int count = list.getChildCount(); + int index = 0; + for ( int ii = 0; ii < count; ++ii ) { + CheckBox box = (CheckBox)list.getChildAt( ii ); + if ( box.isChecked() ) { + result[index++] = box.getText().toString(); + } + } + return result; + } + + protected void tryEnable() + { + m_okButton.setEnabled( m_checkCount == m_nMissing ); + m_clearButton.setEnabled( 0 < m_checkCount ); + } + + public void onCheckedChanged( CompoundButton buttonView, + boolean isChecked ) + { + if ( isChecked ) { + ++m_checkCount; + } else { + --m_checkCount; + } + DbgUtils.logf( "BTInviteActivity.onCheckedChanged( isChecked=%b ); " + + "count now %d", isChecked, m_checkCount ); + tryEnable(); + } + + private class BTDevsAdapter extends XWListAdapter { + private String[] m_devs; + public BTDevsAdapter( String[] devs ) + { + super( null == devs? 0 : devs.length ); + m_devs = devs; + } + + public Object getItem( int position) { return m_devs[position]; } + public View getView( final int position, View convertView, + ViewGroup parent ) { + CheckBox box = (CheckBox)inflate( R.layout.btinviter_item ); + box.setText( m_devs[position] ); + box.setOnCheckedChangeListener( BTInviteDelegate.this ); + return box; + } + } +} diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java index d6a877543..136d1ad69 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java @@ -62,7 +62,6 @@ import org.eehouse.android.xw4.jni.*; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole; import org.eehouse.android.xw4.jni.JNIThread.*; -import org.eehouse.android.xw4.loc.LocUtils; public class BoardDelegate extends DelegateBase implements TransportProcs.TPMsgHandler, View.OnClickListener, @@ -400,7 +399,7 @@ public class BoardDelegate extends DelegateBase public void onClick( DialogInterface dialog, int whichButton ) { m_resultCode = UtilCtxt.PICKER_BACKUP; - m_activity.removeDialog( dlgID.ordinal() ); + removeDialog( dlgID ); } }; ab.setPositiveButton( R.string.tilepick_undo, @@ -411,7 +410,7 @@ public class BoardDelegate extends DelegateBase public void onClick( DialogInterface dialog, int whichButton ) { m_resultCode = UtilCtxt.PICKER_PICKALL; - m_activity.removeDialog( dlgID.ordinal() ); + removeDialog( dlgID ); } }; ab.setNegativeButton( R.string.tilepick_all, doAllClicked ); @@ -603,12 +602,12 @@ public class BoardDelegate extends DelegateBase case BT_INVITE_RESULT: // onActivityResult is called immediately *before* // onResume -- meaning m_gi etc are still null. - m_missingDevs = data.getStringArrayExtra( BTInviteActivity.DEVS ); + m_missingDevs = data.getStringArrayExtra( BTInviteDelegate.DEVS ); break; case SMS_INVITE_RESULT: // onActivityResult is called immediately *before* // onResume -- meaning m_gi etc are still null. - m_missingDevs = data.getStringArrayExtra( SMSInviteActivity.DEVS ); + m_missingDevs = data.getStringArrayExtra( SMSInviteDelegate.DEVS ); break; } } @@ -913,11 +912,11 @@ public class BoardDelegate extends DelegateBase doSyncMenuitem(); break; case BT_PICK_ACTION: - BTInviteActivity.launchForResult( m_activity, m_nMissingPlayers, + BTInviteDelegate.launchForResult( m_activity, m_nMissingPlayers, BT_INVITE_RESULT ); break; case SMS_PICK_ACTION: - SMSInviteActivity.launchForResult( m_activity, m_nMissingPlayers, + SMSInviteDelegate.launchForResult( m_activity, m_nMissingPlayers, SMS_INVITE_RESULT ); break; case SMS_CONFIG_ACTION: @@ -1728,8 +1727,7 @@ public class BoardDelegate extends DelegateBase m_dlgTitle = R.string.badwords_title; waitBlockingDialog( DlgID.DLG_BADWORDS_BLK, 0 ); } else { - m_dlgBytes = message + - LocUtils.getString( m_activity, R.string.badwords_accept ); + m_dlgBytes = message + getString( R.string.badwords_accept ); m_dlgTitle = R.string.query_title; accept = 0 != waitBlockingDialog( DlgID.QUERY_REQUEST_BLK, 0 ); } @@ -1953,7 +1951,7 @@ public class BoardDelegate extends DelegateBase return new OnDismissListener() { public void onDismiss( DialogInterface di ) { releaseIfBlocking(); - m_activity.removeDialog( id ); + removeDialog( id ); } }; } @@ -2229,8 +2227,7 @@ public class BoardDelegate extends DelegateBase private void setupPasswdVars() { m_dlgTitleStr = getString( R.string.msg_ask_password_fmt, m_pwdName ); - m_passwdLyt = (LinearLayout)LocUtils.inflate( m_activity, - R.layout.passwd_view ); + m_passwdLyt = (LinearLayout)inflate( R.layout.passwd_view ); m_passwdEdit = (EditText)m_passwdLyt.findViewById( R.id.edit ); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatDelegate.java index 2bae846e4..776c784e9 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatDelegate.java @@ -32,8 +32,6 @@ import android.view.MenuItem; import android.view.MenuInflater; import android.widget.LinearLayout; -import org.eehouse.android.xw4.loc.LocUtils; - public class ChatDelegate extends DelegateBase implements View.OnClickListener { @@ -59,9 +57,9 @@ public class ChatDelegate extends DelegateBase for ( DBUtils.HistoryPair pair : pairs ) { TextView view = (TextView) - LocUtils.inflate( m_activity, pair.sourceLocal - ? R.layout.chat_history_local - : R.layout.chat_history_remote ); + inflate( pair.sourceLocal + ? R.layout.chat_history_local + : R.layout.chat_history_remote ); view.setText( pair.msg ); layout.addView( view ); } @@ -96,13 +94,13 @@ public class ChatDelegate extends DelegateBase EditText edit = (EditText)findViewById( R.id.chat_edit ); String text = edit.getText().toString(); if ( null == text || text.length() == 0 ) { - m_activity.setResult( Activity.RESULT_CANCELED ); + setResult( Activity.RESULT_CANCELED ); } else { DBUtils.appendChatHistory( m_activity, m_rowid, text, true ); Intent result = new Intent(); result.putExtra( BoardDelegate.INTENT_KEY_CHAT, text ); - m_activity.setResult( Activity.RESULT_OK, result ); + setResult( Activity.RESULT_OK, result ); } finish(); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DelegateBase.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DelegateBase.java index 014c835c3..0a908575b 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DelegateBase.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DelegateBase.java @@ -97,6 +97,21 @@ public class DelegateBase implements DlgDelegate.DlgClickNotify, m_activity.startActivityForResult( intent, requestCode ); } + protected void setResult( int result, Intent intent ) + { + m_activity.setResult( result, intent ); + } + + protected void setResult( int result ) + { + m_activity.setResult( result ); + } + + protected void onContentChanged() + { + m_activity.onContentChanged(); + } + protected void startActivity( Intent intent ) { m_activity.startActivity( intent ); @@ -112,6 +127,11 @@ public class DelegateBase implements DlgDelegate.DlgClickNotify, return LocUtils.getString( m_activity, resID, params ); } + protected String[] getStringArray( int resID ) + { + return LocUtils.getStringArray( m_activity, resID ); + } + protected View inflate( int resID ) { return LocUtils.inflate( m_activity, resID ); @@ -122,6 +142,16 @@ public class DelegateBase implements DlgDelegate.DlgClickNotify, m_delegate.showDialog( dlgID ); } + protected void removeDialog( DlgID dlgID ) + { + removeDialog( dlgID.ordinal() ); + } + + protected void removeDialog( int id ) + { + m_activity.removeDialog( id ); + } + protected Dialog onCreateDialog( int id ) { return m_delegate.createDialog( id ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictBrowseDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictBrowseDelegate.java index 34c73278c..263a3e70a 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictBrowseDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictBrowseDelegate.java @@ -46,9 +46,8 @@ import junit.framework.Assert; import org.eehouse.android.xw4.DlgDelegate.Action; import org.eehouse.android.xw4.jni.JNIUtilsImpl; import org.eehouse.android.xw4.jni.XwJNI; -import org.eehouse.android.xw4.loc.LocUtils; -public class DictBrowseDelegate extends DelegateBase +public class DictBrowseDelegate extends ListDelegateBase implements View.OnClickListener, OnItemSelectedListener { private static final String DICT_NAME = "DICT_NAME"; @@ -91,9 +90,9 @@ public class DictBrowseDelegate extends DelegateBase int format = m_browseState.m_minShown == m_browseState.m_maxShown ? R.string.dict_browse_title1_fmt : R.string.dict_browse_title_fmt; - setTitle( LocUtils.getString( m_activity, format, - m_name, m_nWords, m_browseState.m_minShown, - m_browseState.m_maxShown )); + setTitle( getString( format, + m_name, m_nWords, m_browseState.m_minShown, + m_browseState.m_maxShown )); String desc = XwJNI.dict_iter_getDesc( m_dictClosure ); if ( null != desc ) { @@ -107,8 +106,7 @@ public class DictBrowseDelegate extends DelegateBase public Object getItem( int position ) { TextView text = (TextView) - LocUtils.inflate( m_activity, - android.R.layout.simple_list_item_1 ); + inflate( android.R.layout.simple_list_item_1 ); String str = XwJNI.dict_iter_nthWord( m_dictClosure, position ); if ( null != str ) { text.setText( str ); @@ -198,8 +196,7 @@ public class DictBrowseDelegate extends DelegateBase // this is extended to include tile info -- it should // be -- then use an empty list elem and disable // search/minmax stuff. - String msg = LocUtils.getString( m_activity, R.string.alert_empty_dict_fmt, - name ); + String msg = getString( R.string.alert_empty_dict_fmt, name ); showOKOnlyDialogThen( msg, Action.FINISH_ACTION ); } else { figureMinMax( m_browseState.m_counts ); @@ -220,9 +217,9 @@ public class DictBrowseDelegate extends DelegateBase setUpSpinners(); - m_activity.setListAdapter( new DictListAdapter() ); - m_activity.getListView().setFastScrollEnabled( true ); - m_activity.getListView().setSelectionFromTop( m_browseState.m_pos, + setListAdapter( new DictListAdapter() ); + getListView().setFastScrollEnabled( true ); + getListView().setSelectionFromTop( m_browseState.m_pos, m_browseState.m_top ); } } @@ -231,7 +228,7 @@ public class DictBrowseDelegate extends DelegateBase protected void onPause() { if ( null != m_browseState ) { // already saved? - ListView list = m_activity.getListView(); + ListView list = getListView(); m_browseState.m_pos = list.getFirstVisiblePosition(); View view = list.getChildAt( 0 ); m_browseState.m_top = (view == null) ? 0 : view.getTop(); @@ -339,7 +336,7 @@ public class DictBrowseDelegate extends DelegateBase if ( null != text && 0 < text.length() ) { int pos = XwJNI.dict_iter_getStartsWith( m_dictClosure, text ); if ( 0 <= pos ) { - m_activity.getListView().setSelection( pos ); + getListView().setSelection( pos ); } else { DbgUtils.showf( m_activity, R.string.dict_browse_nowords_fmt, m_name, text ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportDelegate.java index 471dad0c5..89e37510e 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportDelegate.java @@ -40,8 +40,6 @@ import java.net.URLConnection; import java.security.MessageDigest; import java.util.HashMap; -import org.eehouse.android.xw4.loc.LocUtils; - import junit.framework.Assert; public class DictImportDelegate extends DelegateBase { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsDelegate.java index 4bf482dcf..58af9aaa1 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsDelegate.java @@ -60,7 +60,6 @@ import org.eehouse.android.xw4.jni.XwJNI; import org.eehouse.android.xw4.jni.JNIUtilsImpl; import org.eehouse.android.xw4.jni.GameSummary; import org.eehouse.android.xw4.DictUtils.DictLoc; -import org.eehouse.android.xw4.loc.LocUtils; public class DictsDelegate extends DelegateBase implements View.OnClickListener, AdapterView.OnItemLongClickListener, @@ -186,8 +185,7 @@ public class DictsDelegate extends DelegateBase public View getGroupView( int groupPosition, boolean isExpanded, View convertView, ViewGroup parent ) { - View row = LocUtils.inflate( m_activity, android.R.layout - .simple_expandable_list_item_1 ); + View row = inflate( android.R.layout.simple_expandable_list_item_1 ); TextView view = (TextView)row.findViewById( android.R.id.text1 ); view.setText( m_langs[groupPosition] ); return view; @@ -374,7 +372,7 @@ public class DictsDelegate extends DelegateBase } } - m_locNames = LocUtils.getStringArray( m_activity, R.array.loc_names ); + m_locNames = getStringArray( R.array.loc_names ); m_downloadStr = getString( R.string.download_dicts ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfigDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfigDelegate.java index 6d4e002dd..9016059df 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfigDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfigDelegate.java @@ -57,7 +57,6 @@ import org.eehouse.android.xw4.DlgDelegate.Action; import org.eehouse.android.xw4.jni.*; import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; -import org.eehouse.android.xw4.loc.LocUtils; public class GameConfigDelegate extends DelegateBase implements View.OnClickListener @@ -629,7 +628,7 @@ public class GameConfigDelegate extends DelegateBase saveChanges(); if ( m_forResult ) { applyChanges( true ); - m_activity.setResult( Activity.RESULT_OK, null ); + setResult( Activity.RESULT_OK, null ); finish(); } else if ( !m_gameStarted ) { // no confirm needed applyChanges( true ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java index 143847803..9665cadac 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java @@ -57,9 +57,8 @@ import junit.framework.Assert; import org.eehouse.android.xw4.DlgDelegate.Action; import org.eehouse.android.xw4.jni.*; -import org.eehouse.android.xw4.loc.LocUtils; -public class GamesListDelegate extends DelegateBase +public class GamesListDelegate extends ListDelegateBase implements OnItemLongClickListener, DBUtils.DBChangeListener, SelectableItem, DictImportDelegate.DownloadFinishedListener, @@ -239,7 +238,7 @@ public class GamesListDelegate extends DelegateBase DBUtils.setGroupName( m_activity, m_groupid, name ); m_adapter.inval( m_rowid ); - m_activity.onContentChanged(); + onContentChanged(); } }; dialog = buildNamerDlg( m_adapter.groupName( m_groupid ), @@ -254,7 +253,7 @@ public class GamesListDelegate extends DelegateBase String name = m_namer.getName(); DBUtils.addGroup( m_activity, name ); // m_adapter.inval(); - m_activity.onContentChanged(); + onContentChanged(); } }; dialog = buildNamerDlg( "", R.string.newgroup_label, @@ -289,7 +288,7 @@ public class GamesListDelegate extends DelegateBase DBUtils.moveGame( m_activity, rowid, gid ); } DBUtils.setGroupExpanded( m_activity, gid, true ); - m_activity.onContentChanged(); + onContentChanged(); } }; String[] groups = m_adapter.groupNames(); @@ -304,8 +303,7 @@ public class GamesListDelegate extends DelegateBase break; case GET_NAME: - layout = - (LinearLayout)LocUtils.inflate( m_activity, R.layout.dflt_name ); + layout = (LinearLayout)inflate( R.layout.dflt_name ); final EditText etext = (EditText)layout.findViewById( R.id.name_edit ); etext.setText( CommonPrefs.getDefaultPlayerName( m_activity, @@ -356,7 +354,7 @@ public class GamesListDelegate extends DelegateBase getBundledData( savedInstanceState ); setContentView( R.layout.game_list ); - ListView listview = m_activity.getListView(); + ListView listview = getListView(); DBUtils.setDBChangeListener( this ); boolean isUpgrade = Utils.firstBootThisVersion( m_activity ); @@ -458,7 +456,7 @@ public class GamesListDelegate extends DelegateBase m_activity.runOnUiThread( new Runnable() { public void run() { if ( countChanged || DBUtils.ROWID_NOTFOUND == rowid ) { - m_activity.onContentChanged(); + onContentChanged(); if ( DBUtils.ROWID_NOTFOUND != rowid ) { m_launchedGame = rowid; } @@ -562,7 +560,7 @@ public class GamesListDelegate extends DelegateBase for ( long rowid : rowids ) { GameUtils.resetGame( m_activity, rowid ); } - m_activity.onContentChanged(); // required because position may change + onContentChanged(); // required because position may change break; case SYNC_MENU: doSyncMenuitem(); @@ -582,7 +580,7 @@ public class GamesListDelegate extends DelegateBase GameUtils.deleteGroup( m_activity, groupID ); } clearSelections(); - m_activity.onContentChanged(); + onContentChanged(); break; case DELETE_GAMES: deleteGames( (long[])params[0] ); @@ -602,7 +600,7 @@ public class GamesListDelegate extends DelegateBase protected void contentChanged() { if ( null != m_adapter ) { - m_adapter.expandGroups( m_activity.getListView() ); + m_adapter.expandGroups( getListView() ); } } @@ -821,7 +819,7 @@ public class GamesListDelegate extends DelegateBase DBUtils.saveSummary( self, lock, smry ); m_selGames.add( lock.getRowid() ); lock.unlock(); - m_activity.onContentChanged(); + onContentChanged(); } }); } @@ -884,7 +882,7 @@ public class GamesListDelegate extends DelegateBase clearSelections(); } if ( changeContent ) { - m_activity.onContentChanged(); + onContentChanged(); } return handled;// || super.onOptionsItemSelected( item ); @@ -1147,7 +1145,7 @@ public class GamesListDelegate extends DelegateBase if ( m_adapter.setField( newField ) ) { // The adapter should be able to decide whether full // content change is required. PENDING - m_activity.onContentChanged(); + onContentChanged(); } } @@ -1155,8 +1153,7 @@ public class GamesListDelegate extends DelegateBase DialogInterface.OnClickListener lstnr, DlgID dlgID ) { - m_namer = (GameNamer) - LocUtils.inflate( m_activity, R.layout.rename_game ); + m_namer = (GameNamer)inflate( R.layout.rename_game ); m_namer.setName( curname ); m_namer.setLabel( labelID ); Dialog dialog = makeAlertBuilder() @@ -1343,13 +1340,13 @@ public class GamesListDelegate extends DelegateBase private GameListAdapter makeNewAdapter() { - ListView listview = m_activity.getListView(); + ListView listview = getListView(); String field = CommonPrefs.getSummaryField( m_activity ); long[] positions = XWPrefs.getGroupPositions( m_activity ); GameListAdapter adapter = new GameListAdapter( m_activity, listview, new Handler(), this, positions, field ); - m_activity.setListAdapter( adapter ); + setListAdapter( adapter ); adapter.expandGroups( listview ); return adapter; } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteActivity.java index 82b4cebab..58a2be783 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteActivity.java @@ -1,6 +1,6 @@ /* -*- compile-command: "find-and-ant.sh debug install"; -*- */ /* - * Copyright 2009-2011 by Eric House (xwords@eehouse.org). All + * Copyright 2009-2014 by Eric House (xwords@eehouse.org). All * rights reserved. * * This program is free software; you can redistribute it and/or @@ -20,81 +20,17 @@ package org.eehouse.android.xw4; -import android.app.Activity; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; +import android.app.ListActivity; import android.os.Bundle; -import android.os.Handler; -import android.view.View; -import android.view.ViewGroup; import android.view.Window; -import android.widget.AdapterView; -import android.widget.Button; -import android.widget.CompoundButton; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.TextView; -import org.eehouse.android.xw4.loc.LocUtils; +public class InviteActivity extends ListActivity { -import junit.framework.Assert; - -abstract class InviteActivity extends XWListActivity - implements View.OnClickListener { - - public static final String DEVS = "DEVS"; - protected static final String INTENT_KEY_NMISSING = "NMISSING"; - - protected int m_nMissing; - protected Button m_okButton; - protected Button m_rescanButton; - protected Button m_clearButton; - - protected void onCreate( Bundle savedInstanceState, int view_id, - int button_invite, int button_rescan, - int button_clear, int desc_id, int desc_strf ) + @Override + protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); - requestWindowFeature( Window.FEATURE_NO_TITLE ); - - setContentView( view_id ); - - Intent intent = getIntent(); - m_nMissing = intent.getIntExtra( INTENT_KEY_NMISSING, -1 ); - - m_okButton = (Button)findViewById( button_invite ); - m_okButton.setOnClickListener( this ); - m_rescanButton = (Button)findViewById( button_rescan ); - m_rescanButton.setOnClickListener( this ); - m_clearButton = (Button)findViewById( button_clear ); - m_clearButton.setOnClickListener( this ); - - TextView desc = (TextView)findViewById( desc_id ); - desc.setText( LocUtils.getString( this, desc_strf, m_nMissing ) ); - - tryEnable(); } - public void onClick( View view ) - { - if ( m_okButton == view ) { - Intent intent = new Intent(); - String[] devs = listSelected(); - intent.putExtra( DEVS, devs ); - setResult( Activity.RESULT_OK, intent ); - finish(); - } else if ( m_rescanButton == view ) { - scan(); - } else if ( m_clearButton == view ) { - clearSelected(); - } - } - - abstract void tryEnable() ; - abstract String[] listSelected(); - abstract void scan(); - abstract void clearSelected(); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java new file mode 100644 index 000000000..1613b6a65 --- /dev/null +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java @@ -0,0 +1,93 @@ +/* -*- compile-command: "find-and-ant.sh debug install"; -*- */ +/* + * Copyright 2009-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.Dialog; +import android.app.ListActivity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import junit.framework.Assert; + +abstract class InviteDelegate extends ListDelegateBase + implements View.OnClickListener { + + public static final String DEVS = "DEVS"; + protected static final String INTENT_KEY_NMISSING = "NMISSING"; + + protected int m_nMissing; + protected Button m_okButton; + protected Button m_rescanButton; + protected Button m_clearButton; + private ListActivity m_activity; + + public InviteDelegate( ListActivity activity, Bundle savedInstanceState ) + { + super( activity, savedInstanceState ); + m_activity = activity; + } + + protected void init( int view_id, int button_invite, int button_rescan, + int button_clear, int desc_id, int desc_strf ) + { + setContentView( view_id ); + + Intent intent = getIntent(); + m_nMissing = intent.getIntExtra( INTENT_KEY_NMISSING, -1 ); + + m_okButton = (Button)findViewById( button_invite ); + m_okButton.setOnClickListener( this ); + m_rescanButton = (Button)findViewById( button_rescan ); + m_rescanButton.setOnClickListener( this ); + m_clearButton = (Button)findViewById( button_clear ); + m_clearButton.setOnClickListener( this ); + + TextView desc = (TextView)findViewById( desc_id ); + desc.setText( getString( desc_strf, m_nMissing ) ); + + tryEnable(); + } + + public void onClick( View view ) + { + if ( m_okButton == view ) { + Intent intent = new Intent(); + String[] devs = listSelected(); + intent.putExtra( DEVS, devs ); + setResult( Activity.RESULT_OK, intent ); + finish(); + } else if ( m_rescanButton == view ) { + scan(); + } else if ( m_clearButton == view ) { + clearSelected(); + } + } + + abstract void tryEnable() ; + abstract String[] listSelected(); + abstract void scan(); + abstract void clearSelected(); +} diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ListDelegateBase.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ListDelegateBase.java new file mode 100644 index 000000000..862fb001b --- /dev/null +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ListDelegateBase.java @@ -0,0 +1,57 @@ +/* -*- compile-command: "find-and-ant.sh debug install"; -*- */ +/* + * 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.ListActivity; +import android.os.Bundle; +import android.widget.ListAdapter; +import android.widget.ListView; + +public class ListDelegateBase extends DelegateBase { + + private ListActivity m_activity; + + protected ListDelegateBase( ListActivity activity, Bundle savedInstanceState, + int menuID ) + { + super( activity, savedInstanceState, menuID ); + m_activity = activity; + } + + protected ListDelegateBase( ListActivity activity, Bundle savedState ) + { + this( activity, savedState, 0); + } + + protected void setListAdapter( ListAdapter adapter ) + { + m_activity.setListAdapter( adapter ); + } + + protected ListAdapter setListAdapter() + { + return m_activity.getListAdapter(); + } + + protected ListView getListView() + { + return m_activity.getListView(); + } +} diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameDelegate.java index 77a057ba6..87f37a6de 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameDelegate.java @@ -42,7 +42,6 @@ import org.eehouse.android.xw4.jni.CurGameInfo; import org.eehouse.android.xw4.jni.CommonPrefs; import org.eehouse.android.xw4.jni.CommsAddrRec; import org.eehouse.android.xw4.jni.XwJNI; -import org.eehouse.android.xw4.loc.LocUtils; public class NewGameDelegate extends DelegateBase { @@ -188,7 +187,7 @@ public class NewGameDelegate extends DelegateBase { if ( Activity.RESULT_CANCELED != resultCode ) { m_nameForBT = INVITE_FOR_BT == requestCode; String[] remoteDevs = - data.getStringArrayExtra( InviteActivity.DEVS ); + data.getStringArrayExtra( InviteDelegate.DEVS ); Assert.assertTrue( 1 == remoteDevs.length ); m_remoteDev = remoteDevs[0]; @@ -208,8 +207,7 @@ public class NewGameDelegate extends DelegateBase { DlgID dlgID = DlgID.values()[id]; switch( dlgID ) { case NAME_GAME: - final GameNamer namerView = - (GameNamer)LocUtils.inflate( m_activity, R.layout.rename_game ); + final GameNamer namerView = (GameNamer)inflate( R.layout.rename_game ); namerView.setLabel( m_nameForBT ? R.string.btname_label : R.string.smsname_label ); namerView.setName( m_gameName ); @@ -360,7 +358,7 @@ public class NewGameDelegate extends DelegateBase { intent.putExtra( GameUtils.INTENT_FORRESULT_ROWID, true ); startActivityForResult( intent, CONFIG_FOR_BT ); } else { - BTInviteActivity.launchForResult( m_activity, 1, INVITE_FOR_BT ); + BTInviteDelegate.launchForResult( m_activity, 1, INVITE_FOR_BT ); } } } @@ -381,7 +379,7 @@ public class NewGameDelegate extends DelegateBase { intent.putExtra( GameUtils.INTENT_FORRESULT_ROWID, true ); startActivityForResult( intent, CONFIG_FOR_SMS ); } else { - SMSInviteActivity.launchForResult( m_activity, 1, INVITE_FOR_SMS ); + SMSInviteDelegate.launchForResult( m_activity, 1, INVITE_FOR_SMS ); } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/PrefsDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/PrefsDelegate.java index da540ec74..2be45e4c1 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/PrefsDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/PrefsDelegate.java @@ -107,7 +107,7 @@ public class PrefsDelegate extends DelegateBase dialog = SMSCheckBoxPreference.onCreateDialog( m_activity, id ); break; case EXPLAIN_TITLE: - dialog = LocUtils.makeAlertBuilder( m_activity ) + dialog = makeAlertBuilder() .setMessage( R.string.no_hide_titlebar ) .setTitle( R.string.info_title ) .setPositiveButton( R.string.button_ok, null ) @@ -116,7 +116,7 @@ public class PrefsDelegate extends DelegateBase } if ( null == dialog && null != lstnr ) { - dialog = LocUtils.makeAlertBuilder( m_activity ) + dialog = makeAlertBuilder() .setTitle( R.string.query_title ) .setMessage( confirmID ) .setPositiveButton( R.string.button_ok, lstnr ) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteActivity.java index 7327030d8..4445f9c11 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteActivity.java @@ -21,398 +21,44 @@ package org.eehouse.android.xw4; import android.app.Activity; -import android.app.AlertDialog; import android.app.Dialog; -import android.content.DialogInterface; import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; import android.os.Bundle; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract; -import android.text.method.DialerKeyListener; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; -import android.widget.ImageButton; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; - -import org.eehouse.android.xw4.DlgDelegate.Action; -import org.eehouse.android.xw4.loc.LocUtils; public class SMSInviteActivity extends InviteActivity { - private static final int GET_CONTACT = 1; - private static final String SAVE_NAME = "SAVE_NAME"; - private static final String SAVE_NUMBER = "SAVE_NUMBER"; - - private ArrayList m_phoneRecs; - private SMSPhonesAdapter m_adapter; - private ImageButton m_addButton; - private String m_pendingName; - private String m_pendingNumber; - private boolean m_immobileConfirmed; - - public static void launchForResult( Activity activity, int nMissing, - int requestCode ) - { - Intent intent = new Intent( activity, SMSInviteActivity.class ); - intent.putExtra( INTENT_KEY_NMISSING, nMissing ); - activity.startActivityForResult( intent, requestCode ); - } + private SMSInviteDelegate m_dlgt; @Override protected void onCreate( Bundle savedInstanceState ) { - super.onCreate( savedInstanceState, R.layout.smsinviter, - R.id.button_invite, R.id.button_add, - R.id.button_clear, R.id.invite_desc, - R.string.invite_sms_desc_fmt ); - getBundledData( savedInstanceState ); - - m_addButton = (ImageButton)findViewById( R.id.manual_add_button ); - m_addButton.setOnClickListener( new View.OnClickListener() { - public void onClick( View view ) - { - showDialog( DlgID.GET_NUMBER.ordinal() ); - } - } ); - - getSavedState(); - rebuildList( true ); + super.onCreate( savedInstanceState ); + m_dlgt = new SMSInviteDelegate( this, savedInstanceState ); + m_dlgt.init( savedInstanceState ); } @Override protected void onSaveInstanceState( Bundle outState ) { super.onSaveInstanceState( outState ); - outState.putString( SAVE_NAME, m_pendingName ); - outState.putString( SAVE_NUMBER, m_pendingNumber ); + m_dlgt.onSaveInstanceState( outState ); } - private void getBundledData( Bundle bundle ) - { - if ( null != bundle ) { - m_pendingName = bundle.getString( SAVE_NAME ); - m_pendingNumber = bundle.getString( SAVE_NUMBER ); - } - } - @Override protected void onActivityResult( int requestCode, int resultCode, Intent data ) { - super.onActivityResult(requestCode, resultCode, data); - if ( Activity.RESULT_CANCELED != resultCode && data != null ) { - switch (requestCode) { - case GET_CONTACT: - addPhoneNumbers( data ); - break; - } - } + super.onActivityResult( requestCode, resultCode, data ); + m_dlgt.onActivityResult( requestCode, resultCode, data ); } @Override protected Dialog onCreateDialog( int id ) - { + { Dialog dialog = super.onCreateDialog( id ); if ( null == dialog ) { - DialogInterface.OnClickListener lstnr; - DlgID dlgID = DlgID.values()[id]; - switch( dlgID ) { - case GET_NUMBER: - final GameNamer namerView = - (GameNamer)LocUtils.inflate( this, R.layout.rename_game ); - namerView.setLabel( R.string.get_sms_number ); - namerView.setKeyListener(DialerKeyListener.getInstance()); - lstnr = new DialogInterface.OnClickListener() { - public void onClick( DialogInterface dlg, int item ) { - String number = namerView.getName(); - PhoneRec rec = new PhoneRec( number ); - m_pendingNumber = number; - m_pendingName = null; - showConfirmThen( R.string.warn_unlimited, - R.string.button_yes, - Action.POST_WARNING_ACTION ); - } - }; - dialog = new AlertDialog.Builder( this ) - .setNegativeButton( R.string.button_cancel, null ) - .setPositiveButton( R.string.button_ok, lstnr ) - .setView( namerView ) - .create(); - break; - } - Utils.setRemoveOnDismiss( this, dialog, dlgID ); + dialog = m_dlgt.onCreateDialog( id ); } return dialog; } - - protected void scan() - { - Intent intent = new Intent( Intent.ACTION_PICK, - ContactsContract.Contacts.CONTENT_URI ); - intent.setType( Phone.CONTENT_TYPE ); - startActivityForResult( intent, GET_CONTACT ); - } - - protected void clearSelected() - { - showConfirmThen( R.string.confirm_clear, Action.CLEAR_ACTION ); - } - - protected String[] listSelected() - { - int count = m_adapter.getCount(); - String[] result = new String[countChecks()]; - int index = 0; - Iterator iter = m_phoneRecs.iterator(); - for ( int ii = 0; iter.hasNext(); ++ii ) { - if ( iter.next().m_checked ) { - result[index++] = - ((SMSListItem)m_adapter.getItem(ii)).getNumber(); - } - } - return result; - } - - @Override - protected void tryEnable() - { - int count = countChecks(); - m_okButton.setEnabled( count == m_nMissing ); - m_clearButton.setEnabled( 0 < count ); - } - - // DlgDelegate.DlgClickNotify interface - @Override - public void dlgButtonClicked( Action action, int which, Object[] params ) - { - switch( which ) { - case AlertDialog.BUTTON_POSITIVE: - switch( action ) { - case CLEAR_ACTION: - clearSelectedImpl(); - break; - case USE_IMMOBILE_ACTION: - m_immobileConfirmed = true; - break; - case POST_WARNING_ACTION: - addChecked( new PhoneRec( m_pendingName, m_pendingNumber ) ); - saveAndRebuild(); - break; - } - break; - case DlgDelegate.DISMISS_BUTTON: - if ( Action.USE_IMMOBILE_ACTION == action && m_immobileConfirmed ) { - showConfirmThen( R.string.warn_unlimited, - R.string.button_yes, - Action.POST_WARNING_ACTION ); - } - break; - } - } - - private int countChecks() - { - int count = 0; - if ( null != m_phoneRecs ) { - Iterator iter = m_phoneRecs.iterator(); - while ( iter.hasNext() ) { - if ( iter.next().m_checked ) { - ++count; - } - } - } - return count; - } - - private void addPhoneNumbers( Intent intent ) - { - Uri data = intent.getData(); - Cursor cursor = managedQuery( data, - new String[] { Phone.DISPLAY_NAME, - Phone.NUMBER, - Phone.TYPE }, - null, null, null ); - // Have seen a crash reporting - // "android.database.StaleDataException: Attempted to access a - // cursor after it has been closed." when the query takes a - // long time to return. Be safe. - if ( null != cursor && !cursor.isClosed() ) { - if ( cursor.moveToFirst() ) { - String name = - cursor.getString( cursor. - getColumnIndex( Phone.DISPLAY_NAME)); - String number = - cursor.getString( cursor. - getColumnIndex( Phone.NUMBER ) ); - - int type = cursor.getInt( cursor. - getColumnIndex( Phone.TYPE ) ); - m_pendingName = name; - m_pendingNumber = number; - if ( Phone.TYPE_MOBILE == type ) { - showConfirmThen( R.string.warn_unlimited, - R.string.button_yes, - Action.POST_WARNING_ACTION ); - } else { - m_immobileConfirmed = false; - String msg = - LocUtils.getString( this, R.string.warn_nomobile_fmt, - number, name ); - showConfirmThen( msg, R.string.button_yes, - Action.USE_IMMOBILE_ACTION ); - } - } - } - } // addPhoneNumbers - - private void rebuildList( boolean checkIfAll ) - { - Collections.sort( m_phoneRecs, new Comparator() { - public int compare( PhoneRec rec1, PhoneRec rec2 ) { - return rec1.m_name.compareTo(rec2.m_name); - } - }); - m_adapter = new SMSPhonesAdapter(); - setListAdapter( m_adapter ); - if ( checkIfAll && m_phoneRecs.size() <= m_nMissing ) { - Iterator iter = m_phoneRecs.iterator(); - while ( iter.hasNext() ) { - iter.next().m_checked = true; - } - } - tryEnable(); - } - - private void getSavedState() - { - String[] phones = XWPrefs.getSMSPhones( this ); - - m_phoneRecs = new ArrayList(phones.length); - for ( String phone : phones ) { - PhoneRec rec = new PhoneRec( phone ); - m_phoneRecs.add( rec ); - } - } - - private void saveAndRebuild() - { - String[] phones = new String[m_phoneRecs.size()]; - Iterator iter = m_phoneRecs.iterator(); - for ( int ii = 0; iter.hasNext(); ++ii ) { - PhoneRec rec = iter.next(); - phones[ii] = rec.m_phone; - } - XWPrefs.setSMSPhones( this, phones ); - - rebuildList( false ); - } - - private void addChecked( PhoneRec rec ) - { - if ( m_nMissing <= countChecks() ) { - Iterator iter = m_phoneRecs.iterator(); - while ( iter.hasNext() ) { - iter.next().m_checked = false; - } - } - - rec.m_checked = true; - m_phoneRecs.add( rec ); - } - - private void clearSelectedImpl() - { - int count = m_adapter.getCount(); - for ( int ii = count - 1; ii >= 0; --ii ) { - if ( m_phoneRecs.get( ii ).m_checked ) { - m_phoneRecs.remove( ii ); - } - } - saveAndRebuild(); - } - - private class PhoneRec { - public String m_phone; - public String m_name; - public boolean m_checked; - public PhoneRec( String name, String phone ) - { - this( name, phone, false ); - } - public PhoneRec( String phone ) - { - this( null, phone, false ); - } - - public PhoneRec( String name, String phone, boolean checked ) - { - m_phone = phone; - m_checked = checked; - - if ( null == name ) { - name = Utils.phoneToContact( SMSInviteActivity.this, - phone, false ); - if ( null == name ) { - name = getString( R.string.manual_owner_name ); - } - } - m_name = name; - } - } - - private class SMSPhonesAdapter extends XWListAdapter { - private SMSListItem[] m_items; - - public SMSPhonesAdapter() - { - super( m_phoneRecs.size() ); - m_items = new SMSListItem[m_phoneRecs.size()]; - } - - public Object getItem( final int position ) - { - // For some reason I can't cache items to be returned. - // Checking/unchecking breaks for some but not all items, - // with some relation to whether they were scrolled into - // view. So build them anew each time (but still cache - // for by-index access.) - - SMSListItem item = - (SMSListItem)LocUtils.inflate( SMSInviteActivity.this, - R.layout.smsinviter_item ); - item.setChecked( m_phoneRecs.get(position).m_checked ); - - CompoundButton.OnCheckedChangeListener lstnr = - new CompoundButton.OnCheckedChangeListener() { - public void onCheckedChanged( CompoundButton bv, - boolean isChecked ) { - m_phoneRecs.get(position).m_checked = isChecked; - tryEnable(); - } - }; - item.setOnCheckedChangeListener( lstnr ); - PhoneRec rec = m_phoneRecs.get( position ); - item.setContents( rec.m_name, rec.m_phone ); - m_items[position] = item; - return item; - } - - public View getView( final int position, View convertView, - ViewGroup parent ) { - return (View)getItem( position ); - } - - public boolean isChecked( int index ) - { - SMSListItem item = m_items[index]; - boolean checked = null != item && item.isChecked(); - return checked; - } - } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java new file mode 100644 index 000000000..a3d8ee9ff --- /dev/null +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java @@ -0,0 +1,418 @@ +/* -*- compile-command: "find-and-ant.sh debug install"; -*- */ +/* + * Copyright 2012 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.ListActivity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract; +import android.text.method.DialerKeyListener; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.ImageButton; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +import org.eehouse.android.xw4.DlgDelegate.Action; + +public class SMSInviteDelegate extends InviteDelegate { + + private static final int GET_CONTACT = 1; + private static final String SAVE_NAME = "SAVE_NAME"; + private static final String SAVE_NUMBER = "SAVE_NUMBER"; + + private ArrayList m_phoneRecs; + private SMSPhonesAdapter m_adapter; + private ImageButton m_addButton; + private String m_pendingName; + private String m_pendingNumber; + private boolean m_immobileConfirmed; + private ListActivity m_activity; + + public static void launchForResult( Activity activity, int nMissing, + int requestCode ) + { + Intent intent = new Intent( activity, SMSInviteActivity.class ); + intent.putExtra( INTENT_KEY_NMISSING, nMissing ); + activity.startActivityForResult( intent, requestCode ); + } + + public SMSInviteDelegate( ListActivity activity, Bundle savedInstanceState ) + { + super( activity, savedInstanceState ); + m_activity = activity; + } + + protected void init( Bundle savedInstanceState ) + { + super.init( R.layout.smsinviter, + R.id.button_invite, R.id.button_add, + R.id.button_clear, R.id.invite_desc, + R.string.invite_sms_desc_fmt ); + getBundledData( savedInstanceState ); + + m_addButton = (ImageButton)findViewById( R.id.manual_add_button ); + m_addButton.setOnClickListener( new View.OnClickListener() { + public void onClick( View view ) + { + showDialog( DlgID.GET_NUMBER ); + } + } ); + + getSavedState(); + rebuildList( true ); + } + + protected void onSaveInstanceState( Bundle outState ) + { + outState.putString( SAVE_NAME, m_pendingName ); + outState.putString( SAVE_NUMBER, m_pendingNumber ); + } + + private void getBundledData( Bundle bundle ) + { + if ( null != bundle ) { + m_pendingName = bundle.getString( SAVE_NAME ); + m_pendingNumber = bundle.getString( SAVE_NUMBER ); + } + } + + protected void onActivityResult( int requestCode, int resultCode, + Intent data ) + { + // super.onActivityResult( requestCode, resultCode, data ); + if ( Activity.RESULT_CANCELED != resultCode && data != null ) { + switch (requestCode) { + case GET_CONTACT: + addPhoneNumbers( data ); + break; + } + } + } + + protected Dialog onCreateDialog( int id ) + { + Dialog dialog = super.onCreateDialog( id ); + if ( null == dialog ) { + DialogInterface.OnClickListener lstnr; + DlgID dlgID = DlgID.values()[id]; + switch( dlgID ) { + case GET_NUMBER: + final GameNamer namerView = + (GameNamer)inflate( R.layout.rename_game ); + namerView.setLabel( R.string.get_sms_number ); + namerView.setKeyListener(DialerKeyListener.getInstance()); + lstnr = new DialogInterface.OnClickListener() { + public void onClick( DialogInterface dlg, int item ) { + String number = namerView.getName(); + PhoneRec rec = new PhoneRec( number ); + m_pendingNumber = number; + m_pendingName = null; + showConfirmThen( R.string.warn_unlimited, + R.string.button_yes, + Action.POST_WARNING_ACTION ); + } + }; + dialog = makeAlertBuilder() + .setNegativeButton( R.string.button_cancel, null ) + .setPositiveButton( R.string.button_ok, lstnr ) + .setView( namerView ) + .create(); + break; + } + setRemoveOnDismiss( dialog, dlgID ); + } + return dialog; + } + + protected void scan() + { + Intent intent = new Intent( Intent.ACTION_PICK, + ContactsContract.Contacts.CONTENT_URI ); + intent.setType( Phone.CONTENT_TYPE ); + startActivityForResult( intent, GET_CONTACT ); + } + + protected void clearSelected() + { + showConfirmThen( R.string.confirm_clear, Action.CLEAR_ACTION ); + } + + protected String[] listSelected() + { + int count = m_adapter.getCount(); + String[] result = new String[countChecks()]; + int index = 0; + Iterator iter = m_phoneRecs.iterator(); + for ( int ii = 0; iter.hasNext(); ++ii ) { + if ( iter.next().m_checked ) { + result[index++] = + ((SMSListItem)m_adapter.getItem(ii)).getNumber(); + } + } + return result; + } + + @Override + protected void tryEnable() + { + int count = countChecks(); + m_okButton.setEnabled( count == m_nMissing ); + m_clearButton.setEnabled( 0 < count ); + } + + // DlgDelegate.DlgClickNotify interface + @Override + public void dlgButtonClicked( Action action, int which, Object[] params ) + { + switch( which ) { + case AlertDialog.BUTTON_POSITIVE: + switch( action ) { + case CLEAR_ACTION: + clearSelectedImpl(); + break; + case USE_IMMOBILE_ACTION: + m_immobileConfirmed = true; + break; + case POST_WARNING_ACTION: + addChecked( new PhoneRec( m_pendingName, m_pendingNumber ) ); + saveAndRebuild(); + break; + } + break; + case DlgDelegate.DISMISS_BUTTON: + if ( Action.USE_IMMOBILE_ACTION == action && m_immobileConfirmed ) { + showConfirmThen( R.string.warn_unlimited, + R.string.button_yes, + Action.POST_WARNING_ACTION ); + } + break; + } + } + + private int countChecks() + { + int count = 0; + if ( null != m_phoneRecs ) { + Iterator iter = m_phoneRecs.iterator(); + while ( iter.hasNext() ) { + if ( iter.next().m_checked ) { + ++count; + } + } + } + return count; + } + + private void addPhoneNumbers( Intent intent ) + { + Uri data = intent.getData(); + Cursor cursor = m_activity + .managedQuery( data, + new String[] { Phone.DISPLAY_NAME, + Phone.NUMBER, + Phone.TYPE }, + null, null, null ); + // Have seen a crash reporting + // "android.database.StaleDataException: Attempted to access a + // cursor after it has been closed." when the query takes a + // long time to return. Be safe. + if ( null != cursor && !cursor.isClosed() ) { + if ( cursor.moveToFirst() ) { + String name = + cursor.getString( cursor. + getColumnIndex( Phone.DISPLAY_NAME)); + String number = + cursor.getString( cursor. + getColumnIndex( Phone.NUMBER ) ); + + int type = cursor.getInt( cursor. + getColumnIndex( Phone.TYPE ) ); + m_pendingName = name; + m_pendingNumber = number; + if ( Phone.TYPE_MOBILE == type ) { + showConfirmThen( R.string.warn_unlimited, + R.string.button_yes, + Action.POST_WARNING_ACTION ); + } else { + m_immobileConfirmed = false; + String msg = getString( R.string.warn_nomobile_fmt, + number, name ); + showConfirmThen( msg, R.string.button_yes, + Action.USE_IMMOBILE_ACTION ); + } + } + } + } // addPhoneNumbers + + private void rebuildList( boolean checkIfAll ) + { + Collections.sort( m_phoneRecs, new Comparator() { + public int compare( PhoneRec rec1, PhoneRec rec2 ) { + return rec1.m_name.compareTo(rec2.m_name); + } + }); + m_adapter = new SMSPhonesAdapter(); + setListAdapter( m_adapter ); + if ( checkIfAll && m_phoneRecs.size() <= m_nMissing ) { + Iterator iter = m_phoneRecs.iterator(); + while ( iter.hasNext() ) { + iter.next().m_checked = true; + } + } + tryEnable(); + } + + private void getSavedState() + { + String[] phones = XWPrefs.getSMSPhones( m_activity ); + + m_phoneRecs = new ArrayList(phones.length); + for ( String phone : phones ) { + PhoneRec rec = new PhoneRec( phone ); + m_phoneRecs.add( rec ); + } + } + + private void saveAndRebuild() + { + String[] phones = new String[m_phoneRecs.size()]; + Iterator iter = m_phoneRecs.iterator(); + for ( int ii = 0; iter.hasNext(); ++ii ) { + PhoneRec rec = iter.next(); + phones[ii] = rec.m_phone; + } + XWPrefs.setSMSPhones( m_activity, phones ); + + rebuildList( false ); + } + + private void addChecked( PhoneRec rec ) + { + if ( m_nMissing <= countChecks() ) { + Iterator iter = m_phoneRecs.iterator(); + while ( iter.hasNext() ) { + iter.next().m_checked = false; + } + } + + rec.m_checked = true; + m_phoneRecs.add( rec ); + } + + private void clearSelectedImpl() + { + int count = m_adapter.getCount(); + for ( int ii = count - 1; ii >= 0; --ii ) { + if ( m_phoneRecs.get( ii ).m_checked ) { + m_phoneRecs.remove( ii ); + } + } + saveAndRebuild(); + } + + private class PhoneRec { + public String m_phone; + public String m_name; + public boolean m_checked; + public PhoneRec( String name, String phone ) + { + this( name, phone, false ); + } + public PhoneRec( String phone ) + { + this( null, phone, false ); + } + + public PhoneRec( String name, String phone, boolean checked ) + { + m_phone = phone; + m_checked = checked; + + if ( null == name ) { + name = Utils.phoneToContact( m_activity, phone, false ); + if ( null == name ) { + name = getString( R.string.manual_owner_name ); + } + } + m_name = name; + } + } + + private class SMSPhonesAdapter extends XWListAdapter { + private SMSListItem[] m_items; + + public SMSPhonesAdapter() + { + super( m_phoneRecs.size() ); + m_items = new SMSListItem[m_phoneRecs.size()]; + } + + public Object getItem( final int position ) + { + // For some reason I can't cache items to be returned. + // Checking/unchecking breaks for some but not all items, + // with some relation to whether they were scrolled into + // view. So build them anew each time (but still cache + // for by-index access.) + + SMSListItem item = + (SMSListItem)inflate( R.layout.smsinviter_item ); + item.setChecked( m_phoneRecs.get(position).m_checked ); + + CompoundButton.OnCheckedChangeListener lstnr = + new CompoundButton.OnCheckedChangeListener() { + public void onCheckedChanged( CompoundButton bv, + boolean isChecked ) { + m_phoneRecs.get(position).m_checked = isChecked; + tryEnable(); + } + }; + item.setOnCheckedChangeListener( lstnr ); + PhoneRec rec = m_phoneRecs.get( position ); + item.setContents( rec.m_name, rec.m_phone ); + m_items[position] = item; + return item; + } + + public View getView( final int position, View convertView, + ViewGroup parent ) { + return (View)getItem( position ); + } + + public boolean isChecked( int index ) + { + SMSListItem item = m_items[index]; + boolean checked = null != item && item.isChecked(); + return checked; + } + } +} diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListDelegate.java index a7dc61ab8..c4a9b0b22 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListDelegate.java @@ -46,7 +46,7 @@ import org.eehouse.android.xw4.DlgDelegate.Action; import org.eehouse.android.xw4.jni.GameSummary; import org.eehouse.android.xw4.loc.LocUtils; -public class StudyListDelegate extends DelegateBase +public class StudyListDelegate extends ListDelegateBase implements OnItemSelectedListener, SelectableItem, View.OnLongClickListener, View.OnClickListener { @@ -256,7 +256,7 @@ public class StudyListDelegate extends DelegateBase private void makeAdapter() { m_adapter = new SLWordsAdapter(); - m_activity.setListAdapter( m_adapter ); + setListAdapter( m_adapter ); } private void initOrFinish( Intent startIntent ) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWListActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWListActivity.java deleted file mode 100644 index 92b524e07..000000000 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWListActivity.java +++ /dev/null @@ -1,190 +0,0 @@ -/* -*- compile-command: "find-and-ant.sh debug install"; -*- */ -/* - * Copyright 2010 - 2011 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.ListActivity; -import android.app.Dialog; -import android.content.DialogInterface; -import android.os.Bundle; - -import org.eehouse.android.xw4.DlgDelegate.Action; - -import junit.framework.Assert; - -public class XWListActivity extends ListActivity - implements DlgDelegate.DlgClickNotify, MultiService.MultiEventListener { - - private DlgDelegate m_delegate; - - @Override - protected void onCreate( Bundle savedInstanceState ) - { - DbgUtils.logf( "%s.onCreate(this=%H)", getClass().getName(), this ); - super.onCreate( savedInstanceState ); - m_delegate = new DlgDelegate( this, this, savedInstanceState ); - } - - @Override - protected void onStart() - { - DbgUtils.logf( "%s.onStart(this=%H)", getClass().getName(), this ); - super.onStart(); - } - - @Override - protected void onResume() - { - DbgUtils.logf( "%s.onResume(this=%H)", getClass().getName(), this ); - XWService.setListener( this ); - super.onResume(); - } - - @Override - protected void onPause() - { - DbgUtils.logf( "%s.onPause(this=%H)", getClass().getName(), this ); - XWService.setListener( null ); - super.onPause(); - } - - @Override - protected void onStop() - { - DbgUtils.logf( "%s.onStop(this=%H)", getClass().getName(), this ); - super.onStop(); - } - - @Override - protected void onDestroy() - { - DbgUtils.logf( "%s.onDestroy(this=%H); isFinishing=%b", - getClass().getName(), this, isFinishing() ); - super.onDestroy(); - } - - @Override - protected void onSaveInstanceState( Bundle outState ) - { - super.onSaveInstanceState( outState ); - m_delegate.onSaveInstanceState( outState ); - } - - @Override - protected Dialog onCreateDialog( final int id ) - { - DbgUtils.logf( "%s.onCreateDialog() called", getClass().getName() ); - Dialog dialog = m_delegate.createDialog( id ); - if ( null == dialog ) { - dialog = super.onCreateDialog( id ); - } - return dialog; - } - - protected void showNotAgainDlgThen( int msgID, int prefsKey, - Action action ) - { - m_delegate.showNotAgainDlgThen( msgID, prefsKey, action ); - } - - protected void showNotAgainDlg( int msgID, int prefsKey ) - { - m_delegate.showNotAgainDlgThen( msgID, prefsKey ); - } - - protected void showOKOnlyDialogThen( String msg, Action action ) - { - m_delegate.showOKOnlyDialog( msg, action ); - } - - protected void showOKOnlyDialog( String msg ) - { - m_delegate.showOKOnlyDialog( msg ); - } - - protected void showOKOnlyDialog( int msgID ) - { - m_delegate.showOKOnlyDialog( msgID ); - } - - protected void showConfirmThen( String msg, Action action ) - { - m_delegate.showConfirmThen( msg, action ); - } - - protected void showConfirmThen( int msg, Action action ) - { - showConfirmThen( getString(msg), action ); - } - - protected void showConfirmThen( String msg, int posButton, Action action ) - { - m_delegate.showConfirmThen( msg, posButton, action ); - } - - protected void showConfirmThen( int msg, int posButton, Action action ) - { - m_delegate.showConfirmThen( getString(msg), posButton, action ); - } - - protected void doSyncMenuitem() - { - m_delegate.doSyncMenuitem(); - } - - protected void startProgress( int id ) - { - m_delegate.startProgress( id ); - } - - protected void stopProgress() - { - m_delegate.stopProgress(); - } - - protected boolean post( Runnable runnable ) - { - return m_delegate.post( runnable ); - } - - // DlgDelegate.DlgClickNotify interface - public void dlgButtonClicked( Action action, int which, Object[] params ) - { - Assert.fail(); - } - - protected void launchLookup( String[] words, int lang, boolean noStudy ) - { - m_delegate.launchLookup( words, lang, noStudy ); - } - - protected void launchLookup( String[] words, int lang ) - { - m_delegate.launchLookup( words, lang, false ); - } - - // MultiService.MultiEventListener interface - public void eventOccurred( MultiService.MultiEvent event, - final Object ... args ) - { - m_delegate.eventOccurred( event, args ); - } - -}