mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-05 20:45:49 +01:00
Merge branch 'android_branch' into fix_dlgdelegate
This commit is contained in:
commit
d1941090c5
35 changed files with 1260 additions and 281 deletions
|
@ -25,16 +25,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
>
|
||||
<Button android:id="@+id/exchange_commit"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_trade_commit"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
<Button android:id="@+id/exchange_cancel"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button_trade_cancel"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@
|
|||
>
|
||||
<Button android:id="@+id/button_rescan"
|
||||
android:text="@string/bt_pick_rescan_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
<!-- <Button android:id="@+id/button_reconfigure" -->
|
||||
<!-- android:text="@string/bt_pick_reconfig_button" -->
|
||||
|
@ -38,9 +36,7 @@
|
|||
<!-- /> -->
|
||||
<Button android:id="@+id/button_clear"
|
||||
android:text="@string/bt_pick_clear_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
>
|
||||
<LinearLayout android:id="@+id/empty_games_list"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -18,16 +16,20 @@
|
|||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:background="#FF202020"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
/>
|
||||
<TextView android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/empty_games_list2"
|
||||
android:background="#FF202020"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<ListView android:id="@id/android:list"
|
||||
<ExpandableListView android:id="@id/android:list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
|
@ -41,11 +43,21 @@
|
|||
android:text="@string/empty_list_msg"
|
||||
/>
|
||||
|
||||
<Button android:id="@+id/new_game"
|
||||
<LinearLayout android:id="@+id/new_buttons"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
>
|
||||
<Button android:id="@+id/new_game"
|
||||
android:text="@string/button_new_game"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
<Button android:id="@+id/new_group"
|
||||
android:text="@string/button_new_group"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
15
xwords4/android/XWords4/res/layout/game_list_group.xml
Normal file
15
xwords4/android/XWords4/res/layout/game_list_group.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<org.eehouse.android.xw4.GameListGroup
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/game_name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:paddingTop="3dp"
|
||||
android:paddingBottom="3dp"
|
||||
android:textStyle="italic"
|
||||
android:background="#FF7F7F7F"
|
||||
/>
|
|
@ -12,6 +12,7 @@
|
|||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:background="@android:drawable/list_selector_background"
|
||||
android:paddingLeft="12dp"
|
||||
>
|
||||
|
||||
<TextView android:id="@+id/view_unloaded"
|
||||
|
|
|
@ -51,16 +51,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
>
|
||||
<Button android:id="@+id/newgame_local"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/newgame_local"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
<Button android:id="@+id/newgame_local_config"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/newgame_local_config"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -93,17 +89,13 @@
|
|||
android:layout_height="wrap_content"
|
||||
>
|
||||
<Button android:id="@+id/newgame_invite"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/newgame_invite"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
|
||||
<Button android:id="@+id/newgame_net_config"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/newgame_net_config"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -160,17 +152,13 @@
|
|||
android:layout_height="wrap_content"
|
||||
>
|
||||
<Button android:id="@+id/newgame_invite_sms"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/newgame_invite"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
|
||||
<Button android:id="@+id/newgame_sms_config"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/newgame_net_config"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -228,17 +216,13 @@
|
|||
android:layout_height="wrap_content"
|
||||
>
|
||||
<Button android:id="@+id/newgame_invite_bt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/newgame_invite"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
|
||||
<Button android:id="@+id/newgame_bt_config"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/newgame_net_config"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -20,16 +20,12 @@
|
|||
android:layout_weight="0"
|
||||
>
|
||||
<Button android:id="@+id/revert_colors"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/button_revert_colors"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
<Button android:id="@+id/revert_all"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/button_revert_all"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
>
|
||||
<Button android:id="@+id/button_add"
|
||||
android:text="@string/button_sms_add"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_weight="1"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
<ImageButton android:id="@+id/manual_add_button"
|
||||
android:layout_height="fill_parent"
|
||||
|
@ -53,9 +51,7 @@
|
|||
/>
|
||||
<Button android:id="@+id/button_clear"
|
||||
android:text="@string/bt_pick_clear_button"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_weight="1"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
|
19
xwords4/android/XWords4/res/menu/games_list_group_menu.xml
Normal file
19
xwords4/android/XWords4/res/menu/games_list_group_menu.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/list_group_default"
|
||||
android:title="@string/list_group_default"
|
||||
/>
|
||||
<item android:id="@+id/list_group_rename"
|
||||
android:title="@string/list_group_rename"
|
||||
/>
|
||||
<item android:id="@+id/list_group_moveup"
|
||||
android:title="@string/list_group_moveup"
|
||||
/>
|
||||
<item android:id="@+id/list_group_movedown"
|
||||
android:title="@string/list_group_movedown"
|
||||
/>
|
||||
<item android:id="@+id/list_group_delete"
|
||||
android:title="@string/list_group_delete"
|
||||
/>
|
||||
</menu>
|
|
@ -7,6 +7,9 @@
|
|||
<item android:id="@+id/list_item_rename"
|
||||
android:title="@string/list_item_rename"
|
||||
/>
|
||||
<item android:id="@+id/list_item_move"
|
||||
android:title="@string/list_item_move"
|
||||
/>
|
||||
<item android:id="@+id/list_item_delete"
|
||||
android:title="@string/list_item_delete"
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
android:title="@string/button_new_game"
|
||||
android:icon="@android:drawable/ic_menu_add"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_newgroup"
|
||||
android:title="@string/button_new_group"
|
||||
android:icon="@android:drawable/ic_menu_add"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_prefs"
|
||||
android:title="@string/menu_prefs"
|
||||
android:icon="@android:drawable/ic_menu_preferences"
|
||||
|
@ -23,10 +27,6 @@
|
|||
android:icon="@android:drawable/ic_menu_send"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/gamel_menu_delete_all"
|
||||
android:title="@string/gamel_menu_delete_all"
|
||||
android:icon="@android:drawable/ic_menu_delete"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_checkmoves"
|
||||
android:title="@string/gamel_menu_checkmoves"
|
||||
android:icon="@drawable/stat_notify_sync"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<h3>New with this release</h3>
|
||||
<ul>
|
||||
<li>Allow grouping of games in collapsible user-defined categores:
|
||||
<li>Allow grouping of games in collapsible user-defined categories:
|
||||
"Games with Kati", "Finished games", etc.</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
<string name="key_relay_regid">key_relay_regid</string>
|
||||
<string name="key_checked_sms">key_checked_sms</string>
|
||||
<string name="key_default_group">key_default_group</string>
|
||||
<string name="key_group_posns">key_group_posns</string>
|
||||
|
||||
<string name="key_notagain_sync">key_notagain_sync</string>
|
||||
<string name="key_notagain_chat">key_notagain_chat</string>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
menuitem in main games-list screen's menu. (The botton can
|
||||
be hidden in the same way as the above text.) -->
|
||||
<string name="button_new_game">Add game</string>
|
||||
<string name="button_new_group">Add group</string>
|
||||
|
||||
<!-- When the game list is empty and the above messages and button
|
||||
are hidden via preferences, this text is shown -->
|
||||
|
@ -142,6 +143,9 @@
|
|||
<string name="list_item_config">Game settings...</string>
|
||||
<!-- pulls up dialog to rename (change name of) the selected game -->
|
||||
<string name="list_item_rename">Rename...</string>
|
||||
<!-- pulls up dialog to change the group of the selected game -->
|
||||
<string name="list_item_move">Move to group...</string>
|
||||
|
||||
<!-- pulls up dialog to delete the selected game -->
|
||||
<string name="list_item_delete">Delete</string>
|
||||
<!-- pulls up dialog to reset the selected game, that is to remove
|
||||
|
@ -181,12 +185,6 @@
|
|||
game? Resetting erases all moves and any connection
|
||||
information.</string>
|
||||
|
||||
<!-- Text of confirmation dialog posted when gamel_menu_delete_all
|
||||
button is pressed -->
|
||||
<string name="confirm_delete_all">Are you sure you want to delete
|
||||
all games?</string>
|
||||
|
||||
|
||||
<!--
|
||||
############################################################
|
||||
# :Screens:
|
||||
|
@ -630,7 +628,8 @@
|
|||
|
||||
<!-- Appended to the above in the phonies_warn case. User may
|
||||
ignore the warning -->
|
||||
<string name="badwords_accept"> Do you still want to accept this move?</string>
|
||||
<string name="badwords_accept">\u0020Do you still want to accept
|
||||
this move?</string>
|
||||
<!-- Appended to the above in the phonies_disallow case. User has
|
||||
lost his turn. -->
|
||||
<string name="badwords_lost"> Turn lost.</string>
|
||||
|
@ -1235,7 +1234,7 @@
|
|||
|
||||
\u003cbr \\\u003E
|
||||
\u003cbr \\\u003E
|
||||
(full link: %1$s)
|
||||
(full link: %1$s )
|
||||
</string>
|
||||
|
||||
<!-- This is the body of the text version of the invitation. A URL
|
||||
|
@ -2089,7 +2088,7 @@
|
|||
<!-- -->
|
||||
<string name="new_app_availf">New version of %s</string>
|
||||
<!-- -->
|
||||
<string name="new_app_avail">Tap to download</string>
|
||||
<string name="new_app_avail">Tap to download and install</string>
|
||||
<!-- Used in formatting final scores display -->
|
||||
<string name="str_resigned">Resigned</string>
|
||||
<!-- Used in formatting final scores display -->
|
||||
|
@ -2130,9 +2129,32 @@
|
|||
|
||||
<string name="download_path_title">Downloads Directory</string>
|
||||
|
||||
<string name="newgroup_label">Name your new group:</string>
|
||||
|
||||
<string name="list_group_delete">Delete</string>
|
||||
<string name="list_group_rename">Rename</string>
|
||||
<string name="list_group_default">Put new games here</string>
|
||||
<string name="list_group_moveup">Move up</string>
|
||||
<string name="list_group_movedown">Move down</string>
|
||||
|
||||
<string name="group_cur_games">My games</string>
|
||||
<string name="group_new_games">New games</string>
|
||||
|
||||
<string name="group_confirm_del">Are you sure you want to delete
|
||||
this group?</string>
|
||||
<string name="group_confirm_delf">\u0020(It contains %d game[s],
|
||||
which will also be deleted.)</string>
|
||||
|
||||
<string name="rename_group_label">Change the name of this group to:</string>
|
||||
<string name="game_name_group_title">Name group</string>
|
||||
|
||||
<string name="cannot_delete_default_group">The group for new games
|
||||
cannot be deleted."</string>
|
||||
|
||||
<string name="no_move_onegroup">Moving is impossible until there
|
||||
is more than one group.</string>
|
||||
<string name="group_namef">%1$s (%2$d games)</string>
|
||||
|
||||
<!-- Button shown in game over dialog triggering creation of new
|
||||
game with the same players and parameters as the one that
|
||||
just ended. -->
|
||||
|
@ -2141,4 +2163,5 @@
|
|||
<string name="square_tiles">Square rack tiles</string>
|
||||
<string name="square_tiles_summary">Even if they can be taller</string>
|
||||
|
||||
<string name="change_groupf">Move game %s</string>
|
||||
</resources>
|
||||
|
|
|
@ -60,5 +60,11 @@
|
|||
<item name="android:layout_marginBottom">3sp</item>
|
||||
</style>
|
||||
|
||||
<style name="spaced_buttons">
|
||||
<item name="android:layout_width">fill_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.eehouse.android.xw4;
|
|||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
|
@ -33,7 +34,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||
public static final String TABLE_NAME_DICTINFO = "dictinfo";
|
||||
public static final String TABLE_NAME_GROUPS = "groups";
|
||||
private static final String DB_NAME = "xwdb";
|
||||
private static final int DB_VERSION = 15;
|
||||
private static final int DB_VERSION = 16;
|
||||
|
||||
public static final String GAME_NAME = "GAME_NAME";
|
||||
public static final String NUM_MOVES = "NUM_MOVES";
|
||||
|
@ -197,6 +198,8 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||
case 14:
|
||||
addSumColumn( db, GROUPID );
|
||||
createGroupsTable( db );
|
||||
case 15:
|
||||
moveToCurGames( db );
|
||||
// nothing yet
|
||||
break;
|
||||
default:
|
||||
|
@ -260,4 +263,21 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||
XWPrefs.setDefaultNewGameGroup( m_context, newGroup );
|
||||
}
|
||||
|
||||
// Move all existing games to the row previously named "cur games'
|
||||
private void moveToCurGames( SQLiteDatabase db )
|
||||
{
|
||||
String name = m_context.getString( R.string.group_cur_games );
|
||||
String[] columns = { "rowid" };
|
||||
String selection = String.format( "%s = '%s'", GROUPNAME, name );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_GROUPS, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
long rowid = cursor.getLong( cursor.getColumnIndex("rowid") );
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( GROUPID, rowid );
|
||||
db.update( DBHelper.TABLE_NAME_SUM, values, null, null );
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -320,6 +320,7 @@ public class DBUtils {
|
|||
}
|
||||
db.close();
|
||||
notifyListeners( rowid, false );
|
||||
invalGroupsCache();
|
||||
}
|
||||
} // saveSummary
|
||||
|
||||
|
@ -728,6 +729,7 @@ public class DBUtils {
|
|||
if ( -1 != rowid ) { // Means new game?
|
||||
notifyListeners( rowid, false );
|
||||
}
|
||||
invalGroupsCache();
|
||||
return rowid;
|
||||
}
|
||||
|
||||
|
@ -782,35 +784,6 @@ public class DBUtils {
|
|||
notifyListeners( lock.getRowid(), true );
|
||||
}
|
||||
|
||||
public static long[] gamesList( Context context )
|
||||
{
|
||||
long[] result;
|
||||
synchronized( DBUtils.class ) {
|
||||
if ( null == s_cachedRowIDs ) {
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
|
||||
String[] columns = { ROW_ID };
|
||||
String orderBy = DBHelper.CREATE_TIME + " DESC";
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM,
|
||||
columns, null, null, null,
|
||||
null, orderBy );
|
||||
int count = cursor.getCount();
|
||||
s_cachedRowIDs = new long[count];
|
||||
int index = cursor.getColumnIndex( ROW_ID );
|
||||
for ( int ii = 0; cursor.moveToNext(); ++ii ) {
|
||||
s_cachedRowIDs[ii] = cursor.getLong( index );
|
||||
}
|
||||
cursor.close();
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
result = s_cachedRowIDs;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void clearRowIDsCache()
|
||||
{
|
||||
synchronized( DBUtils.class ) {
|
||||
|
@ -865,6 +838,249 @@ public class DBUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
// Groups stuff
|
||||
public static class GameGroupInfo {
|
||||
public String m_name;
|
||||
public boolean m_expanded;
|
||||
public long m_lastMoveTime;
|
||||
public boolean m_hasTurn;
|
||||
public boolean m_turnLocal;
|
||||
|
||||
public GameGroupInfo( String name, boolean expanded ) {
|
||||
m_name = name; m_expanded = expanded;
|
||||
m_lastMoveTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static HashMap<Long,GameGroupInfo> s_groupsCache = null;
|
||||
|
||||
private static void invalGroupsCache()
|
||||
{
|
||||
s_groupsCache = null;
|
||||
}
|
||||
|
||||
// Return map of string (group name) to info about all games in
|
||||
// that group.
|
||||
public static HashMap<Long,GameGroupInfo> getGroups( Context context )
|
||||
{
|
||||
if ( null == s_groupsCache ) {
|
||||
HashMap<Long,GameGroupInfo> result =
|
||||
new HashMap<Long,GameGroupInfo>();
|
||||
initDB( context );
|
||||
String[] columns = { ROW_ID, DBHelper.GROUPNAME,
|
||||
DBHelper.EXPANDED };
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_GROUPS, columns,
|
||||
null, // selection
|
||||
null, // args
|
||||
null, // groupBy
|
||||
null, // having
|
||||
null //orderby
|
||||
);
|
||||
int idIndex = cursor.getColumnIndex( ROW_ID );
|
||||
int nameIndex = cursor.getColumnIndex( DBHelper.GROUPNAME );
|
||||
int expandedIndex = cursor.getColumnIndex( DBHelper.EXPANDED );
|
||||
|
||||
while ( cursor.moveToNext() ) {
|
||||
String name = cursor.getString( nameIndex );
|
||||
long id = cursor.getLong( idIndex );
|
||||
Assert.assertNotNull( name );
|
||||
boolean expanded = 0 != cursor.getInt( expandedIndex );
|
||||
result.put( id, new GameGroupInfo( name, expanded ) );
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
Iterator<Long> iter = result.keySet().iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
Long id = iter.next();
|
||||
GameGroupInfo ggi = result.get( id );
|
||||
readTurnInfo( db, id, ggi );
|
||||
}
|
||||
|
||||
db.close();
|
||||
}
|
||||
s_groupsCache = result;
|
||||
}
|
||||
return s_groupsCache;
|
||||
} // getGroups
|
||||
|
||||
private static void readTurnInfo( SQLiteDatabase db, long id,
|
||||
GameGroupInfo ggi )
|
||||
{
|
||||
String[] columns = { DBHelper.LASTMOVE, DBHelper.GIFLAGS,
|
||||
DBHelper.TURN };
|
||||
String orderBy = DBHelper.LASTMOVE;
|
||||
String selection = String.format( "%s=%d", DBHelper.GROUPID, id );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection,
|
||||
null, // args
|
||||
null, // groupBy,
|
||||
null, // having
|
||||
orderBy
|
||||
);
|
||||
|
||||
// We want the earliest LASTPLAY_TIME (i.e. the first we see
|
||||
// since they're in order) that's a local turn, if any,
|
||||
// otherwise a non-local turn.
|
||||
long lastPlayTimeLocal = 0;
|
||||
long lastPlayTimeRemote = 0;
|
||||
int indexLPT = cursor.getColumnIndex( DBHelper.LASTMOVE );
|
||||
int indexFlags = cursor.getColumnIndex( DBHelper.GIFLAGS );
|
||||
int turnFlags = cursor.getColumnIndex( DBHelper.TURN );
|
||||
while ( cursor.moveToNext() && 0 == lastPlayTimeLocal ) {
|
||||
int flags = cursor.getInt( indexFlags );
|
||||
int turn = cursor.getInt( turnFlags );
|
||||
Boolean isLocal = GameSummary.localTurnNext( flags, turn );
|
||||
if ( null != isLocal ) {
|
||||
long lpt = cursor.getLong( indexLPT );
|
||||
if ( isLocal ) {
|
||||
lastPlayTimeLocal = lpt;
|
||||
} else if ( 0 == lastPlayTimeRemote ) {
|
||||
lastPlayTimeRemote = lpt;
|
||||
}
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
ggi.m_hasTurn = 0 != lastPlayTimeLocal || 0 != lastPlayTimeRemote;
|
||||
if ( ggi.m_hasTurn ) {
|
||||
ggi.m_turnLocal = 0 != lastPlayTimeLocal;
|
||||
if ( ggi.m_turnLocal ) {
|
||||
ggi.m_lastMoveTime = lastPlayTimeLocal;
|
||||
} else {
|
||||
ggi.m_lastMoveTime = lastPlayTimeRemote;
|
||||
}
|
||||
// DateFormat df = DateFormat.getDateTimeInstance( DateFormat.SHORT,
|
||||
// DateFormat.SHORT );
|
||||
// DbgUtils.logf( "using last play time %s for",
|
||||
// df.format( new Date( 1000 * ggi.m_lastMoveTime ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static long[] getGroupGames( Context context, long groupID )
|
||||
{
|
||||
long[] result = null;
|
||||
initDB( context );
|
||||
String[] columns = { ROW_ID };
|
||||
String selection = String.format( "%s=%d", DBHelper.GROUPID, groupID );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String orderBy = DBHelper.CREATE_TIME + " DESC";
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, // selection
|
||||
null, // args
|
||||
null, // groupBy
|
||||
null, // having
|
||||
orderBy
|
||||
);
|
||||
int index = cursor.getColumnIndex( ROW_ID );
|
||||
result = new long[ cursor.getCount() ];
|
||||
for ( int ii = 0; cursor.moveToNext(); ++ii ) {
|
||||
long rowid = cursor.getInt( index );
|
||||
result[ii] = rowid;
|
||||
}
|
||||
cursor.close();
|
||||
db.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static long getGroupForGame( Context context, long rowid )
|
||||
{
|
||||
long result = ROWID_NOTFOUND;
|
||||
initDB( context );
|
||||
String[] columns = { DBHelper.GROUPID };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, // selection
|
||||
null, // args
|
||||
null, // groupBy
|
||||
null, // having
|
||||
null //orderby
|
||||
);
|
||||
if ( cursor.moveToNext() ) {
|
||||
int index = cursor.getColumnIndex( DBHelper.GROUPID );
|
||||
result = cursor.getLong( index );
|
||||
}
|
||||
cursor.close();
|
||||
db.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static long addGroup( Context context, String name )
|
||||
{
|
||||
long rowid = ROWID_NOTFOUND;
|
||||
if ( null != name && 0 < name.length() ) {
|
||||
HashMap<Long,GameGroupInfo> gameInfo = getGroups( context );
|
||||
if ( null == gameInfo.get( name ) ) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.GROUPNAME, name );
|
||||
values.put( DBHelper.EXPANDED, 0 );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
rowid = db.insert( DBHelper.TABLE_NAME_GROUPS, null,
|
||||
values );
|
||||
db.close();
|
||||
}
|
||||
invalGroupsCache();
|
||||
}
|
||||
}
|
||||
return rowid;
|
||||
}
|
||||
|
||||
public static void deleteGroup( Context context, long groupid )
|
||||
{
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
|
||||
// Nuke games having this group id
|
||||
String selection =
|
||||
String.format( "%s=%d", DBHelper.GROUPID, groupid );
|
||||
db.delete( DBHelper.TABLE_NAME_SUM, selection, null );
|
||||
|
||||
// And nuke the group record itself
|
||||
selection = String.format( ROW_ID_FMT, groupid );
|
||||
db.delete( DBHelper.TABLE_NAME_GROUPS, selection, null );
|
||||
|
||||
db.close();
|
||||
}
|
||||
invalGroupsCache();
|
||||
}
|
||||
|
||||
public static void setGroupName( Context context, long groupid,
|
||||
String name )
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.GROUPNAME, name );
|
||||
updateRow( context, DBHelper.TABLE_NAME_GROUPS, groupid, values );
|
||||
invalGroupsCache();
|
||||
}
|
||||
|
||||
public static void setGroupExpanded( Context context, long groupid,
|
||||
boolean expanded )
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.EXPANDED, expanded? 1 : 0 );
|
||||
updateRow( context, DBHelper.TABLE_NAME_GROUPS, groupid, values );
|
||||
invalGroupsCache();
|
||||
}
|
||||
|
||||
// Change group id of a game
|
||||
public static void moveGame( Context context, long gameid, long groupid )
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.GROUPID, groupid );
|
||||
updateRow( context, DBHelper.TABLE_NAME_SUM, gameid, values );
|
||||
}
|
||||
|
||||
private static String getChatHistoryStr( Context context, long rowid )
|
||||
{
|
||||
String result = null;
|
||||
|
|
|
@ -23,7 +23,6 @@ package org.eehouse.android.xw4;
|
|||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.ExpandableListActivity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.DialogInterface;
|
||||
|
@ -33,7 +32,6 @@ import android.content.res.Resources;
|
|||
import android.database.DataSetObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.ContextMenu;
|
||||
|
@ -47,9 +45,7 @@ import android.widget.ExpandableListAdapter;
|
|||
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import junit.framework.Assert;
|
||||
|
||||
|
@ -58,7 +54,7 @@ import org.eehouse.android.xw4.jni.XwJNI;
|
|||
import org.eehouse.android.xw4.jni.JNIUtilsImpl;
|
||||
import org.eehouse.android.xw4.DictUtils.DictLoc;
|
||||
|
||||
public class DictsActivity extends ExpandableListActivity
|
||||
public class DictsActivity extends XWExpandableListActivity
|
||||
implements View.OnClickListener, XWListItem.DeleteCallback,
|
||||
MountEventReceiver.SDCardNotifiee, DlgDelegate.DlgClickNotify,
|
||||
DictImportActivity.DownloadFinishedListener {
|
||||
|
@ -86,10 +82,8 @@ public class DictsActivity extends ExpandableListActivity
|
|||
private String m_deleteDict = null;
|
||||
private String m_download;
|
||||
private ExpandableListView m_expView;
|
||||
private DlgDelegate m_delegate;
|
||||
private String[] m_locNames;
|
||||
private DictListAdapter m_adapter;
|
||||
private Handler m_handler;
|
||||
|
||||
private long m_packedPosition;
|
||||
private DictLoc m_moveFromLoc;
|
||||
|
@ -338,7 +332,6 @@ public class DictsActivity extends ExpandableListActivity
|
|||
int lang = intent.getIntExtra( MultiService.LANG, -1 );
|
||||
String name = intent.getStringExtra( MultiService.DICT );
|
||||
m_launchedForMissing = true;
|
||||
m_handler = new Handler();
|
||||
DictImportActivity
|
||||
.downloadDictInBack( DictsActivity.this, lang,
|
||||
name, DictsActivity.this );
|
||||
|
@ -355,7 +348,7 @@ public class DictsActivity extends ExpandableListActivity
|
|||
break;
|
||||
|
||||
default:
|
||||
dialog = m_delegate.onCreateDialog( id );
|
||||
dialog = super.onCreateDialog( id );
|
||||
doRemove = false;
|
||||
break;
|
||||
}
|
||||
|
@ -371,7 +364,6 @@ public class DictsActivity extends ExpandableListActivity
|
|||
protected void onPrepareDialog( int id, Dialog dialog )
|
||||
{
|
||||
super.onPrepareDialog( id, dialog );
|
||||
m_delegate.onPrepareDialog( id, dialog );
|
||||
|
||||
if ( MOVE_DICT == id ) {
|
||||
// The move button should always start out disabled
|
||||
|
@ -399,7 +391,6 @@ public class DictsActivity extends ExpandableListActivity
|
|||
Resources res = getResources();
|
||||
m_locNames = res.getStringArray( R.array.loc_names );
|
||||
|
||||
m_delegate = new DlgDelegate( this, this, savedInstanceState );
|
||||
m_factory = LayoutInflater.from( this );
|
||||
|
||||
m_download = getString( R.string.download_dicts );
|
||||
|
@ -447,7 +438,6 @@ public class DictsActivity extends ExpandableListActivity
|
|||
protected void onSaveInstanceState( Bundle outState )
|
||||
{
|
||||
super.onSaveInstanceState( outState );
|
||||
m_delegate.onSaveInstanceState( outState );
|
||||
|
||||
outState.putLong( PACKED_POSITION, m_packedPosition );
|
||||
outState.putString( NAME, m_name );
|
||||
|
@ -622,8 +612,7 @@ public class DictsActivity extends ExpandableListActivity
|
|||
}
|
||||
}
|
||||
|
||||
m_delegate.showConfirmThen( msg, R.string.button_delete,
|
||||
DELETE_DICT_ACTION );
|
||||
showConfirmThen( msg, R.string.button_delete, DELETE_DICT_ACTION );
|
||||
}
|
||||
|
||||
// MountEventReceiver.SDCardNotifiee interface
|
||||
|
@ -632,7 +621,7 @@ public class DictsActivity extends ExpandableListActivity
|
|||
DbgUtils.logf( "DictsActivity.cardMounted(%b)", nowMounted );
|
||||
// post so other SDCardNotifiee implementations get a chance
|
||||
// to process first: avoid race conditions
|
||||
new Handler().post( new Runnable() {
|
||||
post( new Runnable() {
|
||||
public void run() {
|
||||
mkListAdapter();
|
||||
expandGroups();
|
||||
|
@ -773,7 +762,7 @@ public class DictsActivity extends ExpandableListActivity
|
|||
public void downloadFinished( String name, final boolean success )
|
||||
{
|
||||
if ( m_launchedForMissing ) {
|
||||
m_handler.post( new Runnable() {
|
||||
post( new Runnable() {
|
||||
public void run() {
|
||||
if ( success ) {
|
||||
Intent intent = getIntent();
|
||||
|
|
|
@ -79,6 +79,7 @@ public class ExpiringDelegate {
|
|||
if ( haveTurnLocal ) {
|
||||
setBackground();
|
||||
} else {
|
||||
m_view.setBackgroundDrawable( null );
|
||||
m_view.setWillNotDraw( false );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,17 @@ class ExpiringTextView extends TextView {
|
|||
if ( null == m_delegate ) {
|
||||
m_delegate = new ExpiringDelegate( m_context, this, handler );
|
||||
}
|
||||
setPct( haveTurn, haveTurnLocal, startSecs );
|
||||
}
|
||||
|
||||
public void setPct( boolean haveTurn, boolean haveTurnLocal,
|
||||
long startSecs )
|
||||
{
|
||||
if ( null != m_delegate ) {
|
||||
m_delegate.configure( haveTurn, haveTurnLocal, startSecs );
|
||||
} else {
|
||||
DbgUtils.logf( "m_delegate null; skipping" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,93 +20,321 @@
|
|||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.DataSetObserver;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ExpandableListAdapter;
|
||||
import android.widget.ExpandableListView;
|
||||
import java.util.HashMap; // class is not synchronized
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
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.DBUtils.GameGroupInfo;
|
||||
|
||||
public class GameListAdapter extends XWListAdapter {
|
||||
public class GameListAdapter implements ExpandableListAdapter {
|
||||
private Context m_context;
|
||||
private ListView m_list;
|
||||
private LayoutInflater m_factory;
|
||||
private ExpandableListView m_list;
|
||||
private int m_fieldID;
|
||||
private Handler m_handler;
|
||||
private LoadItemCB m_cb;
|
||||
private long[] m_positions;
|
||||
|
||||
public interface LoadItemCB {
|
||||
public void itemClicked( long rowid, GameSummary summary );
|
||||
}
|
||||
|
||||
public GameListAdapter( Context context, ListView list,
|
||||
Handler handler, LoadItemCB cb, String fieldName ) {
|
||||
super( DBUtils.gamesList(context).length );
|
||||
public GameListAdapter( Context context, ExpandableListView list,
|
||||
Handler handler, LoadItemCB cb, long[] positions,
|
||||
String fieldName )
|
||||
{
|
||||
m_context = context;
|
||||
m_list = list;
|
||||
m_handler = handler;
|
||||
m_cb = cb;
|
||||
m_factory = LayoutInflater.from( context );
|
||||
m_positions = checkPositions( positions );
|
||||
|
||||
m_fieldID = fieldToID( fieldName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return DBUtils.gamesList(m_context).length;
|
||||
public long[] getPositions()
|
||||
{
|
||||
Set<Long> keys = gameInfo().keySet(); // do not modify!!!!
|
||||
if ( null == m_positions || m_positions.length != keys.size() ) {
|
||||
HashSet<Long> unused = new HashSet<Long>( keys );
|
||||
long[] newArray = new long[unused.size()];
|
||||
|
||||
// First copy the existing values, in order
|
||||
int nextIndx = 0;
|
||||
if ( null != m_positions ) {
|
||||
for ( long id: m_positions ) {
|
||||
if ( unused.contains( id ) ) {
|
||||
newArray[nextIndx++] = id;
|
||||
unused.remove( id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Views. A view depends on a summary, which takes time to load.
|
||||
// When one needs loading it's done via an async task.
|
||||
public View getView( int position, View convertView, ViewGroup parent )
|
||||
// Then copy in what's left
|
||||
Iterator<Long> iter = unused.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
newArray[nextIndx++] = iter.next();
|
||||
}
|
||||
m_positions = newArray;
|
||||
}
|
||||
return m_positions;
|
||||
}
|
||||
|
||||
public boolean moveGroup( long groupid, int moveBy )
|
||||
{
|
||||
GameListItem result = (GameListItem)
|
||||
m_factory.inflate( R.layout.game_list_item, null );
|
||||
result.init( m_handler, DBUtils.gamesList(m_context)[position],
|
||||
m_fieldID, m_cb );
|
||||
int src = getGroupPosition( groupid );
|
||||
int dest = src + moveBy;
|
||||
long[] positions = getPositions();
|
||||
boolean success = 0 <= dest && dest < positions.length;
|
||||
if ( success ) {
|
||||
long tmp = positions[src];
|
||||
positions[src] = positions[dest];
|
||||
positions[dest] = tmp;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public void expandGroups( ExpandableListView view )
|
||||
{
|
||||
HashMap<Long,GameGroupInfo> info = gameInfo();
|
||||
for ( int ii = 0; ii < info.size(); ++ii ) {
|
||||
GameGroupInfo ggi = getInfoForGroup( ii );
|
||||
if ( ggi.m_expanded ) {
|
||||
view.expandGroup( ii );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getRowIDFor( int group, int child )
|
||||
{
|
||||
long rowid = DBUtils.ROWID_NOTFOUND;
|
||||
long[] rows = getRows( getPositions()[group] );
|
||||
if ( child < rows.length ) {
|
||||
rowid = rows[child];
|
||||
}
|
||||
return rowid;
|
||||
}
|
||||
|
||||
public long getRowIDFor( long packedPosition )
|
||||
{
|
||||
int childPosition = ExpandableListView.
|
||||
getPackedPositionChild( packedPosition );
|
||||
int groupPosition = ExpandableListView.
|
||||
getPackedPositionGroup( packedPosition );
|
||||
return getRowIDFor( groupPosition, childPosition );
|
||||
}
|
||||
|
||||
public long getGroupIDFor( int groupPos )
|
||||
{
|
||||
long id = getPositions()[groupPos];
|
||||
return id;
|
||||
}
|
||||
|
||||
public String groupName( long groupid )
|
||||
{
|
||||
HashMap<Long,GameGroupInfo> info = gameInfo();
|
||||
GameGroupInfo ggi = info.get( groupid );
|
||||
return ggi.m_name;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ExpandableListAdapter interface
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
public long getCombinedGroupId( long groupId )
|
||||
{
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public long getCombinedChildId( long groupId, long childId )
|
||||
{
|
||||
return groupId << 16 | childId;
|
||||
}
|
||||
|
||||
public boolean isEmpty() { return false; }
|
||||
|
||||
public void onGroupCollapsed( int groupPosition )
|
||||
{
|
||||
long groupid = getGroupIDFor( groupPosition );
|
||||
DBUtils.setGroupExpanded( m_context, groupid, false );
|
||||
}
|
||||
|
||||
public void onGroupExpanded( int groupPosition )
|
||||
{
|
||||
long groupid = getGroupIDFor( groupPosition );
|
||||
DBUtils.setGroupExpanded( m_context, groupid, true );
|
||||
}
|
||||
|
||||
public boolean areAllItemsEnabled() { return true; }
|
||||
|
||||
public boolean isChildSelectable( int groupPosition, int childPosition )
|
||||
{ return true; }
|
||||
|
||||
public View getChildView( int groupPosition, int childPosition,
|
||||
boolean isLastChild, View convertView,
|
||||
ViewGroup parent)
|
||||
{
|
||||
View result = null;
|
||||
if ( null != convertView ) {
|
||||
// DbgUtils.logf( "getChildView gave non-null convertView" );
|
||||
if ( convertView instanceof GameListItem ) {
|
||||
GameListItem child = (GameListItem)convertView;
|
||||
long rowid = getRowIDFor( groupPosition, childPosition );
|
||||
if ( child.getRowID() == rowid ) {
|
||||
DbgUtils.logf( "reusing child for rowid %d", rowid );
|
||||
result = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( null == result ) {
|
||||
result = getChildView( groupPosition, childPosition );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private View getChildView( int groupPosition, int childPosition )
|
||||
{
|
||||
long rowid = getRowIDFor( groupPosition, childPosition );
|
||||
GameListItem result =
|
||||
GameListItem.makeForRow( m_context, rowid, m_handler,
|
||||
groupPosition, m_fieldID, m_cb );
|
||||
return result;
|
||||
}
|
||||
|
||||
public View getGroupView( int groupPosition, boolean isExpanded,
|
||||
View convertView, ViewGroup parent )
|
||||
{
|
||||
// if ( null != convertView ) {
|
||||
// DbgUtils.logf( "getGroupView gave non-null convertView" );
|
||||
// }
|
||||
GameListGroup view = (GameListGroup)
|
||||
Utils.inflate(m_context, R.layout.game_list_group );
|
||||
view.setGroupPosition( groupPosition );
|
||||
|
||||
if ( !isExpanded ) {
|
||||
GameGroupInfo ggi = getInfoForGroup( groupPosition );
|
||||
view.setPct( m_handler, ggi.m_hasTurn, ggi.m_turnLocal,
|
||||
ggi.m_lastMoveTime );
|
||||
}
|
||||
|
||||
int nKids = getChildrenCount( groupPosition );
|
||||
String name = m_context.getString( R.string.group_namef,
|
||||
groupNames()[groupPosition], nKids );
|
||||
view.setText( name );
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public boolean hasStableIds() { return false; }
|
||||
|
||||
public long getChildId( int groupPosition, int childPosition )
|
||||
{
|
||||
return childPosition;
|
||||
}
|
||||
|
||||
public long getGroupId( int groupPosition )
|
||||
{
|
||||
return groupPosition;
|
||||
}
|
||||
|
||||
public Object getChild( int groupPosition, int childPosition )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getGroup( int groupPosition )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getChildrenCount( int groupPosition )
|
||||
{
|
||||
long[] rows = getRows( getPositions()[groupPosition] );
|
||||
return rows.length;
|
||||
}
|
||||
|
||||
public int getGroupCount()
|
||||
{
|
||||
return gameInfo().size();
|
||||
}
|
||||
|
||||
public void registerDataSetObserver( DataSetObserver obs ){}
|
||||
public void unregisterDataSetObserver( DataSetObserver obs ){}
|
||||
|
||||
public void inval( long rowid )
|
||||
{
|
||||
GameListItem child = getItemFor( rowid );
|
||||
GameListItem child = getGameItemFor( rowid );
|
||||
int groupPosition;
|
||||
if ( null != child && child.getRowID() == rowid ) {
|
||||
child.forceReload();
|
||||
|
||||
groupPosition = child.getGroupPosition();
|
||||
} else {
|
||||
DbgUtils.logf( "no child for rowid %d", rowid );
|
||||
// DbgUtils.logf( "no child for rowid %d", rowid );
|
||||
GameListItem.inval( rowid );
|
||||
m_list.invalidate();
|
||||
|
||||
long groupID = DBUtils.getGroupForGame( m_context, rowid );
|
||||
groupPosition = getGroupPosition( groupID );
|
||||
}
|
||||
reloadGroup( groupPosition );
|
||||
}
|
||||
|
||||
public void invalName( long rowid )
|
||||
{
|
||||
GameListItem item = getItemFor( rowid );
|
||||
GameListItem item = getGameItemFor( rowid );
|
||||
if ( null != item ) {
|
||||
item.invalName();
|
||||
}
|
||||
}
|
||||
|
||||
private long[] getRows( long groupID )
|
||||
{
|
||||
return DBUtils.getGroupGames( m_context, groupID );
|
||||
}
|
||||
|
||||
public String[] groupNames()
|
||||
{
|
||||
HashMap<Long,GameGroupInfo> info = gameInfo();
|
||||
long[] positions = getPositions();
|
||||
String[] names = new String[ positions.length ];
|
||||
for ( int ii = 0; ii < names.length; ++ii ) {
|
||||
names[ii] = info.get(positions[ii]).m_name;
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
public int getGroupPosition( long groupid )
|
||||
{
|
||||
int result = -1;
|
||||
long[] positions = getPositions();
|
||||
for ( int pos = 0; pos < positions.length; ++pos ) {
|
||||
if ( positions[pos] == groupid ) {
|
||||
result = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean setField( String fieldName )
|
||||
{
|
||||
boolean changed = false;
|
||||
int newID = fieldToID( fieldName );
|
||||
if ( -1 == newID ) {
|
||||
if ( XWApp.DEBUG ) {
|
||||
DbgUtils.logf( "GameListAdapter.setField(): unable to match"
|
||||
+ " fieldName %s", fieldName );
|
||||
}
|
||||
} else if ( m_fieldID != newID ) {
|
||||
if ( XWApp.DEBUG ) {
|
||||
DbgUtils.logf( "setField: clearing views cache for change"
|
||||
+ " from %d to %d", m_fieldID, newID );
|
||||
}
|
||||
m_fieldID = newID;
|
||||
// return true so caller will do onContentChanged.
|
||||
// There's no other way to signal GameListItem instances
|
||||
|
@ -116,12 +344,41 @@ public class GameListAdapter extends XWListAdapter {
|
|||
return changed;
|
||||
}
|
||||
|
||||
private GameListItem getItemFor( long rowid )
|
||||
private GameGroupInfo getInfoForGroup( int groupPosition )
|
||||
{
|
||||
return gameInfo().get( getPositions()[groupPosition] );
|
||||
}
|
||||
|
||||
private GameListItem getGameItemFor( long rowid )
|
||||
{
|
||||
GameListItem result = null;
|
||||
int position = positionFor( rowid );
|
||||
if ( 0 <= position ) {
|
||||
result = (GameListItem)m_list.getChildAt( position );
|
||||
int count = m_list.getChildCount();
|
||||
for ( int ii = 0; ii < count; ++ii ) {
|
||||
View view = m_list.getChildAt( ii );
|
||||
if ( view instanceof GameListItem ) {
|
||||
GameListItem tryme = (GameListItem)view;
|
||||
if ( tryme.getRowID() == rowid ) {
|
||||
result = tryme;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private GameListGroup getGroupItemFor( int groupPosition )
|
||||
{
|
||||
GameListGroup result = null;
|
||||
int count = m_list.getChildCount();
|
||||
for ( int ii = 0; ii < count; ++ii ) {
|
||||
View view = m_list.getChildAt( ii );
|
||||
if ( view instanceof GameListGroup ) {
|
||||
GameListGroup tryme = (GameListGroup)view;
|
||||
if ( tryme.getGroupPosition() == groupPosition ) {
|
||||
result = tryme;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -144,16 +401,32 @@ public class GameListAdapter extends XWListAdapter {
|
|||
return result;
|
||||
}
|
||||
|
||||
private int positionFor( long rowid )
|
||||
private void reloadGroup( int groupPosition )
|
||||
{
|
||||
int position = -1;
|
||||
long[] rowids = DBUtils.gamesList( m_context );
|
||||
for ( int ii = 0; ii < rowids.length; ++ii ) {
|
||||
if ( rowids[ii] == rowid ) {
|
||||
position = ii;
|
||||
GameListGroup group = getGroupItemFor( groupPosition );
|
||||
if ( null != group ) {
|
||||
GameGroupInfo ggi = getInfoForGroup( groupPosition );
|
||||
group.setPct( ggi.m_hasTurn, ggi.m_turnLocal, ggi.m_lastMoveTime );
|
||||
}
|
||||
}
|
||||
|
||||
private HashMap<Long,GameGroupInfo> gameInfo()
|
||||
{
|
||||
return DBUtils.getGroups( m_context );
|
||||
}
|
||||
|
||||
private long[] checkPositions( long[] positions )
|
||||
{
|
||||
long[] result = positions;
|
||||
if ( null != positions ) {
|
||||
Set<Long> posns = gameInfo().keySet();
|
||||
for ( long id : positions ) {
|
||||
if ( ! posns.contains( id ) ) {
|
||||
result = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant 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.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import org.eehouse.android.xw4.DBUtils.GameGroupInfo;
|
||||
|
||||
public class GameListGroup extends ExpiringTextView {
|
||||
private int m_groupPosition;
|
||||
|
||||
public GameListGroup( Context cx, AttributeSet as )
|
||||
{
|
||||
super( cx, as );
|
||||
}
|
||||
|
||||
public void setGroupPosition( int groupPosition )
|
||||
{
|
||||
m_groupPosition = groupPosition;
|
||||
}
|
||||
|
||||
public int getGroupPosition()
|
||||
{
|
||||
return m_groupPosition;
|
||||
}
|
||||
}
|
|
@ -57,6 +57,7 @@ public class GameListItem extends LinearLayout
|
|||
private GameListAdapter.LoadItemCB m_cb;
|
||||
private int m_fieldID;
|
||||
private int m_loadingCount;
|
||||
private int m_groupPosition;
|
||||
|
||||
public GameListItem( Context cx, AttributeSet as )
|
||||
{
|
||||
|
@ -68,11 +69,12 @@ public class GameListItem extends LinearLayout
|
|||
m_loadingCount = 0;
|
||||
}
|
||||
|
||||
public void init( Handler handler, long rowid, int fieldID,
|
||||
GameListAdapter.LoadItemCB cb )
|
||||
private void init( Handler handler, long rowid, int groupPosition,
|
||||
int fieldID, GameListAdapter.LoadItemCB cb )
|
||||
{
|
||||
m_handler = handler;
|
||||
m_rowid = rowid;
|
||||
m_groupPosition = groupPosition;
|
||||
m_fieldID = fieldID;
|
||||
m_cb = cb;
|
||||
|
||||
|
@ -128,6 +130,11 @@ public class GameListItem extends LinearLayout
|
|||
return m_rowid;
|
||||
}
|
||||
|
||||
public int getGroupPosition()
|
||||
{
|
||||
return m_groupPosition;
|
||||
}
|
||||
|
||||
// View.OnClickListener interface
|
||||
public void onClick( View view ) {
|
||||
m_expanded = !m_expanded;
|
||||
|
@ -297,6 +304,17 @@ public class GameListItem extends LinearLayout
|
|||
}
|
||||
} // class LoadItemTask
|
||||
|
||||
public static GameListItem makeForRow( Context context, long rowid,
|
||||
Handler handler, int groupPosition,
|
||||
int fieldID,
|
||||
GameListAdapter.LoadItemCB cb )
|
||||
{
|
||||
GameListItem result =
|
||||
(GameListItem)Utils.inflate( context, R.layout.game_list_item );
|
||||
result.init( handler, rowid, groupPosition, fieldID, cb );
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void inval( long rowid )
|
||||
{
|
||||
synchronized( s_invalRows ) {
|
||||
|
|
|
@ -190,10 +190,10 @@ public class GameUtils {
|
|||
return rowid;
|
||||
}
|
||||
|
||||
public static void deleteGame( Context context, long rowid,
|
||||
public static boolean deleteGame( Context context, long rowid,
|
||||
boolean informNow )
|
||||
{
|
||||
DbgUtils.logf( "deleteGame(rowid=%d)", rowid );
|
||||
boolean success;
|
||||
// does this need to be synchronized?
|
||||
GameLock lock = new GameLock( rowid, true );
|
||||
if ( lock.tryLock() ) {
|
||||
|
@ -201,8 +201,25 @@ public class GameUtils {
|
|||
Utils.cancelNotification( context, (int)rowid );
|
||||
DBUtils.deleteGame( context, lock );
|
||||
lock.unlock();
|
||||
success = true;
|
||||
} else {
|
||||
DbgUtils.logf( "deleteGame: unable to delete rowid %d", rowid );
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public static void deleteGroup( Context context, long groupid )
|
||||
{
|
||||
int nSuccesses = 0;
|
||||
long[] rowids = DBUtils.getGroupGames( context, groupid );
|
||||
for ( int ii = rowids.length - 1; ii >= 0; --ii ) {
|
||||
if ( deleteGame( context, rowids[ii], ii == 0 ) ) {
|
||||
++nSuccesses;
|
||||
}
|
||||
}
|
||||
if ( rowids.length == nSuccesses ) {
|
||||
DBUtils.deleteGroup( context, groupid );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,13 +516,6 @@ public class GameUtils {
|
|||
return allHere;
|
||||
}
|
||||
|
||||
public static boolean gameDictsHere( Context context, int indx,
|
||||
String[][] name, int[] lang )
|
||||
{
|
||||
long rowid = DBUtils.gamesList( context )[indx];
|
||||
return gameDictsHere( context, rowid, name, lang );
|
||||
}
|
||||
|
||||
public static String newName( Context context )
|
||||
{
|
||||
return "untitled";
|
||||
|
|
|
@ -41,29 +41,36 @@ import android.view.View;
|
|||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
|
||||
// import android.telephony.PhoneStateListener;
|
||||
// import android.telephony.TelephonyManager;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
|
||||
public class GamesList extends XWListActivity
|
||||
public class GamesList extends XWExpandableListActivity
|
||||
implements DBUtils.DBChangeListener,
|
||||
GameListAdapter.LoadItemCB,
|
||||
DictImportActivity.DownloadFinishedListener {
|
||||
|
||||
private static final int WARN_NODICT = DlgDelegate.DIALOG_LAST + 1;
|
||||
private static final int WARN_NODICT_SUBST = WARN_NODICT + 1;
|
||||
private static final int WARN_NODICT_NEW = WARN_NODICT + 2;
|
||||
private static final int SHOW_SUBST = WARN_NODICT + 3;
|
||||
private static final int GET_NAME = WARN_NODICT + 4;
|
||||
private static final int RENAME_GAME = WARN_NODICT + 5;
|
||||
private static final int SHOW_SUBST = WARN_NODICT + 2;
|
||||
private static final int GET_NAME = WARN_NODICT + 3;
|
||||
private static final int RENAME_GAME = WARN_NODICT + 4;
|
||||
private static final int NEW_GROUP = WARN_NODICT + 5;
|
||||
private static final int RENAME_GROUP = WARN_NODICT + 6;
|
||||
private static final int CHANGE_GROUP = WARN_NODICT + 7;
|
||||
private static final int WARN_NODICT_NEW = WARN_NODICT + 8;
|
||||
|
||||
private static final String SAVE_ROWID = "SAVE_ROWID";
|
||||
private static final String SAVE_GROUPID = "SAVE_GROUPID";
|
||||
private static final String SAVE_DICTNAMES = "SAVE_DICTNAMES";
|
||||
|
||||
private static final String RELAYIDS_EXTRA = "relayids";
|
||||
|
@ -73,9 +80,9 @@ public class GamesList extends XWListActivity
|
|||
private static final int NEW_NET_GAME_ACTION = 1;
|
||||
private static final int RESET_GAME_ACTION = 2;
|
||||
private static final int DELETE_GAME_ACTION = 3;
|
||||
private static final int DELETE_ALL_ACTION = 4;
|
||||
private static final int SYNC_MENU_ACTION = 5;
|
||||
private static final int NEW_FROM_ACTION = 6;
|
||||
private static final int SYNC_MENU_ACTION = 4;
|
||||
private static final int NEW_FROM_ACTION = 5;
|
||||
private static final int DELETE_GROUP_ACTION = 6;
|
||||
private static final int[] DEBUGITEMS = { R.id.gamel_menu_loaddb
|
||||
, R.id.gamel_menu_storedb
|
||||
, R.id.gamel_menu_checkupdates
|
||||
|
@ -90,12 +97,16 @@ public class GamesList extends XWListActivity
|
|||
private String[] m_sameLangDicts;
|
||||
private int m_missingDictLang;
|
||||
private long m_rowid;
|
||||
private long m_groupid;
|
||||
private String m_nameField;
|
||||
private NetLaunchInfo m_netLaunchInfo;
|
||||
private GameNamer m_namer;
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog( int id )
|
||||
{
|
||||
DialogInterface.OnClickListener lstnr;
|
||||
DialogInterface.OnClickListener lstnr2;
|
||||
LinearLayout layout;
|
||||
|
||||
Dialog dialog = super.onCreateDialog( id );
|
||||
|
@ -178,36 +189,87 @@ public class GamesList extends XWListActivity
|
|||
.setNegativeButton( R.string.button_cancel, null )
|
||||
.setSingleChoiceItems( m_sameLangDicts, 0, null )
|
||||
.create();
|
||||
;
|
||||
// Force destruction so onCreateDialog() will get
|
||||
// called next time and we can insert a different
|
||||
// list. There seems to be no way to change the list
|
||||
// inside onPrepareDialog().
|
||||
dialog.setOnDismissListener(new DialogInterface.
|
||||
OnDismissListener() {
|
||||
public void onDismiss(DialogInterface dlg) {
|
||||
removeDialog( SHOW_SUBST );
|
||||
}
|
||||
});
|
||||
Utils.setRemoveOnDismiss( this, dialog, id );
|
||||
break;
|
||||
|
||||
case RENAME_GAME:
|
||||
final GameNamer namerView =
|
||||
(GameNamer)Utils.inflate( this, R.layout.rename_game );
|
||||
namerView.setName( GameUtils.getName( this, m_rowid ) );
|
||||
namerView.setLabel( R.string.rename_label );
|
||||
lstnr = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String name = namerView.getName();
|
||||
String name = m_namer.getName();
|
||||
DBUtils.setName( GamesList.this, m_rowid, name );
|
||||
m_adapter.invalName( m_rowid );
|
||||
}
|
||||
};
|
||||
dialog = buildNamerDlg( GameUtils.getName( this, m_rowid ),
|
||||
R.string.rename_label,
|
||||
R.string.game_rename_title,
|
||||
lstnr, RENAME_GAME );
|
||||
break;
|
||||
|
||||
case RENAME_GROUP:
|
||||
lstnr = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String name = m_namer.getName();
|
||||
DBUtils.setGroupName( GamesList.this, m_groupid,
|
||||
name );
|
||||
m_adapter.inval( m_rowid );
|
||||
onContentChanged();
|
||||
}
|
||||
};
|
||||
dialog = buildNamerDlg( m_adapter.groupName( m_groupid ),
|
||||
R.string.rename_group_label,
|
||||
R.string.game_name_group_title,
|
||||
lstnr, RENAME_GROUP );
|
||||
break;
|
||||
|
||||
case NEW_GROUP:
|
||||
lstnr = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String name = m_namer.getName();
|
||||
DBUtils.addGroup( GamesList.this, name );
|
||||
// m_adapter.inval();
|
||||
onContentChanged();
|
||||
}
|
||||
};
|
||||
dialog = buildNamerDlg( "", R.string.newgroup_label,
|
||||
R.string.game_name_group_title,
|
||||
lstnr, RENAME_GROUP );
|
||||
Utils.setRemoveOnDismiss( this, dialog, id );
|
||||
break;
|
||||
|
||||
case CHANGE_GROUP:
|
||||
final long startGroup = DBUtils.getGroupForGame( this, m_rowid );
|
||||
final int[] selItem = {-1}; // hack!!!!
|
||||
lstnr = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlgi, int item ) {
|
||||
selItem[0] = item;
|
||||
AlertDialog dlg = (AlertDialog)dlgi;
|
||||
Button btn =
|
||||
dlg.getButton( AlertDialog.BUTTON_POSITIVE );
|
||||
long newGroup = m_adapter.getGroupIDFor( item );
|
||||
btn.setEnabled( newGroup != startGroup );
|
||||
}
|
||||
};
|
||||
lstnr2 = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
Assert.assertTrue( -1 != selItem[0] );
|
||||
long gid = m_adapter.getGroupIDFor( selItem[0] );
|
||||
DBUtils.moveGame( GamesList.this, m_rowid, gid );
|
||||
onContentChanged();
|
||||
}
|
||||
};
|
||||
String[] groups = m_adapter.groupNames();
|
||||
int curGroupPos = m_adapter.getGroupPosition( startGroup );
|
||||
String name = GameUtils.getName( this, m_rowid );
|
||||
dialog = new AlertDialog.Builder( this )
|
||||
.setTitle( R.string.game_rename_title )
|
||||
.setTitle( getString( R.string.change_groupf, name ) )
|
||||
.setSingleChoiceItems( groups, curGroupPos, lstnr )
|
||||
.setPositiveButton( R.string.button_move, lstnr2 )
|
||||
.setNegativeButton( R.string.button_cancel, null )
|
||||
.setPositiveButton( R.string.button_ok, lstnr )
|
||||
.setView( namerView )
|
||||
.create();
|
||||
Utils.setRemoveOnDismiss( this, dialog, id );
|
||||
break;
|
||||
|
@ -248,6 +310,16 @@ public class GamesList extends XWListActivity
|
|||
return dialog;
|
||||
} // onCreateDialog
|
||||
|
||||
@Override protected void onPrepareDialog( int id, Dialog dialog )
|
||||
{
|
||||
super.onPrepareDialog( id, dialog );
|
||||
|
||||
if ( CHANGE_GROUP == id ) {
|
||||
((AlertDialog)dialog).getButton( AlertDialog.BUTTON_POSITIVE )
|
||||
.setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
|
@ -258,7 +330,7 @@ public class GamesList extends XWListActivity
|
|||
getBundledData( savedInstanceState );
|
||||
|
||||
setContentView(R.layout.game_list);
|
||||
registerForContextMenu( getListView() );
|
||||
registerForContextMenu( getExpandableListView() );
|
||||
DBUtils.setDBChangeListener( this );
|
||||
|
||||
boolean isUpgrade = Utils.firstBootThisVersion( this );
|
||||
|
@ -280,11 +352,21 @@ public class GamesList extends XWListActivity
|
|||
// R.string.key_notagain_newgame );
|
||||
}
|
||||
});
|
||||
newGameB = (Button)findViewById(R.id.new_group);
|
||||
newGameB.setOnClickListener( new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick( View v ) {
|
||||
showDialog( NEW_GROUP );
|
||||
}
|
||||
});
|
||||
|
||||
String field = CommonPrefs.getSummaryField( this );
|
||||
m_adapter = new GameListAdapter( this, getListView(), new Handler(),
|
||||
this, field );
|
||||
long[] positions = XWPrefs.getGroupPositions( this );
|
||||
m_adapter = new GameListAdapter( this, getExpandableListView(),
|
||||
new Handler(), this, positions,
|
||||
field );
|
||||
setListAdapter( m_adapter );
|
||||
m_adapter.expandGroups( getExpandableListView() );
|
||||
|
||||
NetUtils.informOfDeaths( this );
|
||||
|
||||
|
@ -318,13 +400,13 @@ public class GamesList extends XWListActivity
|
|||
boolean hide = CommonPrefs.getHideIntro( this );
|
||||
int hereOrGone = hide ? View.GONE : View.VISIBLE;
|
||||
for ( int id : new int[]{ R.id.empty_games_list,
|
||||
R.id.new_game } ) {
|
||||
R.id.new_buttons } ) {
|
||||
View view = findViewById( id );
|
||||
view.setVisibility( hereOrGone );
|
||||
}
|
||||
View empty = findViewById( R.id.empty_list_msg );
|
||||
empty.setVisibility( hide ? View.VISIBLE : View.GONE );
|
||||
getListView().setEmptyView( hide? empty : null );
|
||||
getExpandableListView().setEmptyView( hide? empty : null );
|
||||
|
||||
// TelephonyManager mgr =
|
||||
// (TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
|
||||
|
@ -340,7 +422,8 @@ public class GamesList extends XWListActivity
|
|||
// (TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
|
||||
// mgr.listen( m_phoneStateListener, PhoneStateListener.LISTEN_NONE );
|
||||
// m_phoneStateListener = null;
|
||||
|
||||
long[] positions = m_adapter.getPositions();
|
||||
XWPrefs.setGroupPositions( this, positions );
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
|
@ -356,6 +439,7 @@ public class GamesList extends XWListActivity
|
|||
{
|
||||
super.onSaveInstanceState( outState );
|
||||
outState.putLong( SAVE_ROWID, m_rowid );
|
||||
outState.putLong( SAVE_GROUPID, m_groupid );
|
||||
outState.putString( SAVE_DICTNAMES, m_missingDictName );
|
||||
if ( null != m_netLaunchInfo ) {
|
||||
m_netLaunchInfo.putSelf( outState );
|
||||
|
@ -366,6 +450,7 @@ public class GamesList extends XWListActivity
|
|||
{
|
||||
if ( null != bundle ) {
|
||||
m_rowid = bundle.getLong( SAVE_ROWID );
|
||||
m_groupid = bundle.getLong( SAVE_GROUPID );
|
||||
m_netLaunchInfo = new NetLaunchInfo( bundle );
|
||||
m_missingDictName = bundle.getString( SAVE_DICTNAMES );
|
||||
}
|
||||
|
@ -457,12 +542,6 @@ public class GamesList extends XWListActivity
|
|||
case DELETE_GAME_ACTION:
|
||||
GameUtils.deleteGame( this, m_rowid, true );
|
||||
break;
|
||||
case DELETE_ALL_ACTION:
|
||||
long[] games = DBUtils.gamesList( this );
|
||||
for ( int ii = games.length - 1; ii >= 0; --ii ) {
|
||||
GameUtils.deleteGame( this, games[ii], ii == 0 );
|
||||
}
|
||||
break;
|
||||
case SYNC_MENU_ACTION:
|
||||
doSyncMenuitem();
|
||||
break;
|
||||
|
@ -472,40 +551,88 @@ public class GamesList extends XWListActivity
|
|||
m_adapter.inval( newid );
|
||||
}
|
||||
break;
|
||||
|
||||
case DELETE_GROUP_ACTION:
|
||||
GameUtils.deleteGroup( this, m_groupid );
|
||||
onContentChanged();
|
||||
break;
|
||||
default:
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContentChanged()
|
||||
{
|
||||
super.onContentChanged();
|
||||
if ( null != m_adapter ) {
|
||||
m_adapter.expandGroups( getExpandableListView() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu( ContextMenu menu, View view,
|
||||
ContextMenuInfo menuInfo )
|
||||
{
|
||||
ExpandableListView.ExpandableListContextMenuInfo info
|
||||
= (ExpandableListView.ExpandableListContextMenuInfo)menuInfo;
|
||||
long packedPos = info.packedPosition;
|
||||
int childPos = ExpandableListView.getPackedPositionChild( packedPos );
|
||||
|
||||
String name;
|
||||
if ( 0 <= childPos ) { // game case
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate( R.menu.games_list_item_menu, menu );
|
||||
|
||||
AdapterView.AdapterContextMenuInfo info =
|
||||
(AdapterView.AdapterContextMenuInfo)menuInfo;
|
||||
int position = info.position;
|
||||
long rowid = DBUtils.gamesList( this )[position];
|
||||
String title = GameUtils.getName( this, rowid );
|
||||
long rowid = m_adapter.getRowIDFor( packedPos );
|
||||
name = GameUtils.getName( this, rowid );
|
||||
} else { // group case
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate( R.menu.games_list_group_menu, menu );
|
||||
|
||||
int pos = ExpandableListView.getPackedPositionGroup( packedPos );
|
||||
name = m_adapter.groupNames()[pos];
|
||||
|
||||
if ( 0 == pos ) {
|
||||
Utils.setItemEnabled( menu, R.id.list_group_moveup, false );
|
||||
}
|
||||
if ( pos + 1 == m_adapter.getGroupCount() ) {
|
||||
Utils.setItemEnabled( menu, R.id.list_group_movedown, false );
|
||||
}
|
||||
if ( XWPrefs.getDefaultNewGameGroup( this )
|
||||
== m_adapter.getGroupIDFor( pos ) ) {
|
||||
Utils.setItemEnabled( menu, R.id.list_group_default, false );
|
||||
Utils.setItemEnabled( menu, R.id.list_group_delete, false );
|
||||
}
|
||||
}
|
||||
menu.setHeaderTitle( getString( R.string.game_item_menu_titlef,
|
||||
title ) );
|
||||
name ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected( MenuItem item )
|
||||
{
|
||||
AdapterView.AdapterContextMenuInfo info;
|
||||
ExpandableListContextMenuInfo info;
|
||||
try {
|
||||
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
||||
info = (ExpandableListContextMenuInfo)item.getMenuInfo();
|
||||
} catch (ClassCastException cce) {
|
||||
DbgUtils.loge( cce );
|
||||
return false;
|
||||
}
|
||||
|
||||
return handleMenuItem( item.getItemId(), info.position );
|
||||
long packedPos = info.packedPosition;
|
||||
int childPos = ExpandableListView.getPackedPositionChild( packedPos );
|
||||
int groupPos = ExpandableListView.getPackedPositionGroup(packedPos);
|
||||
int menuID = item.getItemId();
|
||||
boolean handled;
|
||||
if ( 0 <= childPos ) {
|
||||
long rowid = m_adapter.getRowIDFor( groupPos, childPos );
|
||||
handled = handleGameMenuItem( menuID, rowid );
|
||||
} else {
|
||||
handled = handleGroupMenuItem( menuID, groupPos );
|
||||
}
|
||||
return handled;
|
||||
} // onContextItemSelected
|
||||
|
||||
@Override
|
||||
|
@ -520,7 +647,7 @@ public class GamesList extends XWListActivity
|
|||
@Override
|
||||
public boolean onPrepareOptionsMenu( Menu menu )
|
||||
{
|
||||
boolean visible = XWPrefs.getDebugEnabled( this ) ;
|
||||
boolean visible = XWPrefs.getDebugEnabled( this );
|
||||
for ( int id : DEBUGITEMS ) {
|
||||
MenuItem item = menu.findItem( id );
|
||||
item.setVisible( visible );
|
||||
|
@ -544,12 +671,8 @@ public class GamesList extends XWListActivity
|
|||
startNewGameActivity();
|
||||
break;
|
||||
|
||||
case R.id.gamel_menu_delete_all:
|
||||
if ( DBUtils.gamesList( this ).length > 0 ) {
|
||||
showConfirmThen( R.string.confirm_delete_all,
|
||||
R.string.button_delete, DELETE_ALL_ACTION );
|
||||
}
|
||||
handled = true;
|
||||
case R.id.gamel_menu_newgroup:
|
||||
showDialog( NEW_GROUP );
|
||||
break;
|
||||
|
||||
case R.id.gamel_menu_dicts:
|
||||
|
@ -615,12 +738,12 @@ public class GamesList extends XWListActivity
|
|||
} );
|
||||
}
|
||||
|
||||
private boolean handleMenuItem( int menuID, int position )
|
||||
private boolean handleGameMenuItem( int menuID, long rowid )
|
||||
{
|
||||
boolean handled = true;
|
||||
DialogInterface.OnClickListener lstnr;
|
||||
|
||||
m_rowid = DBUtils.gamesList( this )[position];
|
||||
m_rowid = rowid;
|
||||
|
||||
if ( R.id.list_item_delete == menuID ) {
|
||||
showConfirmThen( R.string.confirm_delete, R.string.button_delete,
|
||||
|
@ -638,7 +761,13 @@ public class GamesList extends XWListActivity
|
|||
case R.id.list_item_rename:
|
||||
showDialog( RENAME_GAME );
|
||||
break;
|
||||
|
||||
case R.id.list_item_move:
|
||||
if ( 1 >= m_adapter.getGroupCount() ) {
|
||||
showOKOnlyDialog( R.string.no_move_onegroup );
|
||||
} else {
|
||||
showDialog( CHANGE_GROUP );
|
||||
}
|
||||
break;
|
||||
case R.id.list_item_new_from:
|
||||
showNotAgainDlgThen( R.string.not_again_newfrom,
|
||||
R.string.key_notagain_newfrom,
|
||||
|
@ -674,7 +803,48 @@ public class GamesList extends XWListActivity
|
|||
}
|
||||
|
||||
return handled;
|
||||
} // handleMenuItem
|
||||
} // handleGameMenuItem
|
||||
|
||||
private boolean handleGroupMenuItem( int menuID, int groupPos )
|
||||
{
|
||||
boolean handled = true;
|
||||
m_groupid = m_adapter.getGroupIDFor( groupPos );
|
||||
switch ( menuID ) {
|
||||
case R.id.list_group_delete:
|
||||
if ( m_groupid == XWPrefs.getDefaultNewGameGroup( this ) ) {
|
||||
showOKOnlyDialog( R.string.cannot_delete_default_group );
|
||||
} else {
|
||||
String msg = getString( R.string.group_confirm_del );
|
||||
int nGames = m_adapter.getChildrenCount( groupPos );
|
||||
if ( 0 < nGames ) {
|
||||
msg += getString( R.string.group_confirm_delf, nGames );
|
||||
}
|
||||
showConfirmThen( msg, DELETE_GROUP_ACTION );
|
||||
}
|
||||
break;
|
||||
case R.id.list_group_rename:
|
||||
showDialog( RENAME_GROUP );
|
||||
break;
|
||||
case R.id.list_group_default:
|
||||
XWPrefs.setDefaultNewGameGroup( this, m_groupid );
|
||||
break;
|
||||
|
||||
case R.id.list_group_moveup:
|
||||
if ( m_adapter.moveGroup( m_groupid, -1 ) ) {
|
||||
onContentChanged();
|
||||
}
|
||||
break;
|
||||
case R.id.list_group_movedown:
|
||||
if ( m_adapter.moveGroup( m_groupid, 1 ) ) {
|
||||
onContentChanged();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
handled = false;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
private boolean checkWarnNoDict( NetLaunchInfo nli )
|
||||
{
|
||||
|
@ -856,6 +1026,23 @@ public class GamesList extends XWListActivity
|
|||
}
|
||||
}
|
||||
|
||||
private Dialog buildNamerDlg( String curname, int labelID, int titleID,
|
||||
DialogInterface.OnClickListener lstnr,
|
||||
int dlgID )
|
||||
{
|
||||
m_namer = (GameNamer)Utils.inflate( this, R.layout.rename_game );
|
||||
m_namer.setName( curname );
|
||||
m_namer.setLabel( labelID );
|
||||
Dialog dialog = new AlertDialog.Builder( this )
|
||||
.setTitle( titleID )
|
||||
.setNegativeButton( R.string.button_cancel, null )
|
||||
.setPositiveButton( R.string.button_ok, lstnr )
|
||||
.setView( m_namer )
|
||||
.create();
|
||||
Utils.setRemoveOnDismiss( this, dialog, dlgID );
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private boolean makeNewNetGameIf()
|
||||
{
|
||||
boolean madeGame = null != m_netLaunchInfo;
|
||||
|
|
|
@ -23,28 +23,22 @@ package org.eehouse.android.xw4;
|
|||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.ContentResolver;
|
||||
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.CommonDataKinds;
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.method.DialerKeyListener;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ListView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class SMSInviteActivity extends InviteActivity {
|
||||
|
||||
|
@ -275,7 +269,6 @@ public class SMSInviteActivity extends InviteActivity {
|
|||
USE_IMMOBILE_ACTION );
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
} // addPhoneNumbers
|
||||
|
||||
|
|
|
@ -353,6 +353,12 @@ public class Utils {
|
|||
item.setVisible( enabled );
|
||||
}
|
||||
|
||||
public static void setItemEnabled( Menu menu, int id, boolean enabled )
|
||||
{
|
||||
MenuItem item = menu.findItem( id );
|
||||
item.setEnabled( enabled );
|
||||
}
|
||||
|
||||
public static boolean hasSmallScreen( Context context )
|
||||
{
|
||||
if ( null == s_hasSmallScreen ) {
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2010 - 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.Dialog;
|
||||
import android.app.ExpandableListActivity;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
|
||||
public class XWExpandableListActivity extends ExpandableListActivity
|
||||
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 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.onCreateDialog( id );
|
||||
if ( null == dialog ) {
|
||||
dialog = super.onCreateDialog( id );
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareDialog( int id, Dialog dialog )
|
||||
{
|
||||
super.onPrepareDialog( id, dialog );
|
||||
m_delegate.onPrepareDialog( id, dialog );
|
||||
}
|
||||
|
||||
protected boolean post( Runnable runnable )
|
||||
{
|
||||
return m_delegate.post( runnable );
|
||||
}
|
||||
|
||||
protected void doSyncMenuitem()
|
||||
{
|
||||
m_delegate.doSyncMenuitem();
|
||||
}
|
||||
|
||||
protected void showNotAgainDlgThen( int msgID, int prefsKey,
|
||||
int action )
|
||||
{
|
||||
m_delegate.showNotAgainDlgThen( msgID, prefsKey, action );
|
||||
}
|
||||
|
||||
protected void showNotAgainDlg( int msgID, int prefsKey )
|
||||
{
|
||||
m_delegate.showNotAgainDlgThen( msgID, prefsKey );
|
||||
}
|
||||
|
||||
// It sucks that these must be duplicated here and XWActivity
|
||||
protected void showAboutDialog()
|
||||
{
|
||||
m_delegate.showAboutDialog();
|
||||
}
|
||||
|
||||
protected void showOKOnlyDialog( int msgID )
|
||||
{
|
||||
m_delegate.showOKOnlyDialog( msgID );
|
||||
}
|
||||
|
||||
protected void showConfirmThen( String msg, int action )
|
||||
{
|
||||
m_delegate.showConfirmThen( msg, action );
|
||||
}
|
||||
|
||||
protected void showConfirmThen( String msg, int posButton, int action )
|
||||
{
|
||||
m_delegate.showConfirmThen( msg, posButton, action );
|
||||
}
|
||||
|
||||
protected void showConfirmThen( int msg, int posButton, int action )
|
||||
{
|
||||
m_delegate.showConfirmThen( getString(msg), posButton, action );
|
||||
}
|
||||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
{
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
// BTService.BTEventListener interface
|
||||
public void eventOccurred( MultiService.MultiEvent event,
|
||||
final Object ... args )
|
||||
{
|
||||
m_delegate.eventOccurred( event, args );
|
||||
}
|
||||
|
||||
}
|
|
@ -105,12 +105,6 @@ public class XWListActivity extends ListActivity
|
|||
m_delegate.onPrepareDialog( id, dialog );
|
||||
}
|
||||
|
||||
// It sucks that these must be duplicated here and XWActivity
|
||||
protected void showAboutDialog()
|
||||
{
|
||||
m_delegate.showAboutDialog();
|
||||
}
|
||||
|
||||
protected void showNotAgainDlgThen( int msgID, int prefsKey,
|
||||
int action )
|
||||
{
|
||||
|
|
|
@ -26,7 +26,6 @@ import android.preference.PreferenceManager;
|
|||
import android.text.TextUtils;
|
||||
import com.google.android.gcm.GCMRegistrar;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class XWPrefs {
|
||||
|
||||
|
@ -305,6 +304,29 @@ public class XWPrefs {
|
|||
setPrefsLong( context, R.string.key_default_group, val );
|
||||
}
|
||||
|
||||
public static void setGroupPositions( Context context, long[] posns )
|
||||
{
|
||||
String[] asStrs = new String[posns.length];
|
||||
for ( int ii = 0; ii < posns.length; ++ii ) {
|
||||
asStrs[ii] = String.format( "%d", posns[ii] );
|
||||
}
|
||||
setPrefsStringArray( context, R.string.key_group_posns, asStrs );
|
||||
}
|
||||
|
||||
public static long[] getGroupPositions( Context context )
|
||||
{
|
||||
long[] posns = null;
|
||||
String[] longStrs = getPrefsStringArray( context,
|
||||
R.string.key_group_posns );
|
||||
if ( null != longStrs ) {
|
||||
posns = new long[longStrs.length];
|
||||
for ( int ii = 0; ii < longStrs.length; ++ii ) {
|
||||
posns[ii] = Long.parseLong(longStrs[ii]);
|
||||
}
|
||||
}
|
||||
return posns;
|
||||
}
|
||||
|
||||
protected static String getPrefsString( Context context, int keyID )
|
||||
{
|
||||
String key = context.getString( keyID );
|
||||
|
|
|
@ -224,9 +224,9 @@ public class GameSummary {
|
|||
&& serverRole != DeviceRole.SERVER_STANDALONE );
|
||||
}
|
||||
|
||||
private boolean isLocal( int indx ) {
|
||||
int flag = 2 << (indx * 2);
|
||||
return 0 == (m_giFlags & flag);
|
||||
private boolean isLocal( int indx )
|
||||
{
|
||||
return localTurnNextImpl( m_giFlags, indx );
|
||||
}
|
||||
|
||||
private boolean isRobot( int indx ) {
|
||||
|
@ -328,4 +328,19 @@ public class GameSummary {
|
|||
return String.format( "%s%s%s", separator, list, separator );
|
||||
}
|
||||
|
||||
private static boolean localTurnNextImpl( int flags, int turn )
|
||||
{
|
||||
int flag = 2 << (turn * 2);
|
||||
return 0 == (flags & flag);
|
||||
}
|
||||
|
||||
public static Boolean localTurnNext( int flags, int turn )
|
||||
{
|
||||
Boolean result = null;
|
||||
if ( 0 <= turn ) {
|
||||
result = new Boolean( localTurnNextImpl( flags, turn ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ public class JNIThread extends Thread {
|
|||
}
|
||||
byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, m_gi );
|
||||
if ( Arrays.equals( m_gameAtStart, state ) ) {
|
||||
DbgUtils.logf( "no change in game; can skip saving" );
|
||||
// DbgUtils.logf( "no change in game; can skip saving" );
|
||||
} else {
|
||||
GameSummary summary = new GameSummary( m_context, m_gi );
|
||||
XwJNI.game_summarize( m_jniGamePtr, summary );
|
||||
|
|
|
@ -743,12 +743,14 @@ warnBadWords( const XP_UCHAR* word, XP_Bool isLegal,
|
|||
{
|
||||
XP_Bool ok = XP_TRUE;
|
||||
if ( !isLegal ) {
|
||||
BadWordInfo bwi;
|
||||
BadWordInfo bwi = {0};
|
||||
BoardCtxt* board = (BoardCtxt*)closure;
|
||||
XP_S16 turn = server_getCurrentTurn( board->server );
|
||||
|
||||
bwi.nWords = 1;
|
||||
bwi.words[0] = word;
|
||||
bwi.dictName =
|
||||
dict_getShortName( model_getPlayerDict( board->model, turn ) );
|
||||
|
||||
ok = !board->badWordRejected
|
||||
&& util_warnIllegalWord( board->util, &bwi, turn, XP_FALSE );
|
||||
|
|
|
@ -82,7 +82,7 @@ typedef struct PickInfo {
|
|||
|
||||
typedef struct BadWordInfo {
|
||||
XP_U16 nWords;
|
||||
XP_UCHAR* dictName;
|
||||
const XP_UCHAR* dictName;
|
||||
const XP_UCHAR* words[MAX_TRAY_TILES+1]; /* can form in both directions */
|
||||
} BadWordInfo;
|
||||
|
||||
|
|
|
@ -1708,8 +1708,8 @@ gtk_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi, XP_U16 player,
|
|||
result = XP_TRUE;
|
||||
} else {
|
||||
XP_ASSERT( bwi->nWords == 1 );
|
||||
sprintf( buf, "Word \"%s\" not in the current dictionary. "
|
||||
"Use it anyway?", bwi->words[0] );
|
||||
sprintf( buf, "Word \"%s\" not in the current dictionary (%s). "
|
||||
"Use it anyway?", bwi->words[0], bwi->dictName );
|
||||
result = gtkask( globals->window, buf, GTK_BUTTONS_YES_NO );
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue