mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-09 22:00:39 +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"
|
android:layout_height="wrap_content"
|
||||||
>
|
>
|
||||||
<Button android:id="@+id/exchange_commit"
|
<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"
|
android:text="@string/button_trade_commit"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
<Button android:id="@+id/exchange_cancel"
|
<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"
|
android:text="@string/button_trade_cancel"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
>
|
>
|
||||||
<Button android:id="@+id/button_rescan"
|
<Button android:id="@+id/button_rescan"
|
||||||
android:text="@string/bt_pick_rescan_button"
|
android:text="@string/bt_pick_rescan_button"
|
||||||
android:layout_width="fill_parent"
|
style="@style/spaced_buttons"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
/>
|
/>
|
||||||
<!-- <Button android:id="@+id/button_reconfigure" -->
|
<!-- <Button android:id="@+id/button_reconfigure" -->
|
||||||
<!-- android:text="@string/bt_pick_reconfig_button" -->
|
<!-- android:text="@string/bt_pick_reconfig_button" -->
|
||||||
|
@ -38,9 +36,7 @@
|
||||||
<!-- /> -->
|
<!-- /> -->
|
||||||
<Button android:id="@+id/button_clear"
|
<Button android:id="@+id/button_clear"
|
||||||
android:text="@string/bt_pick_clear_button"
|
android:text="@string/bt_pick_clear_button"
|
||||||
android:layout_width="fill_parent"
|
style="@style/spaced_buttons"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:paddingLeft="8dp"
|
>
|
||||||
android:paddingRight="8dp">
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/empty_games_list"
|
<LinearLayout android:id="@+id/empty_games_list"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
|
@ -18,21 +16,25 @@
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
android:background="#FF202020"
|
android:background="#FF202020"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
/>
|
/>
|
||||||
<TextView android:layout_height="wrap_content"
|
<TextView android:layout_height="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:text="@string/empty_games_list2"
|
android:text="@string/empty_games_list2"
|
||||||
android:background="#FF202020"
|
android:background="#FF202020"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ListView android:id="@id/android:list"
|
<ExpandableListView android:id="@id/android:list"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:drawSelectorOnTop="false"
|
android:drawSelectorOnTop="false"
|
||||||
/>
|
/>
|
||||||
<TextView android:id="@+id/empty_list_msg"
|
<TextView android:id="@+id/empty_list_msg"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
|
@ -41,11 +43,21 @@
|
||||||
android:text="@string/empty_list_msg"
|
android:text="@string/empty_list_msg"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button android:id="@+id/new_game"
|
<LinearLayout android:id="@+id/new_buttons"
|
||||||
android:layout_width="fill_parent"
|
android:orientation="horizontal"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="fill_parent"
|
||||||
android:layout_gravity="right"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/button_new_game"
|
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>
|
</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:focusable="true"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:background="@android:drawable/list_selector_background"
|
android:background="@android:drawable/list_selector_background"
|
||||||
|
android:paddingLeft="12dp"
|
||||||
>
|
>
|
||||||
|
|
||||||
<TextView android:id="@+id/view_unloaded"
|
<TextView android:id="@+id/view_unloaded"
|
||||||
|
|
|
@ -51,16 +51,12 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
>
|
>
|
||||||
<Button android:id="@+id/newgame_local"
|
<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"
|
android:text="@string/newgame_local"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
<Button android:id="@+id/newgame_local_config"
|
<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"
|
android:text="@string/newgame_local_config"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -93,17 +89,13 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
>
|
>
|
||||||
<Button android:id="@+id/newgame_invite"
|
<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"
|
android:text="@string/newgame_invite"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button android:id="@+id/newgame_net_config"
|
<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"
|
android:text="@string/newgame_net_config"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -160,17 +152,13 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
>
|
>
|
||||||
<Button android:id="@+id/newgame_invite_sms"
|
<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"
|
android:text="@string/newgame_invite"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button android:id="@+id/newgame_sms_config"
|
<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"
|
android:text="@string/newgame_net_config"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -228,17 +216,13 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
>
|
>
|
||||||
<Button android:id="@+id/newgame_invite_bt"
|
<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"
|
android:text="@string/newgame_invite"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button android:id="@+id/newgame_bt_config"
|
<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"
|
android:text="@string/newgame_net_config"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -20,16 +20,12 @@
|
||||||
android:layout_weight="0"
|
android:layout_weight="0"
|
||||||
>
|
>
|
||||||
<Button android:id="@+id/revert_colors"
|
<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"
|
android:text="@string/button_revert_colors"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
<Button android:id="@+id/revert_all"
|
<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"
|
android:text="@string/button_revert_all"
|
||||||
|
style="@style/spaced_buttons"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -41,9 +41,7 @@
|
||||||
>
|
>
|
||||||
<Button android:id="@+id/button_add"
|
<Button android:id="@+id/button_add"
|
||||||
android:text="@string/button_sms_add"
|
android:text="@string/button_sms_add"
|
||||||
android:layout_height="fill_parent"
|
style="@style/spaced_buttons"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
/>
|
/>
|
||||||
<ImageButton android:id="@+id/manual_add_button"
|
<ImageButton android:id="@+id/manual_add_button"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
|
@ -53,9 +51,7 @@
|
||||||
/>
|
/>
|
||||||
<Button android:id="@+id/button_clear"
|
<Button android:id="@+id/button_clear"
|
||||||
android:text="@string/bt_pick_clear_button"
|
android:text="@string/bt_pick_clear_button"
|
||||||
android:layout_height="fill_parent"
|
style="@style/spaced_buttons"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</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"
|
<item android:id="@+id/list_item_rename"
|
||||||
android:title="@string/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"
|
<item android:id="@+id/list_item_delete"
|
||||||
android:title="@string/list_item_delete"
|
android:title="@string/list_item_delete"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
android:title="@string/button_new_game"
|
android:title="@string/button_new_game"
|
||||||
android:icon="@android:drawable/ic_menu_add"
|
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"
|
<item android:id="@+id/gamel_menu_prefs"
|
||||||
android:title="@string/menu_prefs"
|
android:title="@string/menu_prefs"
|
||||||
android:icon="@android:drawable/ic_menu_preferences"
|
android:icon="@android:drawable/ic_menu_preferences"
|
||||||
|
@ -23,10 +27,6 @@
|
||||||
android:icon="@android:drawable/ic_menu_send"
|
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"
|
<item android:id="@+id/gamel_menu_checkmoves"
|
||||||
android:title="@string/gamel_menu_checkmoves"
|
android:title="@string/gamel_menu_checkmoves"
|
||||||
android:icon="@drawable/stat_notify_sync"
|
android:icon="@drawable/stat_notify_sync"
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<h3>New with this release</h3>
|
<h3>New with this release</h3>
|
||||||
<ul>
|
<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>
|
"Games with Kati", "Finished games", etc.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
<string name="key_relay_regid">key_relay_regid</string>
|
<string name="key_relay_regid">key_relay_regid</string>
|
||||||
<string name="key_checked_sms">key_checked_sms</string>
|
<string name="key_checked_sms">key_checked_sms</string>
|
||||||
<string name="key_default_group">key_default_group</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_sync">key_notagain_sync</string>
|
||||||
<string name="key_notagain_chat">key_notagain_chat</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
|
menuitem in main games-list screen's menu. (The botton can
|
||||||
be hidden in the same way as the above text.) -->
|
be hidden in the same way as the above text.) -->
|
||||||
<string name="button_new_game">Add game</string>
|
<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
|
<!-- When the game list is empty and the above messages and button
|
||||||
are hidden via preferences, this text is shown -->
|
are hidden via preferences, this text is shown -->
|
||||||
|
@ -142,6 +143,9 @@
|
||||||
<string name="list_item_config">Game settings...</string>
|
<string name="list_item_config">Game settings...</string>
|
||||||
<!-- pulls up dialog to rename (change name of) the selected game -->
|
<!-- pulls up dialog to rename (change name of) the selected game -->
|
||||||
<string name="list_item_rename">Rename...</string>
|
<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 -->
|
<!-- pulls up dialog to delete the selected game -->
|
||||||
<string name="list_item_delete">Delete</string>
|
<string name="list_item_delete">Delete</string>
|
||||||
<!-- pulls up dialog to reset the selected game, that is to remove
|
<!-- pulls up dialog to reset the selected game, that is to remove
|
||||||
|
@ -181,12 +185,6 @@
|
||||||
game? Resetting erases all moves and any connection
|
game? Resetting erases all moves and any connection
|
||||||
information.</string>
|
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:
|
# :Screens:
|
||||||
|
@ -630,7 +628,8 @@
|
||||||
|
|
||||||
<!-- Appended to the above in the phonies_warn case. User may
|
<!-- Appended to the above in the phonies_warn case. User may
|
||||||
ignore the warning -->
|
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
|
<!-- Appended to the above in the phonies_disallow case. User has
|
||||||
lost his turn. -->
|
lost his turn. -->
|
||||||
<string name="badwords_lost"> Turn lost.</string>
|
<string name="badwords_lost"> Turn lost.</string>
|
||||||
|
@ -1235,7 +1234,7 @@
|
||||||
|
|
||||||
\u003cbr \\\u003E
|
\u003cbr \\\u003E
|
||||||
\u003cbr \\\u003E
|
\u003cbr \\\u003E
|
||||||
(full link: %1$s)
|
(full link: %1$s )
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
<!-- This is the body of the text version of the invitation. A URL
|
<!-- 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_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 -->
|
<!-- Used in formatting final scores display -->
|
||||||
<string name="str_resigned">Resigned</string>
|
<string name="str_resigned">Resigned</string>
|
||||||
<!-- Used in formatting final scores display -->
|
<!-- Used in formatting final scores display -->
|
||||||
|
@ -2130,9 +2129,32 @@
|
||||||
|
|
||||||
<string name="download_path_title">Downloads Directory</string>
|
<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_cur_games">My games</string>
|
||||||
<string name="group_new_games">New 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
|
<!-- Button shown in game over dialog triggering creation of new
|
||||||
game with the same players and parameters as the one that
|
game with the same players and parameters as the one that
|
||||||
just ended. -->
|
just ended. -->
|
||||||
|
@ -2141,4 +2163,5 @@
|
||||||
<string name="square_tiles">Square rack tiles</string>
|
<string name="square_tiles">Square rack tiles</string>
|
||||||
<string name="square_tiles_summary">Even if they can be taller</string>
|
<string name="square_tiles_summary">Even if they can be taller</string>
|
||||||
|
|
||||||
|
<string name="change_groupf">Move game %s</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -60,5 +60,11 @@
|
||||||
<item name="android:layout_marginBottom">3sp</item>
|
<item name="android:layout_marginBottom">3sp</item>
|
||||||
</style>
|
</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>
|
</resources>
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.eehouse.android.xw4;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
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_DICTINFO = "dictinfo";
|
||||||
public static final String TABLE_NAME_GROUPS = "groups";
|
public static final String TABLE_NAME_GROUPS = "groups";
|
||||||
private static final String DB_NAME = "xwdb";
|
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 GAME_NAME = "GAME_NAME";
|
||||||
public static final String NUM_MOVES = "NUM_MOVES";
|
public static final String NUM_MOVES = "NUM_MOVES";
|
||||||
|
@ -197,6 +198,8 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||||
case 14:
|
case 14:
|
||||||
addSumColumn( db, GROUPID );
|
addSumColumn( db, GROUPID );
|
||||||
createGroupsTable( db );
|
createGroupsTable( db );
|
||||||
|
case 15:
|
||||||
|
moveToCurGames( db );
|
||||||
// nothing yet
|
// nothing yet
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -260,4 +263,21 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||||
XWPrefs.setDefaultNewGameGroup( m_context, newGroup );
|
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();
|
db.close();
|
||||||
notifyListeners( rowid, false );
|
notifyListeners( rowid, false );
|
||||||
|
invalGroupsCache();
|
||||||
}
|
}
|
||||||
} // saveSummary
|
} // saveSummary
|
||||||
|
|
||||||
|
@ -728,6 +729,7 @@ public class DBUtils {
|
||||||
if ( -1 != rowid ) { // Means new game?
|
if ( -1 != rowid ) { // Means new game?
|
||||||
notifyListeners( rowid, false );
|
notifyListeners( rowid, false );
|
||||||
}
|
}
|
||||||
|
invalGroupsCache();
|
||||||
return rowid;
|
return rowid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,35 +784,6 @@ public class DBUtils {
|
||||||
notifyListeners( lock.getRowid(), true );
|
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()
|
private static void clearRowIDsCache()
|
||||||
{
|
{
|
||||||
synchronized( DBUtils.class ) {
|
synchronized( DBUtils.class ) {
|
||||||
|
@ -865,6 +838,249 @@ public class DBUtils {
|
||||||
return result;
|
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 )
|
private static String getChatHistoryStr( Context context, long rowid )
|
||||||
{
|
{
|
||||||
String result = null;
|
String result = null;
|
||||||
|
|
|
@ -23,7 +23,6 @@ package org.eehouse.android.xw4;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.ExpandableListActivity;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
@ -33,7 +32,6 @@ import android.content.res.Resources;
|
||||||
import android.database.DataSetObserver;
|
import android.database.DataSetObserver;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
|
@ -47,9 +45,7 @@ import android.widget.ExpandableListAdapter;
|
||||||
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
|
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
|
||||||
import android.widget.ExpandableListView;
|
import android.widget.ExpandableListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import junit.framework.Assert;
|
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.jni.JNIUtilsImpl;
|
||||||
import org.eehouse.android.xw4.DictUtils.DictLoc;
|
import org.eehouse.android.xw4.DictUtils.DictLoc;
|
||||||
|
|
||||||
public class DictsActivity extends ExpandableListActivity
|
public class DictsActivity extends XWExpandableListActivity
|
||||||
implements View.OnClickListener, XWListItem.DeleteCallback,
|
implements View.OnClickListener, XWListItem.DeleteCallback,
|
||||||
MountEventReceiver.SDCardNotifiee, DlgDelegate.DlgClickNotify,
|
MountEventReceiver.SDCardNotifiee, DlgDelegate.DlgClickNotify,
|
||||||
DictImportActivity.DownloadFinishedListener {
|
DictImportActivity.DownloadFinishedListener {
|
||||||
|
@ -86,10 +82,8 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
private String m_deleteDict = null;
|
private String m_deleteDict = null;
|
||||||
private String m_download;
|
private String m_download;
|
||||||
private ExpandableListView m_expView;
|
private ExpandableListView m_expView;
|
||||||
private DlgDelegate m_delegate;
|
|
||||||
private String[] m_locNames;
|
private String[] m_locNames;
|
||||||
private DictListAdapter m_adapter;
|
private DictListAdapter m_adapter;
|
||||||
private Handler m_handler;
|
|
||||||
|
|
||||||
private long m_packedPosition;
|
private long m_packedPosition;
|
||||||
private DictLoc m_moveFromLoc;
|
private DictLoc m_moveFromLoc;
|
||||||
|
@ -338,7 +332,6 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
int lang = intent.getIntExtra( MultiService.LANG, -1 );
|
int lang = intent.getIntExtra( MultiService.LANG, -1 );
|
||||||
String name = intent.getStringExtra( MultiService.DICT );
|
String name = intent.getStringExtra( MultiService.DICT );
|
||||||
m_launchedForMissing = true;
|
m_launchedForMissing = true;
|
||||||
m_handler = new Handler();
|
|
||||||
DictImportActivity
|
DictImportActivity
|
||||||
.downloadDictInBack( DictsActivity.this, lang,
|
.downloadDictInBack( DictsActivity.this, lang,
|
||||||
name, DictsActivity.this );
|
name, DictsActivity.this );
|
||||||
|
@ -355,7 +348,7 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dialog = m_delegate.onCreateDialog( id );
|
dialog = super.onCreateDialog( id );
|
||||||
doRemove = false;
|
doRemove = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -371,7 +364,6 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
protected void onPrepareDialog( int id, Dialog dialog )
|
protected void onPrepareDialog( int id, Dialog dialog )
|
||||||
{
|
{
|
||||||
super.onPrepareDialog( id, dialog );
|
super.onPrepareDialog( id, dialog );
|
||||||
m_delegate.onPrepareDialog( id, dialog );
|
|
||||||
|
|
||||||
if ( MOVE_DICT == id ) {
|
if ( MOVE_DICT == id ) {
|
||||||
// The move button should always start out disabled
|
// The move button should always start out disabled
|
||||||
|
@ -399,7 +391,6 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
Resources res = getResources();
|
Resources res = getResources();
|
||||||
m_locNames = res.getStringArray( R.array.loc_names );
|
m_locNames = res.getStringArray( R.array.loc_names );
|
||||||
|
|
||||||
m_delegate = new DlgDelegate( this, this, savedInstanceState );
|
|
||||||
m_factory = LayoutInflater.from( this );
|
m_factory = LayoutInflater.from( this );
|
||||||
|
|
||||||
m_download = getString( R.string.download_dicts );
|
m_download = getString( R.string.download_dicts );
|
||||||
|
@ -447,7 +438,6 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
protected void onSaveInstanceState( Bundle outState )
|
protected void onSaveInstanceState( Bundle outState )
|
||||||
{
|
{
|
||||||
super.onSaveInstanceState( outState );
|
super.onSaveInstanceState( outState );
|
||||||
m_delegate.onSaveInstanceState( outState );
|
|
||||||
|
|
||||||
outState.putLong( PACKED_POSITION, m_packedPosition );
|
outState.putLong( PACKED_POSITION, m_packedPosition );
|
||||||
outState.putString( NAME, m_name );
|
outState.putString( NAME, m_name );
|
||||||
|
@ -622,8 +612,7 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_delegate.showConfirmThen( msg, R.string.button_delete,
|
showConfirmThen( msg, R.string.button_delete, DELETE_DICT_ACTION );
|
||||||
DELETE_DICT_ACTION );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MountEventReceiver.SDCardNotifiee interface
|
// MountEventReceiver.SDCardNotifiee interface
|
||||||
|
@ -632,7 +621,7 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
DbgUtils.logf( "DictsActivity.cardMounted(%b)", nowMounted );
|
DbgUtils.logf( "DictsActivity.cardMounted(%b)", nowMounted );
|
||||||
// post so other SDCardNotifiee implementations get a chance
|
// post so other SDCardNotifiee implementations get a chance
|
||||||
// to process first: avoid race conditions
|
// to process first: avoid race conditions
|
||||||
new Handler().post( new Runnable() {
|
post( new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
mkListAdapter();
|
mkListAdapter();
|
||||||
expandGroups();
|
expandGroups();
|
||||||
|
@ -773,7 +762,7 @@ public class DictsActivity extends ExpandableListActivity
|
||||||
public void downloadFinished( String name, final boolean success )
|
public void downloadFinished( String name, final boolean success )
|
||||||
{
|
{
|
||||||
if ( m_launchedForMissing ) {
|
if ( m_launchedForMissing ) {
|
||||||
m_handler.post( new Runnable() {
|
post( new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
|
|
|
@ -79,6 +79,7 @@ public class ExpiringDelegate {
|
||||||
if ( haveTurnLocal ) {
|
if ( haveTurnLocal ) {
|
||||||
setBackground();
|
setBackground();
|
||||||
} else {
|
} else {
|
||||||
|
m_view.setBackgroundDrawable( null );
|
||||||
m_view.setWillNotDraw( false );
|
m_view.setWillNotDraw( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,17 @@ class ExpiringTextView extends TextView {
|
||||||
if ( null == m_delegate ) {
|
if ( null == m_delegate ) {
|
||||||
m_delegate = new ExpiringDelegate( m_context, this, handler );
|
m_delegate = new ExpiringDelegate( m_context, this, handler );
|
||||||
}
|
}
|
||||||
m_delegate.configure( haveTurn, haveTurnLocal, startSecs );
|
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
|
@Override
|
||||||
|
|
|
@ -20,93 +20,321 @@
|
||||||
package org.eehouse.android.xw4;
|
package org.eehouse.android.xw4;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.database.DataSetObserver;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ExpandableListAdapter;
|
||||||
import android.widget.ListView;
|
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 junit.framework.Assert;
|
||||||
|
|
||||||
import org.eehouse.android.xw4.jni.*;
|
import org.eehouse.android.xw4.jni.*;
|
||||||
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
|
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
|
||||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
|
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 Context m_context;
|
||||||
private ListView m_list;
|
private ExpandableListView m_list;
|
||||||
private LayoutInflater m_factory;
|
|
||||||
private int m_fieldID;
|
private int m_fieldID;
|
||||||
private Handler m_handler;
|
private Handler m_handler;
|
||||||
private LoadItemCB m_cb;
|
private LoadItemCB m_cb;
|
||||||
|
private long[] m_positions;
|
||||||
|
|
||||||
public interface LoadItemCB {
|
public interface LoadItemCB {
|
||||||
public void itemClicked( long rowid, GameSummary summary );
|
public void itemClicked( long rowid, GameSummary summary );
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameListAdapter( Context context, ListView list,
|
public GameListAdapter( Context context, ExpandableListView list,
|
||||||
Handler handler, LoadItemCB cb, String fieldName ) {
|
Handler handler, LoadItemCB cb, long[] positions,
|
||||||
super( DBUtils.gamesList(context).length );
|
String fieldName )
|
||||||
|
{
|
||||||
m_context = context;
|
m_context = context;
|
||||||
m_list = list;
|
m_list = list;
|
||||||
m_handler = handler;
|
m_handler = handler;
|
||||||
m_cb = cb;
|
m_cb = cb;
|
||||||
m_factory = LayoutInflater.from( context );
|
m_positions = checkPositions( positions );
|
||||||
|
|
||||||
m_fieldID = fieldToID( fieldName );
|
m_fieldID = fieldToID( fieldName );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public long[] getPositions()
|
||||||
public int getCount() {
|
{
|
||||||
return DBUtils.gamesList(m_context).length;
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then copy in what's left
|
||||||
|
Iterator<Long> iter = unused.iterator();
|
||||||
|
while ( iter.hasNext() ) {
|
||||||
|
newArray[nextIndx++] = iter.next();
|
||||||
|
}
|
||||||
|
m_positions = newArray;
|
||||||
|
}
|
||||||
|
return m_positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Views. A view depends on a summary, which takes time to load.
|
public boolean moveGroup( long groupid, int moveBy )
|
||||||
// When one needs loading it's done via an async task.
|
|
||||||
public View getView( int position, View convertView, ViewGroup parent )
|
|
||||||
{
|
{
|
||||||
GameListItem result = (GameListItem)
|
int src = getGroupPosition( groupid );
|
||||||
m_factory.inflate( R.layout.game_list_item, null );
|
int dest = src + moveBy;
|
||||||
result.init( m_handler, DBUtils.gamesList(m_context)[position],
|
long[] positions = getPositions();
|
||||||
m_fieldID, m_cb );
|
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;
|
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 )
|
public void inval( long rowid )
|
||||||
{
|
{
|
||||||
GameListItem child = getItemFor( rowid );
|
GameListItem child = getGameItemFor( rowid );
|
||||||
|
int groupPosition;
|
||||||
if ( null != child && child.getRowID() == rowid ) {
|
if ( null != child && child.getRowID() == rowid ) {
|
||||||
child.forceReload();
|
child.forceReload();
|
||||||
|
|
||||||
|
groupPosition = child.getGroupPosition();
|
||||||
} else {
|
} else {
|
||||||
DbgUtils.logf( "no child for rowid %d", rowid );
|
// DbgUtils.logf( "no child for rowid %d", rowid );
|
||||||
GameListItem.inval( rowid );
|
GameListItem.inval( rowid );
|
||||||
m_list.invalidate();
|
m_list.invalidate();
|
||||||
|
|
||||||
|
long groupID = DBUtils.getGroupForGame( m_context, rowid );
|
||||||
|
groupPosition = getGroupPosition( groupID );
|
||||||
}
|
}
|
||||||
|
reloadGroup( groupPosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalName( long rowid )
|
public void invalName( long rowid )
|
||||||
{
|
{
|
||||||
GameListItem item = getItemFor( rowid );
|
GameListItem item = getGameItemFor( rowid );
|
||||||
if ( null != item ) {
|
if ( null != item ) {
|
||||||
item.invalName();
|
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 )
|
public boolean setField( String fieldName )
|
||||||
{
|
{
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
int newID = fieldToID( fieldName );
|
int newID = fieldToID( fieldName );
|
||||||
if ( -1 == newID ) {
|
if ( -1 == newID ) {
|
||||||
if ( XWApp.DEBUG ) {
|
DbgUtils.logf( "GameListAdapter.setField(): unable to match"
|
||||||
DbgUtils.logf( "GameListAdapter.setField(): unable to match"
|
+ " fieldName %s", fieldName );
|
||||||
+ " fieldName %s", fieldName );
|
|
||||||
}
|
|
||||||
} else if ( m_fieldID != newID ) {
|
} 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;
|
m_fieldID = newID;
|
||||||
// return true so caller will do onContentChanged.
|
// return true so caller will do onContentChanged.
|
||||||
// There's no other way to signal GameListItem instances
|
// There's no other way to signal GameListItem instances
|
||||||
|
@ -116,12 +344,41 @@ public class GameListAdapter extends XWListAdapter {
|
||||||
return changed;
|
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;
|
GameListItem result = null;
|
||||||
int position = positionFor( rowid );
|
int count = m_list.getChildCount();
|
||||||
if ( 0 <= position ) {
|
for ( int ii = 0; ii < count; ++ii ) {
|
||||||
result = (GameListItem)m_list.getChildAt( position );
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -144,16 +401,32 @@ public class GameListAdapter extends XWListAdapter {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int positionFor( long rowid )
|
private void reloadGroup( int groupPosition )
|
||||||
{
|
{
|
||||||
int position = -1;
|
GameListGroup group = getGroupItemFor( groupPosition );
|
||||||
long[] rowids = DBUtils.gamesList( m_context );
|
if ( null != group ) {
|
||||||
for ( int ii = 0; ii < rowids.length; ++ii ) {
|
GameGroupInfo ggi = getInfoForGroup( groupPosition );
|
||||||
if ( rowids[ii] == rowid ) {
|
group.setPct( ggi.m_hasTurn, ggi.m_turnLocal, ggi.m_lastMoveTime );
|
||||||
position = ii;
|
}
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
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 GameListAdapter.LoadItemCB m_cb;
|
||||||
private int m_fieldID;
|
private int m_fieldID;
|
||||||
private int m_loadingCount;
|
private int m_loadingCount;
|
||||||
|
private int m_groupPosition;
|
||||||
|
|
||||||
public GameListItem( Context cx, AttributeSet as )
|
public GameListItem( Context cx, AttributeSet as )
|
||||||
{
|
{
|
||||||
|
@ -68,11 +69,12 @@ public class GameListItem extends LinearLayout
|
||||||
m_loadingCount = 0;
|
m_loadingCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init( Handler handler, long rowid, int fieldID,
|
private void init( Handler handler, long rowid, int groupPosition,
|
||||||
GameListAdapter.LoadItemCB cb )
|
int fieldID, GameListAdapter.LoadItemCB cb )
|
||||||
{
|
{
|
||||||
m_handler = handler;
|
m_handler = handler;
|
||||||
m_rowid = rowid;
|
m_rowid = rowid;
|
||||||
|
m_groupPosition = groupPosition;
|
||||||
m_fieldID = fieldID;
|
m_fieldID = fieldID;
|
||||||
m_cb = cb;
|
m_cb = cb;
|
||||||
|
|
||||||
|
@ -128,6 +130,11 @@ public class GameListItem extends LinearLayout
|
||||||
return m_rowid;
|
return m_rowid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getGroupPosition()
|
||||||
|
{
|
||||||
|
return m_groupPosition;
|
||||||
|
}
|
||||||
|
|
||||||
// View.OnClickListener interface
|
// View.OnClickListener interface
|
||||||
public void onClick( View view ) {
|
public void onClick( View view ) {
|
||||||
m_expanded = !m_expanded;
|
m_expanded = !m_expanded;
|
||||||
|
@ -297,6 +304,17 @@ public class GameListItem extends LinearLayout
|
||||||
}
|
}
|
||||||
} // class LoadItemTask
|
} // 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 )
|
public static void inval( long rowid )
|
||||||
{
|
{
|
||||||
synchronized( s_invalRows ) {
|
synchronized( s_invalRows ) {
|
||||||
|
|
|
@ -190,10 +190,10 @@ public class GameUtils {
|
||||||
return rowid;
|
return rowid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteGame( Context context, long rowid,
|
public static boolean deleteGame( Context context, long rowid,
|
||||||
boolean informNow )
|
boolean informNow )
|
||||||
{
|
{
|
||||||
DbgUtils.logf( "deleteGame(rowid=%d)", rowid );
|
boolean success;
|
||||||
// does this need to be synchronized?
|
// does this need to be synchronized?
|
||||||
GameLock lock = new GameLock( rowid, true );
|
GameLock lock = new GameLock( rowid, true );
|
||||||
if ( lock.tryLock() ) {
|
if ( lock.tryLock() ) {
|
||||||
|
@ -201,8 +201,25 @@ public class GameUtils {
|
||||||
Utils.cancelNotification( context, (int)rowid );
|
Utils.cancelNotification( context, (int)rowid );
|
||||||
DBUtils.deleteGame( context, lock );
|
DBUtils.deleteGame( context, lock );
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
success = true;
|
||||||
} else {
|
} else {
|
||||||
DbgUtils.logf( "deleteGame: unable to delete rowid %d", rowid );
|
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;
|
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 )
|
public static String newName( Context context )
|
||||||
{
|
{
|
||||||
return "untitled";
|
return "untitled";
|
||||||
|
|
|
@ -41,29 +41,36 @@ import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
|
||||||
|
import android.widget.ExpandableListView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
// import android.telephony.PhoneStateListener;
|
// import android.telephony.PhoneStateListener;
|
||||||
// import android.telephony.TelephonyManager;
|
// import android.telephony.TelephonyManager;
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import org.eehouse.android.xw4.jni.*;
|
import org.eehouse.android.xw4.jni.*;
|
||||||
|
|
||||||
public class GamesList extends XWListActivity
|
public class GamesList extends XWExpandableListActivity
|
||||||
implements DBUtils.DBChangeListener,
|
implements DBUtils.DBChangeListener,
|
||||||
GameListAdapter.LoadItemCB,
|
GameListAdapter.LoadItemCB,
|
||||||
DictImportActivity.DownloadFinishedListener {
|
DictImportActivity.DownloadFinishedListener {
|
||||||
|
|
||||||
private static final int WARN_NODICT = DlgDelegate.DIALOG_LAST + 1;
|
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_SUBST = WARN_NODICT + 1;
|
||||||
private static final int WARN_NODICT_NEW = WARN_NODICT + 2;
|
private static final int SHOW_SUBST = WARN_NODICT + 2;
|
||||||
private static final int SHOW_SUBST = WARN_NODICT + 3;
|
private static final int GET_NAME = WARN_NODICT + 3;
|
||||||
private static final int GET_NAME = WARN_NODICT + 4;
|
private static final int RENAME_GAME = WARN_NODICT + 4;
|
||||||
private static final int RENAME_GAME = WARN_NODICT + 5;
|
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_ROWID = "SAVE_ROWID";
|
||||||
|
private static final String SAVE_GROUPID = "SAVE_GROUPID";
|
||||||
private static final String SAVE_DICTNAMES = "SAVE_DICTNAMES";
|
private static final String SAVE_DICTNAMES = "SAVE_DICTNAMES";
|
||||||
|
|
||||||
private static final String RELAYIDS_EXTRA = "relayids";
|
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 NEW_NET_GAME_ACTION = 1;
|
||||||
private static final int RESET_GAME_ACTION = 2;
|
private static final int RESET_GAME_ACTION = 2;
|
||||||
private static final int DELETE_GAME_ACTION = 3;
|
private static final int DELETE_GAME_ACTION = 3;
|
||||||
private static final int DELETE_ALL_ACTION = 4;
|
private static final int SYNC_MENU_ACTION = 4;
|
||||||
private static final int SYNC_MENU_ACTION = 5;
|
private static final int NEW_FROM_ACTION = 5;
|
||||||
private static final int NEW_FROM_ACTION = 6;
|
private static final int DELETE_GROUP_ACTION = 6;
|
||||||
private static final int[] DEBUGITEMS = { R.id.gamel_menu_loaddb
|
private static final int[] DEBUGITEMS = { R.id.gamel_menu_loaddb
|
||||||
, R.id.gamel_menu_storedb
|
, R.id.gamel_menu_storedb
|
||||||
, R.id.gamel_menu_checkupdates
|
, R.id.gamel_menu_checkupdates
|
||||||
|
@ -90,12 +97,16 @@ public class GamesList extends XWListActivity
|
||||||
private String[] m_sameLangDicts;
|
private String[] m_sameLangDicts;
|
||||||
private int m_missingDictLang;
|
private int m_missingDictLang;
|
||||||
private long m_rowid;
|
private long m_rowid;
|
||||||
|
private long m_groupid;
|
||||||
|
private String m_nameField;
|
||||||
private NetLaunchInfo m_netLaunchInfo;
|
private NetLaunchInfo m_netLaunchInfo;
|
||||||
|
private GameNamer m_namer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dialog onCreateDialog( int id )
|
protected Dialog onCreateDialog( int id )
|
||||||
{
|
{
|
||||||
DialogInterface.OnClickListener lstnr;
|
DialogInterface.OnClickListener lstnr;
|
||||||
|
DialogInterface.OnClickListener lstnr2;
|
||||||
LinearLayout layout;
|
LinearLayout layout;
|
||||||
|
|
||||||
Dialog dialog = super.onCreateDialog( id );
|
Dialog dialog = super.onCreateDialog( id );
|
||||||
|
@ -178,36 +189,87 @@ public class GamesList extends XWListActivity
|
||||||
.setNegativeButton( R.string.button_cancel, null )
|
.setNegativeButton( R.string.button_cancel, null )
|
||||||
.setSingleChoiceItems( m_sameLangDicts, 0, null )
|
.setSingleChoiceItems( m_sameLangDicts, 0, null )
|
||||||
.create();
|
.create();
|
||||||
;
|
|
||||||
// Force destruction so onCreateDialog() will get
|
// Force destruction so onCreateDialog() will get
|
||||||
// called next time and we can insert a different
|
// called next time and we can insert a different
|
||||||
// list. There seems to be no way to change the list
|
// list. There seems to be no way to change the list
|
||||||
// inside onPrepareDialog().
|
// inside onPrepareDialog().
|
||||||
dialog.setOnDismissListener(new DialogInterface.
|
Utils.setRemoveOnDismiss( this, dialog, id );
|
||||||
OnDismissListener() {
|
|
||||||
public void onDismiss(DialogInterface dlg) {
|
|
||||||
removeDialog( SHOW_SUBST );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RENAME_GAME:
|
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() {
|
lstnr = new DialogInterface.OnClickListener() {
|
||||||
public void onClick( DialogInterface dlg, int item ) {
|
public void onClick( DialogInterface dlg, int item ) {
|
||||||
String name = namerView.getName();
|
String name = m_namer.getName();
|
||||||
DBUtils.setName( GamesList.this, m_rowid, name );
|
DBUtils.setName( GamesList.this, m_rowid, name );
|
||||||
m_adapter.invalName( m_rowid );
|
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 )
|
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 )
|
.setNegativeButton( R.string.button_cancel, null )
|
||||||
.setPositiveButton( R.string.button_ok, lstnr )
|
|
||||||
.setView( namerView )
|
|
||||||
.create();
|
.create();
|
||||||
Utils.setRemoveOnDismiss( this, dialog, id );
|
Utils.setRemoveOnDismiss( this, dialog, id );
|
||||||
break;
|
break;
|
||||||
|
@ -248,6 +310,16 @@ public class GamesList extends XWListActivity
|
||||||
return dialog;
|
return dialog;
|
||||||
} // onCreateDialog
|
} // 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
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
|
@ -258,7 +330,7 @@ public class GamesList extends XWListActivity
|
||||||
getBundledData( savedInstanceState );
|
getBundledData( savedInstanceState );
|
||||||
|
|
||||||
setContentView(R.layout.game_list);
|
setContentView(R.layout.game_list);
|
||||||
registerForContextMenu( getListView() );
|
registerForContextMenu( getExpandableListView() );
|
||||||
DBUtils.setDBChangeListener( this );
|
DBUtils.setDBChangeListener( this );
|
||||||
|
|
||||||
boolean isUpgrade = Utils.firstBootThisVersion( this );
|
boolean isUpgrade = Utils.firstBootThisVersion( this );
|
||||||
|
@ -280,11 +352,21 @@ public class GamesList extends XWListActivity
|
||||||
// R.string.key_notagain_newgame );
|
// 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 );
|
String field = CommonPrefs.getSummaryField( this );
|
||||||
m_adapter = new GameListAdapter( this, getListView(), new Handler(),
|
long[] positions = XWPrefs.getGroupPositions( this );
|
||||||
this, field );
|
m_adapter = new GameListAdapter( this, getExpandableListView(),
|
||||||
|
new Handler(), this, positions,
|
||||||
|
field );
|
||||||
setListAdapter( m_adapter );
|
setListAdapter( m_adapter );
|
||||||
|
m_adapter.expandGroups( getExpandableListView() );
|
||||||
|
|
||||||
NetUtils.informOfDeaths( this );
|
NetUtils.informOfDeaths( this );
|
||||||
|
|
||||||
|
@ -318,13 +400,13 @@ public class GamesList extends XWListActivity
|
||||||
boolean hide = CommonPrefs.getHideIntro( this );
|
boolean hide = CommonPrefs.getHideIntro( this );
|
||||||
int hereOrGone = hide ? View.GONE : View.VISIBLE;
|
int hereOrGone = hide ? View.GONE : View.VISIBLE;
|
||||||
for ( int id : new int[]{ R.id.empty_games_list,
|
for ( int id : new int[]{ R.id.empty_games_list,
|
||||||
R.id.new_game } ) {
|
R.id.new_buttons } ) {
|
||||||
View view = findViewById( id );
|
View view = findViewById( id );
|
||||||
view.setVisibility( hereOrGone );
|
view.setVisibility( hereOrGone );
|
||||||
}
|
}
|
||||||
View empty = findViewById( R.id.empty_list_msg );
|
View empty = findViewById( R.id.empty_list_msg );
|
||||||
empty.setVisibility( hide ? View.VISIBLE : View.GONE );
|
empty.setVisibility( hide ? View.VISIBLE : View.GONE );
|
||||||
getListView().setEmptyView( hide? empty : null );
|
getExpandableListView().setEmptyView( hide? empty : null );
|
||||||
|
|
||||||
// TelephonyManager mgr =
|
// TelephonyManager mgr =
|
||||||
// (TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
|
// (TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
|
||||||
|
@ -340,7 +422,8 @@ public class GamesList extends XWListActivity
|
||||||
// (TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
|
// (TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
|
||||||
// mgr.listen( m_phoneStateListener, PhoneStateListener.LISTEN_NONE );
|
// mgr.listen( m_phoneStateListener, PhoneStateListener.LISTEN_NONE );
|
||||||
// m_phoneStateListener = null;
|
// m_phoneStateListener = null;
|
||||||
|
long[] positions = m_adapter.getPositions();
|
||||||
|
XWPrefs.setGroupPositions( this, positions );
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,6 +439,7 @@ public class GamesList extends XWListActivity
|
||||||
{
|
{
|
||||||
super.onSaveInstanceState( outState );
|
super.onSaveInstanceState( outState );
|
||||||
outState.putLong( SAVE_ROWID, m_rowid );
|
outState.putLong( SAVE_ROWID, m_rowid );
|
||||||
|
outState.putLong( SAVE_GROUPID, m_groupid );
|
||||||
outState.putString( SAVE_DICTNAMES, m_missingDictName );
|
outState.putString( SAVE_DICTNAMES, m_missingDictName );
|
||||||
if ( null != m_netLaunchInfo ) {
|
if ( null != m_netLaunchInfo ) {
|
||||||
m_netLaunchInfo.putSelf( outState );
|
m_netLaunchInfo.putSelf( outState );
|
||||||
|
@ -366,6 +450,7 @@ public class GamesList extends XWListActivity
|
||||||
{
|
{
|
||||||
if ( null != bundle ) {
|
if ( null != bundle ) {
|
||||||
m_rowid = bundle.getLong( SAVE_ROWID );
|
m_rowid = bundle.getLong( SAVE_ROWID );
|
||||||
|
m_groupid = bundle.getLong( SAVE_GROUPID );
|
||||||
m_netLaunchInfo = new NetLaunchInfo( bundle );
|
m_netLaunchInfo = new NetLaunchInfo( bundle );
|
||||||
m_missingDictName = bundle.getString( SAVE_DICTNAMES );
|
m_missingDictName = bundle.getString( SAVE_DICTNAMES );
|
||||||
}
|
}
|
||||||
|
@ -457,12 +542,6 @@ public class GamesList extends XWListActivity
|
||||||
case DELETE_GAME_ACTION:
|
case DELETE_GAME_ACTION:
|
||||||
GameUtils.deleteGame( this, m_rowid, true );
|
GameUtils.deleteGame( this, m_rowid, true );
|
||||||
break;
|
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:
|
case SYNC_MENU_ACTION:
|
||||||
doSyncMenuitem();
|
doSyncMenuitem();
|
||||||
break;
|
break;
|
||||||
|
@ -472,40 +551,88 @@ public class GamesList extends XWListActivity
|
||||||
m_adapter.inval( newid );
|
m_adapter.inval( newid );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DELETE_GROUP_ACTION:
|
||||||
|
GameUtils.deleteGroup( this, m_groupid );
|
||||||
|
onContentChanged();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onContentChanged()
|
||||||
|
{
|
||||||
|
super.onContentChanged();
|
||||||
|
if ( null != m_adapter ) {
|
||||||
|
m_adapter.expandGroups( getExpandableListView() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu( ContextMenu menu, View view,
|
public void onCreateContextMenu( ContextMenu menu, View view,
|
||||||
ContextMenuInfo menuInfo )
|
ContextMenuInfo menuInfo )
|
||||||
{
|
{
|
||||||
MenuInflater inflater = getMenuInflater();
|
ExpandableListView.ExpandableListContextMenuInfo info
|
||||||
inflater.inflate( R.menu.games_list_item_menu, menu );
|
= (ExpandableListView.ExpandableListContextMenuInfo)menuInfo;
|
||||||
|
long packedPos = info.packedPosition;
|
||||||
|
int childPos = ExpandableListView.getPackedPositionChild( packedPos );
|
||||||
|
|
||||||
AdapterView.AdapterContextMenuInfo info =
|
String name;
|
||||||
(AdapterView.AdapterContextMenuInfo)menuInfo;
|
if ( 0 <= childPos ) { // game case
|
||||||
int position = info.position;
|
MenuInflater inflater = getMenuInflater();
|
||||||
long rowid = DBUtils.gamesList( this )[position];
|
inflater.inflate( R.menu.games_list_item_menu, menu );
|
||||||
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,
|
menu.setHeaderTitle( getString( R.string.game_item_menu_titlef,
|
||||||
title ) );
|
name ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onContextItemSelected( MenuItem item )
|
public boolean onContextItemSelected( MenuItem item )
|
||||||
{
|
{
|
||||||
AdapterView.AdapterContextMenuInfo info;
|
ExpandableListContextMenuInfo info;
|
||||||
try {
|
try {
|
||||||
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
info = (ExpandableListContextMenuInfo)item.getMenuInfo();
|
||||||
} catch (ClassCastException cce) {
|
} catch (ClassCastException cce) {
|
||||||
DbgUtils.loge( cce );
|
DbgUtils.loge( cce );
|
||||||
return false;
|
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
|
} // onContextItemSelected
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -520,7 +647,7 @@ public class GamesList extends XWListActivity
|
||||||
@Override
|
@Override
|
||||||
public boolean onPrepareOptionsMenu( Menu menu )
|
public boolean onPrepareOptionsMenu( Menu menu )
|
||||||
{
|
{
|
||||||
boolean visible = XWPrefs.getDebugEnabled( this ) ;
|
boolean visible = XWPrefs.getDebugEnabled( this );
|
||||||
for ( int id : DEBUGITEMS ) {
|
for ( int id : DEBUGITEMS ) {
|
||||||
MenuItem item = menu.findItem( id );
|
MenuItem item = menu.findItem( id );
|
||||||
item.setVisible( visible );
|
item.setVisible( visible );
|
||||||
|
@ -544,12 +671,8 @@ public class GamesList extends XWListActivity
|
||||||
startNewGameActivity();
|
startNewGameActivity();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R.id.gamel_menu_delete_all:
|
case R.id.gamel_menu_newgroup:
|
||||||
if ( DBUtils.gamesList( this ).length > 0 ) {
|
showDialog( NEW_GROUP );
|
||||||
showConfirmThen( R.string.confirm_delete_all,
|
|
||||||
R.string.button_delete, DELETE_ALL_ACTION );
|
|
||||||
}
|
|
||||||
handled = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R.id.gamel_menu_dicts:
|
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;
|
boolean handled = true;
|
||||||
DialogInterface.OnClickListener lstnr;
|
DialogInterface.OnClickListener lstnr;
|
||||||
|
|
||||||
m_rowid = DBUtils.gamesList( this )[position];
|
m_rowid = rowid;
|
||||||
|
|
||||||
if ( R.id.list_item_delete == menuID ) {
|
if ( R.id.list_item_delete == menuID ) {
|
||||||
showConfirmThen( R.string.confirm_delete, R.string.button_delete,
|
showConfirmThen( R.string.confirm_delete, R.string.button_delete,
|
||||||
|
@ -638,7 +761,13 @@ public class GamesList extends XWListActivity
|
||||||
case R.id.list_item_rename:
|
case R.id.list_item_rename:
|
||||||
showDialog( RENAME_GAME );
|
showDialog( RENAME_GAME );
|
||||||
break;
|
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:
|
case R.id.list_item_new_from:
|
||||||
showNotAgainDlgThen( R.string.not_again_newfrom,
|
showNotAgainDlgThen( R.string.not_again_newfrom,
|
||||||
R.string.key_notagain_newfrom,
|
R.string.key_notagain_newfrom,
|
||||||
|
@ -674,7 +803,48 @@ public class GamesList extends XWListActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
return handled;
|
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 )
|
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()
|
private boolean makeNewNetGameIf()
|
||||||
{
|
{
|
||||||
boolean madeGame = null != m_netLaunchInfo;
|
boolean madeGame = null != m_netLaunchInfo;
|
||||||
|
|
|
@ -23,28 +23,22 @@ package org.eehouse.android.xw4;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||||
import android.provider.ContactsContract.CommonDataKinds;
|
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.text.method.DialerKeyListener;
|
import android.text.method.DialerKeyListener;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ListView;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import junit.framework.Assert;
|
|
||||||
|
|
||||||
public class SMSInviteActivity extends InviteActivity {
|
public class SMSInviteActivity extends InviteActivity {
|
||||||
|
|
||||||
|
@ -251,31 +245,30 @@ public class SMSInviteActivity extends InviteActivity {
|
||||||
// long time to return. Be safe.
|
// long time to return. Be safe.
|
||||||
if ( null != cursor && !cursor.isClosed() ) {
|
if ( null != cursor && !cursor.isClosed() ) {
|
||||||
if ( cursor.moveToFirst() ) {
|
if ( cursor.moveToFirst() ) {
|
||||||
String name =
|
String name =
|
||||||
cursor.getString( cursor.
|
cursor.getString( cursor.
|
||||||
getColumnIndex( Phone.DISPLAY_NAME));
|
getColumnIndex( Phone.DISPLAY_NAME));
|
||||||
String number =
|
String number =
|
||||||
cursor.getString( cursor.
|
cursor.getString( cursor.
|
||||||
getColumnIndex( Phone.NUMBER ) );
|
getColumnIndex( Phone.NUMBER ) );
|
||||||
|
|
||||||
int type = cursor.getInt( cursor.
|
int type = cursor.getInt( cursor.
|
||||||
getColumnIndex( Phone.TYPE ) );
|
getColumnIndex( Phone.TYPE ) );
|
||||||
m_pendingName = name;
|
m_pendingName = name;
|
||||||
m_pendingNumber = number;
|
m_pendingNumber = number;
|
||||||
if ( Phone.TYPE_MOBILE == type ) {
|
if ( Phone.TYPE_MOBILE == type ) {
|
||||||
showConfirmThen( R.string.warn_unlimited,
|
showConfirmThen( R.string.warn_unlimited,
|
||||||
R.string.button_yes,
|
R.string.button_yes,
|
||||||
POST_WARNING_ACTION );
|
POST_WARNING_ACTION );
|
||||||
} else {
|
} else {
|
||||||
m_immobileConfirmed = false;
|
m_immobileConfirmed = false;
|
||||||
String msg =
|
String msg =
|
||||||
Utils.format( this, R.string.warn_nomobilef,
|
Utils.format( this, R.string.warn_nomobilef,
|
||||||
number, name );
|
number, name );
|
||||||
showConfirmThen( msg, R.string.button_yes,
|
showConfirmThen( msg, R.string.button_yes,
|
||||||
USE_IMMOBILE_ACTION );
|
USE_IMMOBILE_ACTION );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cursor.close();
|
|
||||||
}
|
}
|
||||||
} // addPhoneNumbers
|
} // addPhoneNumbers
|
||||||
|
|
||||||
|
|
|
@ -353,6 +353,12 @@ public class Utils {
|
||||||
item.setVisible( enabled );
|
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 )
|
public static boolean hasSmallScreen( Context context )
|
||||||
{
|
{
|
||||||
if ( null == s_hasSmallScreen ) {
|
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 );
|
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,
|
protected void showNotAgainDlgThen( int msgID, int prefsKey,
|
||||||
int action )
|
int action )
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,6 @@ import android.preference.PreferenceManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import com.google.android.gcm.GCMRegistrar;
|
import com.google.android.gcm.GCMRegistrar;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class XWPrefs {
|
public class XWPrefs {
|
||||||
|
|
||||||
|
@ -305,6 +304,29 @@ public class XWPrefs {
|
||||||
setPrefsLong( context, R.string.key_default_group, val );
|
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 )
|
protected static String getPrefsString( Context context, int keyID )
|
||||||
{
|
{
|
||||||
String key = context.getString( keyID );
|
String key = context.getString( keyID );
|
||||||
|
|
|
@ -224,9 +224,9 @@ public class GameSummary {
|
||||||
&& serverRole != DeviceRole.SERVER_STANDALONE );
|
&& serverRole != DeviceRole.SERVER_STANDALONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isLocal( int indx ) {
|
private boolean isLocal( int indx )
|
||||||
int flag = 2 << (indx * 2);
|
{
|
||||||
return 0 == (m_giFlags & flag);
|
return localTurnNextImpl( m_giFlags, indx );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRobot( int indx ) {
|
private boolean isRobot( int indx ) {
|
||||||
|
@ -328,4 +328,19 @@ public class GameSummary {
|
||||||
return String.format( "%s%s%s", separator, list, separator );
|
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 );
|
byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, m_gi );
|
||||||
if ( Arrays.equals( m_gameAtStart, state ) ) {
|
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 {
|
} else {
|
||||||
GameSummary summary = new GameSummary( m_context, m_gi );
|
GameSummary summary = new GameSummary( m_context, m_gi );
|
||||||
XwJNI.game_summarize( m_jniGamePtr, summary );
|
XwJNI.game_summarize( m_jniGamePtr, summary );
|
||||||
|
|
|
@ -743,12 +743,14 @@ warnBadWords( const XP_UCHAR* word, XP_Bool isLegal,
|
||||||
{
|
{
|
||||||
XP_Bool ok = XP_TRUE;
|
XP_Bool ok = XP_TRUE;
|
||||||
if ( !isLegal ) {
|
if ( !isLegal ) {
|
||||||
BadWordInfo bwi;
|
BadWordInfo bwi = {0};
|
||||||
BoardCtxt* board = (BoardCtxt*)closure;
|
BoardCtxt* board = (BoardCtxt*)closure;
|
||||||
XP_S16 turn = server_getCurrentTurn( board->server );
|
XP_S16 turn = server_getCurrentTurn( board->server );
|
||||||
|
|
||||||
bwi.nWords = 1;
|
bwi.nWords = 1;
|
||||||
bwi.words[0] = word;
|
bwi.words[0] = word;
|
||||||
|
bwi.dictName =
|
||||||
|
dict_getShortName( model_getPlayerDict( board->model, turn ) );
|
||||||
|
|
||||||
ok = !board->badWordRejected
|
ok = !board->badWordRejected
|
||||||
&& util_warnIllegalWord( board->util, &bwi, turn, XP_FALSE );
|
&& util_warnIllegalWord( board->util, &bwi, turn, XP_FALSE );
|
||||||
|
|
|
@ -82,7 +82,7 @@ typedef struct PickInfo {
|
||||||
|
|
||||||
typedef struct BadWordInfo {
|
typedef struct BadWordInfo {
|
||||||
XP_U16 nWords;
|
XP_U16 nWords;
|
||||||
XP_UCHAR* dictName;
|
const XP_UCHAR* dictName;
|
||||||
const XP_UCHAR* words[MAX_TRAY_TILES+1]; /* can form in both directions */
|
const XP_UCHAR* words[MAX_TRAY_TILES+1]; /* can form in both directions */
|
||||||
} BadWordInfo;
|
} BadWordInfo;
|
||||||
|
|
||||||
|
|
|
@ -1708,8 +1708,8 @@ gtk_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi, XP_U16 player,
|
||||||
result = XP_TRUE;
|
result = XP_TRUE;
|
||||||
} else {
|
} else {
|
||||||
XP_ASSERT( bwi->nWords == 1 );
|
XP_ASSERT( bwi->nWords == 1 );
|
||||||
sprintf( buf, "Word \"%s\" not in the current dictionary. "
|
sprintf( buf, "Word \"%s\" not in the current dictionary (%s). "
|
||||||
"Use it anyway?", bwi->words[0] );
|
"Use it anyway?", bwi->words[0], bwi->dictName );
|
||||||
result = gtkask( globals->window, buf, GTK_BUTTONS_YES_NO );
|
result = gtkask( globals->window, buf, GTK_BUTTONS_YES_NO );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue