diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTInviteDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTInviteDelegate.java index 3332eff80..546292ddb 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTInviteDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BTInviteDelegate.java @@ -41,6 +41,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -87,12 +88,19 @@ public class BTInviteDelegate extends InviteDelegate { sort(); } - void remove(final Set checked) + void remove( final Set checked ) { - for ( InviterItem item : checked ) { - TwoStringPair pair = (TwoStringPair)item; - stamps.remove( pair.str2 ); - pairs.remove( pair ); + for ( String dev : checked ) { + stamps.remove( dev ); + + for ( Iterator iter = pairs.iterator(); + iter.hasNext(); ) { + TwoStringPair pair = iter.next(); + if ( pair.str2.equals( dev ) ) { + iter.remove(); + break; + } + } } } @@ -137,6 +145,8 @@ public class BTInviteDelegate extends InviteDelegate { @Override protected void init( Bundle savedInstanceState ) { + super.init( savedInstanceState ); + String msg = getQuantityString( R.plurals.invite_bt_desc_fmt_2, m_nMissing, m_nMissing ) + getString( R.string.invite_bt_desc_postscript ); diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/InviteDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/InviteDelegate.java index 2e7f5d004..8c140bd23 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/InviteDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/InviteDelegate.java @@ -89,6 +89,7 @@ abstract class InviteDelegate extends DelegateBase public static final String RAR = "RAR"; private static final String INTENT_KEY_NMISSING = "NMISSING"; protected static final String INTENT_KEY_LASTDEV = "LDEV"; + private static final String KEY_CHECKED = "CHECKED"; protected int m_nMissing; protected String m_lastDev; @@ -97,7 +98,7 @@ abstract class InviteDelegate extends DelegateBase private LinearLayout m_lv; private TextView m_ev; protected Map m_counts; - protected Set m_checked; + private HashSet m_checked; private boolean m_setChecked; private boolean m_remotesAreRobots; @@ -127,7 +128,27 @@ abstract class InviteDelegate extends DelegateBase @Override protected void init( Bundle sis ) { - super.init( sis ); + // DO NOT CALL super!!! + getBundledData( sis ); + } + + @Override + protected void onSaveInstanceState( Bundle outState ) + { + addBundledData( outState ); + super.onSaveInstanceState( outState ); + } + + private void getBundledData( Bundle bundle ) + { + if ( null != bundle ) { + m_checked = (HashSet)bundle.getSerializable( KEY_CHECKED ); + } + } + + private void addBundledData( Bundle bundle ) + { + bundle.putSerializable( KEY_CHECKED, m_checked ); } protected void init( String descTxt, int emptyMsgId ) @@ -198,13 +219,6 @@ abstract class InviteDelegate extends DelegateBase } } - protected void listSelected( InviterItem[] selected, String[] devs ) - { - for ( int ii = 0; ii < selected.length; ++ii ) { - devs[ii] = selected[ii].getDev(); - } - } - abstract void onBarButtonClicked( int id ); //////////////////////////////////////// @@ -214,10 +228,12 @@ abstract class InviteDelegate extends DelegateBase { if ( m_inviteButton == view ) { int len = m_checked.size(); - String[] devs = new String[len]; InviterItem[] items = getSelItems(); - listSelected( items, devs ); + String[] devs = new String[items.length]; + for ( int ii = 0; ii < items.length; ++ii ) { + devs[ii] = items[ii].getDev(); + } int[] counts = new int[len]; for ( int ii = 0; ii < len; ++ii ) { @@ -235,10 +251,15 @@ abstract class InviteDelegate extends DelegateBase private InviterItem[] getSelItems() { - int ii = 0; InviterItem[] result = new InviterItem[m_checked.size()]; - for ( InviterItem checked : m_checked ) { - result[ii++] = checked; + int next = 0; + for ( int ii = 0; ii < m_lv.getChildCount(); ++ii ) { + InviterItemFrame child = (InviterItemFrame)m_lv.getChildAt( ii ); + InviterItem item = child.getItem(); + if ( m_checked.contains( item.getDev() ) ) { + result[next++] = item; + Assert.assertTrue( child.isChecked() || !BuildConfig.DEBUG ); + } } return result; } @@ -270,22 +291,25 @@ abstract class InviteDelegate extends DelegateBase m_inviteButton.setEnabled( count > 0 && count <= m_nMissing ); } - final Set getChecked() { return m_checked; } + final Set getChecked() { return m_checked; } - protected void clearChecked() { m_checked.clear(); } + protected void clearChecked() + { + m_checked.clear(); + } // Figure which previously-checked items belong in the new set. private void updateChecked( List newItems ) { - Set old = new HashSet<>(); + Set old = new HashSet<>(); old.addAll( m_checked ); m_checked.clear(); - for ( Iterator iter = old.iterator(); iter.hasNext(); ) { - InviterItem oldItem = iter.next(); + for ( Iterator iter = old.iterator(); iter.hasNext(); ) { + String oldDev = iter.next(); for ( InviterItem item : newItems ) { - if ( item.equals( oldItem ) ) { - m_checked.add( item ); + if ( item.getDev().equals( oldDev ) ) { + m_checked.add( oldDev ); break; } } @@ -295,23 +319,23 @@ abstract class InviteDelegate extends DelegateBase // callbacks made by InviteItemsAdapter protected void onItemChecked( InviterItem item, boolean checked ) { + String dev = item.getDev(); if ( checked ) { - m_checked.add( item ); + m_checked.add( dev ); } else { - m_checked.remove( item ); + m_checked.remove( dev ); } } private View makeViewFor( int itemID, final InviterItem item ) { - final LinearLayout layout = (LinearLayout) + final InviterItemFrame layout = (InviterItemFrame) inflate( R.layout.inviter_item_frame ); - CheckBox box = (CheckBox)layout.findViewById( R.id.inviter_check ); + layout.setItem( item ); // Give subclass a chance to install and populate its view - FrameLayout frame = (FrameLayout)layout.findViewById( R.id.frame ); View child = inflate( itemID ); - frame.addView( child ); + ((FrameLayout)layout.findViewById( R.id.frame )).addView( child ); onChildAdded( child, item ); m_counts.put( item, 1 ); @@ -340,30 +364,28 @@ abstract class InviteDelegate extends DelegateBase } ); } - box.setOnCheckedChangeListener( new OnCheckedChangeListener() { + layout.setOnCheckedChangeListener( new OnCheckedChangeListener() { @Override public void onCheckedChanged( CompoundButton buttonView, boolean isChecked ) { if ( !isChecked ) { m_setChecked = false; } - if ( isChecked ) { - m_checked.add( item ); - } else { - m_checked.remove( item ); - } - onItemChecked( item, isChecked ); + onItemChecked( item, isChecked ); tryEnable(); } } ); - if ( m_setChecked || m_checked.contains( item ) ) { - box.setChecked( true ); - } else if ( null != m_lastDev && m_lastDev.equals(item.getDev()) ) { + String dev = item.getDev(); + boolean setIt = false; + if ( m_setChecked || m_checked.contains( dev ) ) { + setIt = true; + } else if ( null != m_lastDev && m_lastDev.equals( dev ) ) { m_lastDev = null; - box.setChecked( true ); + setIt = true; } + layout.setChecked( setIt ); return layout; } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/InviterItemFrame.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/InviterItemFrame.java new file mode 100644 index 000000000..c2c11c2b2 --- /dev/null +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/InviterItemFrame.java @@ -0,0 +1,57 @@ +/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */ +/* + * 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.content.Context; +import android.util.AttributeSet; +import android.widget.CheckBox; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.LinearLayout; + +import org.eehouse.android.xw4.InviteDelegate.InviterItem; + +public class InviterItemFrame extends LinearLayout /*implements InviterItem*/ { + private InviterItem mItem; + + public InviterItemFrame( Context context, AttributeSet as ) { + super( context, as ); + } + + void setItem( InviterItem item ) { mItem = item; } + InviterItem getItem() { return mItem; } + + void setOnCheckedChangeListener( OnCheckedChangeListener listener ) + { + ((CheckBox)findViewById( R.id.inviter_check )) + .setOnCheckedChangeListener( listener ); + } + + void setChecked( boolean newVal ) + { + ((CheckBox)findViewById( R.id.inviter_check )) + .setChecked( newVal ); + } + + boolean isChecked() + { + return ((CheckBox)findViewById( R.id.inviter_check )).isChecked(); + } +} diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java index 93c4971ac..89e9fd218 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java @@ -95,6 +95,8 @@ public class RelayInviteDelegate extends InviteDelegate { protected void init( Bundle savedInstanceState ) { if ( BuildConfig.RELAYINVITE_SUPPORTED ) { + super.init( savedInstanceState ); + String msg = getString( R.string.button_invite ); msg = getQuantityString( R.plurals.invite_relay_desc_fmt, m_nMissing, m_nMissing, msg ); @@ -470,11 +472,12 @@ public class RelayInviteDelegate extends InviteDelegate { private void getSavedState() { String dataString = DBUtils.getStringFor( m_activity, RECS_KEY, null ); - if ( null == dataString ) { + if ( null != dataString ) { + m_devIDRecs = (ArrayList)Utils.string64ToSerializable( dataString ); + } + + if ( null == m_devIDRecs ) { m_devIDRecs = new ArrayList(); - } else { - m_devIDRecs = (ArrayList)Utils - .string64ToSerializable( dataString ); } } @@ -500,23 +503,14 @@ public class RelayInviteDelegate extends InviteDelegate { private void clearSelectedImpl() { - Set checked = getChecked(); - Iterator iter = m_devIDRecs.iterator(); - for ( ; iter.hasNext(); ) { - if ( checked.contains( iter.next() ) ) { + Set checked = getChecked(); + for ( Iterator iter = m_devIDRecs.iterator(); iter.hasNext(); ) { + if ( checked.contains( iter.next().getDev() ) ) { iter.remove(); } } clearChecked(); saveAndRebuild(); - - // int count = m_adapter.getCount(); - // for ( int ii = count - 1; ii >= 0; --ii ) { - // if ( m_devIDRecs.get( ii ).m_isChecked ) { - // m_devIDRecs.remove( ii ); - // } - // } - // saveAndRebuild(); } private static class DevIDRec implements InviterItem, Serializable { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/SMSInviteDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/SMSInviteDelegate.java index 726581012..fa1916ed2 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/SMSInviteDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/SMSInviteDelegate.java @@ -89,11 +89,13 @@ public class SMSInviteDelegate extends InviteDelegate { @Override protected void init( Bundle savedInstanceState ) { + super.init( savedInstanceState ); + mMeans = InviteMeans.values()[getIntent().getIntExtra(INTENT_KEY_MEANS, -1)]; String msg = getString( R.string.button_invite ); msg = getQuantityString( R.plurals.invite_sms_desc_fmt, m_nMissing, m_nMissing, msg ); - super.init( msg, R.string.empty_sms_inviter ); + init( msg, R.string.empty_sms_inviter ); addButtonBar( R.layout.sms_buttons, BUTTONIDS ); getSavedState(); @@ -338,10 +340,10 @@ public class SMSInviteDelegate extends InviteDelegate { private void clearSelectedImpl() { - Set checked = getChecked(); + Set checked = getChecked(); Iterator iter = m_phoneRecs.iterator(); for ( ; iter.hasNext(); ) { - if ( checked.contains( iter.next() ) ) { + if ( checked.contains( iter.next().getDev() ) ) { iter.remove(); } } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/WiDirInviteDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/WiDirInviteDelegate.java index 97e6dd1a5..0347f2302 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/WiDirInviteDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/WiDirInviteDelegate.java @@ -60,6 +60,8 @@ public class WiDirInviteDelegate extends InviteDelegate @Override protected void init( Bundle savedInstanceState ) { + super.init( savedInstanceState ); + String msg = getString( R.string.button_invite ); msg = getQuantityString( R.plurals.invite_p2p_desc_fmt, m_nMissing, m_nMissing, msg ); @@ -94,15 +96,6 @@ public class WiDirInviteDelegate extends InviteDelegate ((TwoStrsItem)child).setStrings( pair.str2, pair.getDev() ); } - @Override - protected void listSelected( InviterItem[] selected, String[] devs ) - { - for ( int ii = 0; ii < selected.length; ++ii ) { - TwoStringPair pair = (TwoStringPair)selected[ii]; - devs[ii] = pair.getDev(); - } - } - // DevSetListener interface public void setChanged( Map macToName ) { diff --git a/xwords4/android/app/src/main/res/layout/inviter_item_frame.xml b/xwords4/android/app/src/main/res/layout/inviter_item_frame.xml index 9a05b6aca..ea7c34d88 100644 --- a/xwords4/android/app/src/main/res/layout/inviter_item_frame.xml +++ b/xwords4/android/app/src/main/res/layout/inviter_item_frame.xml @@ -1,14 +1,16 @@ - + - +