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 07da001d4..570abd275 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DelegateBase.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DelegateBase.java @@ -106,6 +106,16 @@ public class DelegateBase implements DlgDelegate.DlgClickNotify { m_delegate.doSyncMenuitem(); } + 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 ); + } + ////////////////////////////////////////////////////////////////////// // DlgDelegate.DlgClickNotify interface ////////////////////////////////////////////////////////////////////// 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 416525a65..dcbac54da 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java @@ -769,7 +769,7 @@ public class GamesListDelegate extends DelegateBase break; case R.id.games_menu_study: - StudyListActivity.launchOrAlert( m_activity, StudyListActivity.NO_LANG, this ); + StudyListActivity.launchOrAlert( m_activity, StudyListDelegate.NO_LANG, this ); break; case R.id.games_menu_about: diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListActivity.java index 73b35550d..bbaa0dd5a 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListActivity.java @@ -21,6 +21,7 @@ package org.eehouse.android.xw4; import android.view.ViewGroup; import android.widget.ListView; +import android.app.Dialog; import android.app.AlertDialog; import android.content.Context; import android.content.Intent; @@ -44,44 +45,22 @@ import junit.framework.Assert; import org.eehouse.android.xw4.DlgDelegate.Action; import org.eehouse.android.xw4.jni.GameSummary; -public class StudyListActivity extends XWListActivity - implements OnItemSelectedListener, SelectableItem, - View.OnLongClickListener, View.OnClickListener { +public class StudyListActivity extends XWListActivity { - public static final int NO_LANG = -1; - - private static final String START_LANG = "START_LANG"; - - private Spinner m_spinner; - private View m_pickView; // LinearLayout, actually - private int[] m_langCodes; - private String[] m_words; - private HashSet m_checkeds; - private int m_langPosition; - private SLWordsAdapter m_adapter; - private ListView m_list; - private CharSequence m_origTitle; + private StudyListDelegate m_dlgt; @Override protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); - setContentView( R.layout.studylist ); - m_list = (ListView)findViewById( android.R.id.list ); - - m_spinner = (Spinner)findViewById( R.id.pick_lang_spinner ); - m_pickView = findViewById( R.id.pick_lang ); - - initOrFinish( getIntent() ); + m_dlgt = new StudyListDelegate( this, savedInstanceState ); } @Override public void onBackPressed() { - if ( 0 == m_checkeds.size() ) { + if ( !m_dlgt.backPressed() ) { super.onBackPressed(); - } else { - clearSels(); } } @@ -95,246 +74,26 @@ public class StudyListActivity extends XWListActivity @Override public boolean onPrepareOptionsMenu( Menu menu ) { - int nSel = m_checkeds.size(); - Utils.setItemVisible( menu, R.id.slmenu_copy_sel, 0 < nSel ); - Utils.setItemVisible( menu, R.id.slmenu_clear_sel, 0 < nSel ); - Utils.setItemVisible( menu, R.id.slmenu_select_all, - m_words.length > nSel ); - Utils.setItemVisible( menu, R.id.slmenu_deselect_all, 0 < nSel ); - boolean enable = 1 == nSel; - if ( enable ) { - String title = - getString( R.string.button_lookupf, getSelWords()[0] ); - menu.findItem( R.id.slmenu_lookup_sel ).setTitle( title ); - } - Utils.setItemVisible( menu, R.id.slmenu_lookup_sel, enable ); - return super.onPrepareOptionsMenu( menu ); + return m_dlgt.onPrepareOptionsMenu( menu ) + || super.onPrepareOptionsMenu( menu ); } + @Override public boolean onOptionsItemSelected( MenuItem item ) { - boolean handled = true; - switch ( item.getItemId() ) { - case R.id.slmenu_copy_sel: - showNotAgainDlgThen( R.string.not_again_studycopy, - R.string.key_na_studycopy, - Action.SL_COPY_ACTION ); - break; - case R.id.slmenu_clear_sel: - String msg = getString( R.string.confirm_studylist_clearf, - m_checkeds.size() ); - showConfirmThen( msg, Action.SL_CLEAR_ACTION ); - break; - - case R.id.slmenu_select_all: - for ( int ii = 0; ii < m_words.length; ++ii ) { - m_checkeds.add( ii ); - } - makeAdapter(); - setTitleBar(); - break; - case R.id.slmenu_deselect_all: - clearSels(); - break; - case R.id.slmenu_lookup_sel: - String[] oneWord = new String[]{ getSelWords()[0] }; - launchLookup( oneWord, m_langCodes[m_langPosition], true ); - break; - default: - handled = false; - } - return handled; + return m_dlgt.onOptionsItemSelected( item ) + || super.onOptionsItemSelected( item ); } - ////////////////////////////////////////////////// - // DlgDelegate.DlgClickNotify interface - ////////////////////////////////////////////////// @Override - public void dlgButtonClicked( Action action, int which, Object[] params ) + protected Dialog onCreateDialog( int id ) { - if ( AlertDialog.BUTTON_POSITIVE == which ) { - switch ( action ) { - case SL_CLEAR_ACTION: - String[] selWords = getSelWords(); - if ( selWords.length == m_words.length ) { - selWords = null; // all: easier on DB :-) - } - DBUtils.studyListClear( this, m_langCodes[m_langPosition], selWords ); - initOrFinish( null ); - break; - case SL_COPY_ACTION: - selWords = getSelWords(); - ClipboardManager clipboard = (ClipboardManager) - getSystemService( Context.CLIPBOARD_SERVICE ); - clipboard.setText( TextUtils.join( "\n", selWords ) ); - - String msg = getString( R.string.paste_donef, selWords.length ); - Utils.showToast( this, msg ); - break; - default: - Assert.fail(); - break; - } + Dialog dialog = m_dlgt.createDialog( id ); + if ( null == dialog ) { + dialog = super.onCreateDialog( id ); } - } - - ////////////////////////////////////////////////// - // AdapterView.OnItemSelectedListener interface - ////////////////////////////////////////////////// - public void onItemSelected( AdapterView parent, View view, - int position, long id ) - { - m_langPosition = position; - loadList(); // because language has changed - } - - public void onNothingSelected( AdapterView parent ) - { - } - - ////////////////////////////////////////////////// - // View.OnLongClickListener interface - ////////////////////////////////////////////////// - public boolean onLongClick( View view ) - { - boolean success = view instanceof SelectableItem.LongClickHandler; - if ( success ) { - ((SelectableItem.LongClickHandler)view).longClicked(); - } - return success; - } - - ////////////////////////////////////////////////// - // View.OnClickListener interface - ////////////////////////////////////////////////// - public void onClick( View view ) - { - XWListItem item = (XWListItem)view; - String[] words = { m_words[item.getPosition()] }; - launchLookup( words, m_langCodes[m_langPosition], true ); - } - - ////////////////////////////////////////////////// - // SelectableItem interface - ////////////////////////////////////////////////// - public void itemClicked( SelectableItem.LongClickHandler clicked, - GameSummary summary ) - { - m_checkeds.add( ((XWListItem)clicked).getPosition() ); - } - - public void itemToggled( SelectableItem.LongClickHandler toggled, - boolean selected ) - { - int position = ((XWListItem)toggled).getPosition(); - if ( selected ) { - m_checkeds.add( position ); - } else { - m_checkeds.remove( position ); - } - setTitleBar(); - } - - public boolean getSelected( SelectableItem.LongClickHandler obj ) - { - return m_checkeds.contains( ((XWListItem)obj).getPosition() ); - } - - private void loadList() - { - int lang = m_langCodes[m_langPosition]; - m_words = DBUtils.studyListWords( this, lang ); - m_checkeds = new HashSet(); - - makeAdapter(); - - String langName = DictLangCache.getLangNames( this )[lang]; - m_origTitle = getString( R.string.studylist_titlef, langName ); - setTitleBar(); - } - - private void makeAdapter() - { - m_adapter = new SLWordsAdapter(); - setListAdapter( m_adapter ); - } - - private void initOrFinish( Intent startIntent ) - { - m_langCodes = DBUtils.studyListLangs( this ); - if ( 0 == m_langCodes.length ) { - finish(); - } else if ( 1 == m_langCodes.length ) { - m_pickView.setVisibility( View.GONE ); - m_langPosition = 0; - loadList(); - } else { - int startLang = NO_LANG; - int startIndex = -1; - if ( null != startIntent ) { - startLang = startIntent.getIntExtra( START_LANG, NO_LANG ); - } - - String[] names = DictLangCache.getLangNames( this ); - String[] myNames = new String[m_langCodes.length]; - for ( int ii = 0; ii < m_langCodes.length; ++ii ) { - int lang = m_langCodes[ii]; - myNames[ii] = names[lang]; - if ( lang == startLang ) { - startIndex = ii; - } - } - - ArrayAdapter adapter = new - ArrayAdapter( this, - android.R.layout.simple_spinner_item, - myNames ); - adapter.setDropDownViewResource( android.R.layout. - simple_spinner_dropdown_item ); - m_spinner.setAdapter( adapter ); - m_spinner.setOnItemSelectedListener( this ); - if ( -1 != startIndex ) { - m_spinner.setSelection( startIndex ); - } - } - } - - private void setTitleBar() - { - CharSequence newTitle; - int nSels = m_checkeds.size(); - if ( 0 == nSels ) { - newTitle = m_origTitle; - } else { - newTitle = getString( R.string.sel_itemsf, nSels ); - } - setTitle( newTitle ); - - ABUtils.invalidateOptionsMenuIf( this ); - } - - private String[] getSelWords() - { - String[] result; - int nSels = m_checkeds.size(); - if ( nSels == m_words.length ) { - result = m_words; - } else { - result = new String[nSels]; - Iterator iter = m_checkeds.iterator(); - for ( int ii = 0; iter.hasNext(); ++ii ) { - result[ii] = m_words[iter.next()]; - } - } - return result; - } - - private void clearSels() - { - m_checkeds.clear(); - makeAdapter(); - setTitleBar(); - } + return dialog; + } // onCreateDialog public static void launchOrAlert( Context context, int lang, DlgDelegate.HasDlgDelegate dlg ) @@ -342,14 +101,14 @@ public class StudyListActivity extends XWListActivity String msg = null; if ( 0 == DBUtils.studyListLangs( context ).length ) { msg = context.getString( R.string.study_no_lists ); - } else if ( NO_LANG != lang && + } else if ( StudyListDelegate.NO_LANG != lang && 0 == DBUtils.studyListWords( context, lang ).length ) { String langname = DictLangCache.getLangName( context, lang ); msg = context.getString( R.string.study_no_langf, langname ); } else { Intent intent = new Intent( context, StudyListActivity.class ); - if ( NO_LANG != lang ) { - intent.putExtra( START_LANG, lang ); + if ( StudyListDelegate.NO_LANG != lang ) { + intent.putExtra( StudyListDelegate.START_LANG, lang ); } context.startActivity( intent ); } @@ -358,24 +117,4 @@ public class StudyListActivity extends XWListActivity dlg.showOKOnlyDialog( msg ); } } - - private class SLWordsAdapter extends XWListAdapter { - - public SLWordsAdapter() - { - super( m_words.length ); - } - - public View getView( int position, View convertView, ViewGroup parent ){ - XWListItem item = - XWListItem.inflate( StudyListActivity.this, - StudyListActivity.this ); - item.setPosition( position ); - item.setText( m_words[position] ); - item.setSelected( m_checkeds.contains(position) ); - item.setOnLongClickListener( StudyListActivity.this ); - item.setOnClickListener( StudyListActivity.this ); - return item; - } - } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListDelegate.java new file mode 100644 index 000000000..3f1d76fe8 --- /dev/null +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/StudyListDelegate.java @@ -0,0 +1,380 @@ +/* -*- 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.view.ViewGroup; +import android.widget.ListView; +import android.app.AlertDialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.ClipboardManager; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Spinner; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; + +import junit.framework.Assert; + +import org.eehouse.android.xw4.DlgDelegate.Action; +import org.eehouse.android.xw4.jni.GameSummary; + +public class StudyListDelegate extends DelegateBase + implements OnItemSelectedListener, SelectableItem, + View.OnLongClickListener, View.OnClickListener { + + public static final int NO_LANG = -1; + + protected static final String START_LANG = "START_LANG"; + + private XWListActivity m_activity; + private Spinner m_spinner; + private View m_pickView; // LinearLayout, actually + private int[] m_langCodes; + private String[] m_words; + private HashSet m_checkeds; + private int m_langPosition; + private SLWordsAdapter m_adapter; + private ListView m_list; + private CharSequence m_origTitle; + + protected StudyListDelegate( XWListActivity activity, Bundle savedInstanceState ) + { + super( activity, savedInstanceState ); + m_activity = activity; + init( savedInstanceState ); + } + + private void init( Bundle savedInstanceState ) + { + + m_activity.setContentView( R.layout.studylist ); + m_list = (ListView)m_activity.findViewById( android.R.id.list ); + + m_spinner = (Spinner)m_activity.findViewById( R.id.pick_lang_spinner ); + m_pickView = m_activity.findViewById( R.id.pick_lang ); + + initOrFinish( m_activity.getIntent() ); + } + + protected boolean backPressed() + { + boolean handled = 0 < m_checkeds.size(); + if ( handled ) { + clearSels(); + } + return handled; + } + + protected boolean onPrepareOptionsMenu( Menu menu ) + { + int nSel = m_checkeds.size(); + Utils.setItemVisible( menu, R.id.slmenu_copy_sel, 0 < nSel ); + Utils.setItemVisible( menu, R.id.slmenu_clear_sel, 0 < nSel ); + Utils.setItemVisible( menu, R.id.slmenu_select_all, + m_words.length > nSel ); + Utils.setItemVisible( menu, R.id.slmenu_deselect_all, 0 < nSel ); + boolean enable = 1 == nSel; + if ( enable ) { + String title = + m_activity.getString( R.string.button_lookupf, getSelWords()[0] ); + menu.findItem( R.id.slmenu_lookup_sel ).setTitle( title ); + } + Utils.setItemVisible( menu, R.id.slmenu_lookup_sel, enable ); + return true; + } + + protected boolean onOptionsItemSelected( MenuItem item ) + { + boolean handled = true; + switch ( item.getItemId() ) { + case R.id.slmenu_copy_sel: + showNotAgainDlgThen( R.string.not_again_studycopy, + R.string.key_na_studycopy, + Action.SL_COPY_ACTION ); + break; + case R.id.slmenu_clear_sel: + String msg = m_activity.getString( R.string.confirm_studylist_clearf, + m_checkeds.size() ); + showConfirmThen( msg, Action.SL_CLEAR_ACTION ); + break; + + case R.id.slmenu_select_all: + for ( int ii = 0; ii < m_words.length; ++ii ) { + m_checkeds.add( ii ); + } + makeAdapter(); + setTitleBar(); + break; + case R.id.slmenu_deselect_all: + clearSels(); + break; + case R.id.slmenu_lookup_sel: + String[] oneWord = new String[]{ getSelWords()[0] }; + launchLookup( oneWord, m_langCodes[m_langPosition], true ); + break; + default: + handled = false; + } + return handled; + } + + ////////////////////////////////////////////////// + // DlgDelegate.DlgClickNotify interface + ////////////////////////////////////////////////// + @Override + public void dlgButtonClicked( Action action, int which, Object[] params ) + { + if ( AlertDialog.BUTTON_POSITIVE == which ) { + switch ( action ) { + case SL_CLEAR_ACTION: + String[] selWords = getSelWords(); + if ( selWords.length == m_words.length ) { + selWords = null; // all: easier on DB :-) + } + DBUtils.studyListClear( m_activity, m_langCodes[m_langPosition], + selWords ); + initOrFinish( null ); + break; + case SL_COPY_ACTION: + selWords = getSelWords(); + ClipboardManager clipboard = (ClipboardManager) + m_activity.getSystemService( Context.CLIPBOARD_SERVICE ); + clipboard.setText( TextUtils.join( "\n", selWords ) ); + + String msg = m_activity.getString( R.string.paste_donef, + selWords.length ); + Utils.showToast( m_activity, msg ); + break; + default: + Assert.fail(); + break; + } + } + } + + ////////////////////////////////////////////////// + // AdapterView.OnItemSelectedListener interface + ////////////////////////////////////////////////// + public void onItemSelected( AdapterView parent, View view, + int position, long id ) + { + m_langPosition = position; + loadList(); // because language has changed + } + + public void onNothingSelected( AdapterView parent ) + { + } + + ////////////////////////////////////////////////// + // View.OnLongClickListener interface + ////////////////////////////////////////////////// + public boolean onLongClick( View view ) + { + boolean success = view instanceof SelectableItem.LongClickHandler; + if ( success ) { + ((SelectableItem.LongClickHandler)view).longClicked(); + } + return success; + } + + ////////////////////////////////////////////////// + // View.OnClickListener interface + ////////////////////////////////////////////////// + public void onClick( View view ) + { + XWListItem item = (XWListItem)view; + String[] words = { m_words[item.getPosition()] }; + launchLookup( words, m_langCodes[m_langPosition], true ); + } + + ////////////////////////////////////////////////// + // SelectableItem interface + ////////////////////////////////////////////////// + public void itemClicked( SelectableItem.LongClickHandler clicked, + GameSummary summary ) + { + m_checkeds.add( ((XWListItem)clicked).getPosition() ); + } + + public void itemToggled( SelectableItem.LongClickHandler toggled, + boolean selected ) + { + int position = ((XWListItem)toggled).getPosition(); + if ( selected ) { + m_checkeds.add( position ); + } else { + m_checkeds.remove( position ); + } + setTitleBar(); + } + + public boolean getSelected( SelectableItem.LongClickHandler obj ) + { + return m_checkeds.contains( ((XWListItem)obj).getPosition() ); + } + + private void loadList() + { + int lang = m_langCodes[m_langPosition]; + m_words = DBUtils.studyListWords( m_activity, lang ); + m_checkeds = new HashSet(); + + makeAdapter(); + + String langName = DictLangCache.getLangNames( m_activity )[lang]; + m_origTitle = m_activity.getString( R.string.studylist_titlef, langName ); + setTitleBar(); + } + + private void makeAdapter() + { + m_adapter = new SLWordsAdapter(); + m_activity.setListAdapter( m_adapter ); + } + + private void initOrFinish( Intent startIntent ) + { + m_langCodes = DBUtils.studyListLangs( m_activity ); + if ( 0 == m_langCodes.length ) { + m_activity.finish(); + } else if ( 1 == m_langCodes.length ) { + m_pickView.setVisibility( View.GONE ); + m_langPosition = 0; + loadList(); + } else { + int startLang = NO_LANG; + int startIndex = -1; + if ( null != startIntent ) { + startLang = startIntent.getIntExtra( START_LANG, NO_LANG ); + } + + String[] names = DictLangCache.getLangNames( m_activity ); + String[] myNames = new String[m_langCodes.length]; + for ( int ii = 0; ii < m_langCodes.length; ++ii ) { + int lang = m_langCodes[ii]; + myNames[ii] = names[lang]; + if ( lang == startLang ) { + startIndex = ii; + } + } + + ArrayAdapter adapter = new + ArrayAdapter( m_activity, + android.R.layout.simple_spinner_item, + myNames ); + adapter.setDropDownViewResource( android.R.layout. + simple_spinner_dropdown_item ); + m_spinner.setAdapter( adapter ); + m_spinner.setOnItemSelectedListener( this ); + if ( -1 != startIndex ) { + m_spinner.setSelection( startIndex ); + } + } + } + + private void setTitleBar() + { + CharSequence newTitle; + int nSels = m_checkeds.size(); + if ( 0 == nSels ) { + newTitle = m_origTitle; + } else { + newTitle = m_activity.getString( R.string.sel_itemsf, nSels ); + } + m_activity.setTitle( newTitle ); + + ABUtils.invalidateOptionsMenuIf( m_activity ); + } + + private String[] getSelWords() + { + String[] result; + int nSels = m_checkeds.size(); + if ( nSels == m_words.length ) { + result = m_words; + } else { + result = new String[nSels]; + Iterator iter = m_checkeds.iterator(); + for ( int ii = 0; iter.hasNext(); ++ii ) { + result[ii] = m_words[iter.next()]; + } + } + return result; + } + + private void clearSels() + { + m_checkeds.clear(); + makeAdapter(); + setTitleBar(); + } + + public static void launchOrAlert( Context context, int lang, + DlgDelegate.HasDlgDelegate dlg ) + { + String msg = null; + if ( 0 == DBUtils.studyListLangs( context ).length ) { + msg = context.getString( R.string.study_no_lists ); + } else if ( NO_LANG != lang && + 0 == DBUtils.studyListWords( context, lang ).length ) { + String langname = DictLangCache.getLangName( context, lang ); + msg = context.getString( R.string.study_no_langf, langname ); + } else { + Intent intent = new Intent( context, StudyListActivity.class ); + if ( NO_LANG != lang ) { + intent.putExtra( START_LANG, lang ); + } + context.startActivity( intent ); + } + + if ( null != msg ) { + dlg.showOKOnlyDialog( msg ); + } + } + + private class SLWordsAdapter extends XWListAdapter { + + public SLWordsAdapter() + { + super( m_words.length ); + } + + public View getView( int position, View convertView, ViewGroup parent ){ + XWListItem item = + XWListItem.inflate( m_activity, StudyListDelegate.this ); + item.setPosition( position ); + item.setText( m_words[position] ); + item.setSelected( m_checkeds.contains(position) ); + item.setOnLongClickListener( StudyListDelegate.this ); + item.setOnClickListener( StudyListDelegate.this ); + return item; + } + } +}