diff --git a/DroidFish/res/values/strings.xml b/DroidFish/res/values/strings.xml index b4a9617..027e240 100644 --- a/DroidFish/res/values/strings.xml +++ b/DroidFish/res/values/strings.xml @@ -37,6 +37,7 @@ you are not actively using the program.\ Load game from PGN file Load game from Scid file Save game to PGN file + Retrieve Position Truncate Game Tree Move Variation Up Move Variation Down diff --git a/DroidFish/src/org/petero/droidfish/DroidFish.java b/DroidFish/src/org/petero/droidfish/DroidFish.java index 11ce6a7..7651895 100644 --- a/DroidFish/src/org/petero/droidfish/DroidFish.java +++ b/DroidFish/src/org/petero/droidfish/DroidFish.java @@ -19,15 +19,14 @@ package org.petero.droidfish; -import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -75,8 +74,10 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Typeface; @@ -1159,6 +1160,7 @@ public class DroidFish extends Activity implements GUIInterface { static private final int RESULT_SELECT_SCID = 3; static private final int RESULT_OI_PGN_SAVE = 4; static private final int RESULT_OI_PGN_LOAD = 5; + static private final int RESULT_GET_FEN = 6; @Override public boolean onOptionsItemSelected(MenuItem item) { @@ -1289,6 +1291,39 @@ public class DroidFish extends Activity implements GUIInterface { } } break; + case RESULT_GET_FEN: + if (resultCode == RESULT_OK) { + String fen = data.getStringExtra(Intent.EXTRA_TEXT); + if (fen == null) { + String pathName = getFilePathFromUri(data.getData()); + if (pathName != null) { + InputStream is = null; + try { + is = new FileInputStream(pathName); + fen = Util.readFromStream(is); + } catch (FileNotFoundException e) { + Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + } finally { + if (is != null) + try { is.close(); } catch (IOException e) {} + } + } + } + if (fen != null) { + try { + ctrl.setFENOrPGN(fen); + } catch (ChessParseError e) { + // If FEN corresponds to illegal chess position, go into edit board mode. + try { + TextIO.readFEN(fen); + } catch (ChessParseError e2) { + if (e2.pos != null) + startEditBoard(fen); + } + } + } + } + break; } } @@ -1302,7 +1337,7 @@ public class DroidFish extends Activity implements GUIInterface { ctrl.setGameMode(gameMode); } - private static String getFilePathFromUri(Uri uri) { + public static String getFilePathFromUri(Uri uri) { if (uri == null) return null; return uri.getPath(); @@ -1713,6 +1748,7 @@ public class DroidFish extends Activity implements GUIInterface { final int LOAD_GAME = 4; final int SAVE_GAME = 5; final int LOAD_SCID_GAME = 6; + final int GET_FEN = 7; List lst = new ArrayList(); List actions = new ArrayList(); @@ -1725,6 +1761,9 @@ public class DroidFish extends Activity implements GUIInterface { if (hasScidProvider()) { lst.add(getString(R.string.load_scid_game)); actions.add(LOAD_SCID_GAME); } + if (hasFenProvider(getPackageManager())) { + lst.add(getString(R.string.get_fen)); actions.add(GET_FEN); + } final List finalActions = actions; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.tools_menu); @@ -1769,6 +1808,9 @@ public class DroidFish extends Activity implements GUIInterface { case SAVE_GAME: selectPgnFile(true); break; + case GET_FEN: + getFen(); + break; } } }); @@ -1823,22 +1865,11 @@ public class DroidFish extends Activity implements GUIInterface { String title = getString(R.string.app_name); WebView wv = new WebView(this); builder.setView(wv); - String data = ""; - try { - InputStream is = getResources().openRawResource(R.raw.about); - InputStreamReader isr = new InputStreamReader(is, "UTF-8"); - BufferedReader br = new BufferedReader(isr); - StringBuilder sb = new StringBuilder(); - String line; - while ((line = br.readLine()) != null) { - sb.append(line); - sb.append('\n'); - } - br.close(); - data = sb.toString(); - } catch (UnsupportedEncodingException e1) { - } catch (IOException e) { - } + InputStream is = getResources().openRawResource(R.raw.about); + String data = Util.readFromStream(is); + if (data == null) + data = ""; + try { is.close(); } catch (IOException e1) {} wv.loadDataWithBaseURL(null, data, "text/html", "utf-8", null); try { PackageInfo pi = getPackageManager().getPackageInfo("org.petero.droidfish", 0); @@ -2823,6 +2854,23 @@ public class DroidFish extends Activity implements GUIInterface { } } + public final static boolean hasFenProvider(PackageManager manager) { + Intent i = new Intent(Intent.ACTION_GET_CONTENT); + i.setType("application/x-chess-fen"); + List resolvers = manager.queryIntentActivities(i, 0); + return (resolvers != null) && (resolvers.size() > 0); + } + + private final void getFen() { + Intent i = new Intent(Intent.ACTION_GET_CONTENT); + i.setType("application/x-chess-fen"); + try { + startActivityForResult(i, RESULT_GET_FEN); + } catch (ActivityNotFoundException e) { + Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + } + } + final static int FT_NONE = 0; final static int FT_PGN = 1; final static int FT_SCID = 2; diff --git a/DroidFish/src/org/petero/droidfish/Util.java b/DroidFish/src/org/petero/droidfish/Util.java index 8576ac9..ddb33df 100644 --- a/DroidFish/src/org/petero/droidfish/Util.java +++ b/DroidFish/src/org/petero/droidfish/Util.java @@ -5,6 +5,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import org.petero.droidfish.gamelogic.Piece; @@ -52,7 +53,28 @@ public final class Util { return ret.toArray(new String[ret.size()]); } - /** Represent materiel difference as two unicode strings. */ + /** Read all data from an input stream. Return null if IO error. */ + public static String readFromStream(InputStream is) { + InputStreamReader isr; + try { + isr = new InputStreamReader(is, "UTF-8"); + BufferedReader br = new BufferedReader(isr); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line); + sb.append('\n'); + } + br.close(); + return sb.toString(); + } catch (UnsupportedEncodingException e) { + return null; + } catch (IOException e) { + return null; + } + } + + /** Represent material difference as two unicode strings. */ public final static class MaterialDiff { public CharSequence white; public CharSequence black; diff --git a/DroidFish/src/org/petero/droidfish/activities/EditBoard.java b/DroidFish/src/org/petero/droidfish/activities/EditBoard.java index 2934766..31b20fa 100644 --- a/DroidFish/src/org/petero/droidfish/activities/EditBoard.java +++ b/DroidFish/src/org/petero/droidfish/activities/EditBoard.java @@ -18,9 +18,15 @@ package org.petero.droidfish.activities; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; +import java.util.List; import org.petero.droidfish.ChessBoard; +import org.petero.droidfish.DroidFish; import org.petero.droidfish.R; import org.petero.droidfish.ChessBoard.SquareDecoration; import org.petero.droidfish.Util; @@ -36,6 +42,7 @@ import org.petero.droidfish.gtb.Probe; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -364,31 +371,48 @@ public class EditBoard extends Activity { protected Dialog onCreateDialog(int id) { switch (id) { case EDIT_DIALOG: { - final CharSequence[] items = { - getString(R.string.side_to_move), - getString(R.string.clear_board), getString(R.string.initial_position), - getString(R.string.castling_flags), getString(R.string.en_passant_file), - getString(R.string.move_counters), - getString(R.string.copy_position), getString(R.string.paste_position) - }; + final int SIDE_TO_MOVE = 0; + final int CLEAR_BOARD = 1; + final int INITIAL_POS = 2; + final int CASTLING_FLAGS = 3; + final int EN_PASSANT_FILE = 4; + final int MOVE_COUNTERS = 5; + final int COPY_POSITION = 6; + final int PASTE_POSITION = 7; + final int GET_FEN = 8; + + List lst = new ArrayList(); + List actions = new ArrayList(); + lst.add(getString(R.string.side_to_move)); actions.add(SIDE_TO_MOVE); + lst.add(getString(R.string.clear_board)); actions.add(CLEAR_BOARD); + lst.add(getString(R.string.initial_position)); actions.add(INITIAL_POS); + lst.add(getString(R.string.castling_flags)); actions.add(CASTLING_FLAGS); + lst.add(getString(R.string.en_passant_file)); actions.add(EN_PASSANT_FILE); + lst.add(getString(R.string.move_counters)); actions.add(MOVE_COUNTERS); + lst.add(getString(R.string.copy_position)); actions.add(COPY_POSITION); + lst.add(getString(R.string.paste_position)); actions.add(PASTE_POSITION); + if (DroidFish.hasFenProvider(getPackageManager())) { + lst.add(getString(R.string.get_fen)); actions.add(GET_FEN); + } + final List finalActions = actions; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.edit_board); - builder.setItems(items, new DialogInterface.OnClickListener() { + builder.setItems(lst.toArray(new CharSequence[lst.size()]), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { - switch (item) { - case 0: // Edit side to move + switch (finalActions.get(item)) { + case SIDE_TO_MOVE: showDialog(SIDE_DIALOG); setSelection(-1); checkValidAndUpdateMaterialDiff(); break; - case 1: { // Clear board + case CLEAR_BOARD: { Position pos = new Position(); cb.setPosition(pos); setSelection(-1); checkValidAndUpdateMaterialDiff(); break; } - case 2: { // Set initial position + case INITIAL_POS: { try { Position pos = TextIO.readFEN(TextIO.startPosFEN); cb.setPosition(pos); @@ -398,25 +422,25 @@ public class EditBoard extends Activity { } break; } - case 3: // Edit castling flags + case CASTLING_FLAGS: removeDialog(CASTLE_DIALOG); showDialog(CASTLE_DIALOG); setSelection(-1); checkValidAndUpdateMaterialDiff(); break; - case 4: // Edit en passant file + case EN_PASSANT_FILE: removeDialog(EP_DIALOG); showDialog(EP_DIALOG); setSelection(-1); checkValidAndUpdateMaterialDiff(); break; - case 5: // Edit move counters + case MOVE_COUNTERS: removeDialog(MOVCNT_DIALOG); showDialog(MOVCNT_DIALOG); setSelection(-1); checkValidAndUpdateMaterialDiff(); break; - case 6: { // Copy position + case COPY_POSITION: { setPosFields(); String fen = TextIO.toFEN(cb.pos) + "\n"; ClipboardManager clipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE); @@ -424,23 +448,22 @@ public class EditBoard extends Activity { setSelection(-1); break; } - case 7: { // Paste position + case PASTE_POSITION: { ClipboardManager clipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE); if (clipboard.hasText()) { String fen = clipboard.getText().toString(); - try { - Position pos = TextIO.readFEN(fen); - cb.setPosition(pos); - } catch (ChessParseError e) { - if (e.pos != null) - cb.setPosition(e.pos); - Toast.makeText(getApplicationContext(), getParseErrString(e), Toast.LENGTH_SHORT).show(); - } - setSelection(-1); - checkValidAndUpdateMaterialDiff(); + setFEN(fen); } break; } + case GET_FEN: + Intent i = new Intent(Intent.ACTION_GET_CONTENT); + i.setType("application/x-chess-fen"); + try { + startActivityForResult(i, RESULT_GET_FEN); + } catch (ActivityNotFoundException e) { + Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + } } } }); @@ -566,4 +589,48 @@ public class EditBoard extends Activity { } return null; } + + private final void setFEN(String fen) { + if (fen == null) + return; + try { + Position pos = TextIO.readFEN(fen); + cb.setPosition(pos); + } catch (ChessParseError e) { + if (e.pos != null) + cb.setPosition(e.pos); + Toast.makeText(getApplicationContext(), getParseErrString(e), Toast.LENGTH_SHORT).show(); + } + setSelection(-1); + checkValidAndUpdateMaterialDiff(); + } + + static private final int RESULT_GET_FEN = 0; + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case RESULT_GET_FEN: + if (resultCode == RESULT_OK) { + String fen = data.getStringExtra(Intent.EXTRA_TEXT); + if (fen == null) { + String pathName = DroidFish.getFilePathFromUri(data.getData()); + if (pathName != null) { + InputStream is = null; + try { + is = new FileInputStream(pathName); + fen = Util.readFromStream(is); + } catch (FileNotFoundException e) { + Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + } finally { + if (is != null) + try { is.close(); } catch (IOException e) {} + } + } + } + setFEN(fen); + } + break; + } + } }