mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-01-30 17:13:50 +01:00
DroidFish: When receiving a fen file from an external program, let the user select which fen position to use.
This commit is contained in:
parent
6a1186dca5
commit
f72dd4f466
|
@ -62,6 +62,10 @@
|
|||
android:label="@string/load_scid_game_title"
|
||||
android:configChanges="orientation">
|
||||
</activity>
|
||||
<activity android:name=".activities.LoadFEN"
|
||||
android:label="@string/load_fen_title"
|
||||
android:configChanges="orientation">
|
||||
</activity>
|
||||
<activity android:name=".activities.CPUWarning"
|
||||
android:label="@string/cpu_warning_title">
|
||||
</activity>
|
||||
|
|
53
DroidFish/res/layout-land/load_fen.xml
Normal file
53
DroidFish/res/layout-land/load_fen.xml
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="horizontal">
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:focusable="false">
|
||||
</ListView>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="2"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false">
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<view
|
||||
class="org.petero.droidfish.ChessBoardPlay"
|
||||
android:id="@+id/loadfen_chessboard"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</view>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<Button
|
||||
android:id="@+id/loadfen_ok"
|
||||
android:text="@android:string/ok"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</Button>
|
||||
<Button
|
||||
android:id="@+id/loadfen_cancel"
|
||||
android:text="@string/cancel"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</Button>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
49
DroidFish/res/layout/load_fen.xml
Normal file
49
DroidFish/res/layout/load_fen.xml
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false">
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<view
|
||||
class="org.petero.droidfish.ChessBoardPlay"
|
||||
android:id="@+id/loadfen_chessboard"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</view>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<Button
|
||||
android:text="@android:string/ok"
|
||||
android:id="@+id/loadfen_ok"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
</Button>
|
||||
<Button
|
||||
android:id="@+id/loadfen_cancel"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel">
|
||||
</Button>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:focusable="false">
|
||||
</ListView>
|
||||
</LinearLayout>
|
|
@ -76,6 +76,7 @@ you are not actively using the program.\
|
|||
<string name="pgn_load">Load</string>
|
||||
<string name="pgn_save">Save</string>
|
||||
<string name="reading_pgn_file">Reading PGN file</string>
|
||||
<string name="reading_fen_file">Reading FEN file</string>
|
||||
<string name="reading_scid_file">Reading Scid file</string>
|
||||
<string name="new_file"><New File></string>
|
||||
<string name="new_engine"><New Engine></string>
|
||||
|
@ -111,6 +112,8 @@ you are not actively using the program.\
|
|||
<string name="load_next_game">Load Next Game</string>
|
||||
<string name="no_prev_game">No previous game</string>
|
||||
<string name="no_next_game">No next game</string>
|
||||
<string name="no_prev_fen">No previous position</string>
|
||||
<string name="no_next_fen">No next position</string>
|
||||
<string name="select_action">Select Action</string>
|
||||
<string name="flip_board">Flip Board</string>
|
||||
<string name="blind_mode">Blindfold mode</string>
|
||||
|
@ -160,6 +163,7 @@ you are not actively using the program.\
|
|||
<string name="save_game_title">Edit File / Save Game</string>
|
||||
<string name="save_game_hint">Select an existing game to control where to save the game. Long press an existing game to delete it.</string>
|
||||
<string name="load_scid_game_title">Load Scid Game</string>
|
||||
<string name="load_fen_title">Load Position</string>
|
||||
<string name="cpu_warning_title">CPU Warning</string>
|
||||
<string name="failed_to_read_pgn_data">Failed to read PGN data</string>
|
||||
<string name="variation">Var:</string>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
DroidFish - An Android chess program.
|
||||
Copyright (C) 2011-2012 Peter Österlund, peterosterlund2@gmail.com
|
||||
Copyright (C) 2011-2013 Peter Österlund, peterosterlund2@gmail.com
|
||||
Copyright (C) 2012 Leo Mayer
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -22,7 +22,6 @@ package org.petero.droidfish;
|
|||
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;
|
||||
|
@ -40,6 +39,7 @@ import org.petero.droidfish.activities.CPUWarning;
|
|||
import org.petero.droidfish.activities.EditBoard;
|
||||
import org.petero.droidfish.activities.EditPGNLoad;
|
||||
import org.petero.droidfish.activities.EditPGNSave;
|
||||
import org.petero.droidfish.activities.LoadFEN;
|
||||
import org.petero.droidfish.activities.LoadScid;
|
||||
import org.petero.droidfish.activities.Preferences;
|
||||
import org.petero.droidfish.book.BookOptions;
|
||||
|
@ -1161,6 +1161,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
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;
|
||||
static private final int RESULT_LOAD_FEN = 7;
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
@ -1296,32 +1297,15 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
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);
|
||||
}
|
||||
}
|
||||
loadFENFromFile(pathName);
|
||||
}
|
||||
setFenHelper(fen);
|
||||
}
|
||||
break;
|
||||
case RESULT_LOAD_FEN:
|
||||
if (resultCode == RESULT_OK) {
|
||||
String fen = data.getAction();
|
||||
setFenHelper(fen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2439,12 +2423,18 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
i = new Intent(DroidFish.this, EditPGNLoad.class);
|
||||
i.setAction("org.petero.droidfish.loadFilePrevGame");
|
||||
i.putExtra("org.petero.droidfish.pathname", currPathName);
|
||||
} else {
|
||||
startActivityForResult(i, RESULT_LOAD_PGN);
|
||||
} else if (currFT == FT_SCID) {
|
||||
i = new Intent(DroidFish.this, LoadScid.class);
|
||||
i.setAction("org.petero.droidfish.loadScidPrevGame");
|
||||
i.putExtra("org.petero.droidfish.pathname", currPathName);
|
||||
startActivityForResult(i, RESULT_LOAD_PGN);
|
||||
} else if (currFT == FT_FEN) {
|
||||
i = new Intent(DroidFish.this, LoadFEN.class);
|
||||
i.setAction("org.petero.droidfish.loadPrevFen");
|
||||
i.putExtra("org.petero.droidfish.pathname", currPathName);
|
||||
startActivityForResult(i, RESULT_LOAD_FEN);
|
||||
}
|
||||
startActivityForResult(i, RESULT_LOAD_PGN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2483,12 +2473,18 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
i = new Intent(DroidFish.this, EditPGNLoad.class);
|
||||
i.setAction("org.petero.droidfish.loadFileNextGame");
|
||||
i.putExtra("org.petero.droidfish.pathname", currPathName);
|
||||
} else {
|
||||
startActivityForResult(i, RESULT_LOAD_PGN);
|
||||
} else if (currFT == FT_SCID) {
|
||||
i = new Intent(DroidFish.this, LoadScid.class);
|
||||
i.setAction("org.petero.droidfish.loadScidNextGame");
|
||||
i.putExtra("org.petero.droidfish.pathname", currPathName);
|
||||
startActivityForResult(i, RESULT_LOAD_PGN);
|
||||
} else if (currFT == FT_FEN) {
|
||||
i = new Intent(DroidFish.this, LoadFEN.class);
|
||||
i.setAction("org.petero.droidfish.loadNextFen");
|
||||
i.putExtra("org.petero.droidfish.pathname", currPathName);
|
||||
startActivityForResult(i, RESULT_LOAD_FEN);
|
||||
}
|
||||
startActivityForResult(i, RESULT_LOAD_PGN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2874,6 +2870,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
final static int FT_NONE = 0;
|
||||
final static int FT_PGN = 1;
|
||||
final static int FT_SCID = 2;
|
||||
final static int FT_FEN = 3;
|
||||
|
||||
private final int currFileType() {
|
||||
if (gameMode.clocksActive())
|
||||
|
@ -2895,6 +2892,8 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
}
|
||||
case FT_SCID:
|
||||
return settings.getString("currentScidFile", "");
|
||||
case FT_FEN:
|
||||
return settings.getString("currentFENFile", "");
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
@ -2952,6 +2951,36 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
startActivityForResult(i, RESULT_LOAD_PGN);
|
||||
}
|
||||
|
||||
/** Load a FEN position from a file. */
|
||||
private final void loadFENFromFile(String pathName) {
|
||||
if (pathName == null)
|
||||
return;
|
||||
Editor editor = settings.edit();
|
||||
editor.putString("currentFENFile", pathName);
|
||||
editor.putInt("currFT", FT_FEN);
|
||||
editor.commit();
|
||||
Intent i = new Intent(DroidFish.this, LoadFEN.class);
|
||||
i.setAction("org.petero.droidfish.loadFen");
|
||||
i.putExtra("org.petero.droidfish.pathname", pathName);
|
||||
startActivityForResult(i, RESULT_LOAD_FEN);
|
||||
}
|
||||
|
||||
private final void setFenHelper(String fen) {
|
||||
if (fen == null)
|
||||
return;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestPromotePiece() {
|
||||
showDialog(PROMOTE_DIALOG);
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
DroidFish - An Android chess program.
|
||||
Copyright (C) 2011-2013 Peter Österlund, peterosterlund2@gmail.com
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.petero.droidfish.activities;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
final class BufferedRandomAccessFileReader {
|
||||
RandomAccessFile f;
|
||||
byte[] buffer = new byte[8192];
|
||||
long bufStartFilePos = 0;
|
||||
int bufLen = 0;
|
||||
int bufPos = 0;
|
||||
|
||||
BufferedRandomAccessFileReader(String fileName) throws FileNotFoundException {
|
||||
f = new RandomAccessFile(fileName, "r");
|
||||
}
|
||||
final long length() throws IOException {
|
||||
return f.length();
|
||||
}
|
||||
final long getFilePointer() throws IOException {
|
||||
return bufStartFilePos + bufPos;
|
||||
}
|
||||
final void close() throws IOException {
|
||||
f.close();
|
||||
}
|
||||
|
||||
private final static int EOF = -1024;
|
||||
|
||||
final String readLine() throws IOException {
|
||||
// First handle the common case where the next line is entirely
|
||||
// contained in the buffer
|
||||
for (int i = bufPos; i < bufLen; i++) {
|
||||
byte b = buffer[i];
|
||||
if ((b == '\n') || (b == '\r')) {
|
||||
String line = new String(buffer, bufPos, i - bufPos);
|
||||
for ( ; i < bufLen; i++) {
|
||||
b = buffer[i];
|
||||
if ((b != '\n') && (b != '\r')) {
|
||||
bufPos = i;
|
||||
return line;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Generic case
|
||||
byte[] lineBuf = new byte[8192];
|
||||
int lineLen = 0;
|
||||
int b;
|
||||
while (true) {
|
||||
b = getByte();
|
||||
if (b == '\n' || b == '\r' || b == EOF)
|
||||
break;
|
||||
lineBuf[lineLen++] = (byte)b;
|
||||
if (lineLen >= lineBuf.length)
|
||||
break;
|
||||
}
|
||||
while (true) {
|
||||
b = getByte();
|
||||
if ((b != '\n') && (b != '\r')) {
|
||||
if (b != EOF)
|
||||
bufPos--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((b == EOF) && (lineLen == 0))
|
||||
return null;
|
||||
else
|
||||
return new String(lineBuf, 0, lineLen);
|
||||
}
|
||||
|
||||
private final int getByte() throws IOException {
|
||||
if (bufPos >= bufLen) {
|
||||
bufStartFilePos = f.getFilePointer();
|
||||
bufLen = f.read(buffer);
|
||||
bufPos = 0;
|
||||
if (bufLen <= 0)
|
||||
return EOF;
|
||||
}
|
||||
return buffer[bufPos++];
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
DroidFish - An Android chess program.
|
||||
Copyright (C) 2011 Peter Österlund, peterosterlund2@gmail.com
|
||||
Copyright (C) 2011-2013 Peter Österlund, peterosterlund2@gmail.com
|
||||
|
||||
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
|
||||
|
@ -18,10 +18,6 @@
|
|||
|
||||
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;
|
||||
|
||||
|
@ -605,7 +601,8 @@ public class EditBoard extends Activity {
|
|||
checkValidAndUpdateMaterialDiff();
|
||||
}
|
||||
|
||||
static private final int RESULT_GET_FEN = 0;
|
||||
static private final int RESULT_GET_FEN = 0;
|
||||
static private final int RESULT_LOAD_FEN = 1;
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
|
@ -615,22 +612,20 @@ public class EditBoard extends Activity {
|
|||
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) {}
|
||||
}
|
||||
}
|
||||
Intent i = new Intent(EditBoard.this, LoadFEN.class);
|
||||
i.setAction("org.petero.droidfish.loadFen");
|
||||
i.putExtra("org.petero.droidfish.pathname", pathName);
|
||||
startActivityForResult(i, RESULT_LOAD_FEN);
|
||||
}
|
||||
setFEN(fen);
|
||||
}
|
||||
break;
|
||||
case RESULT_LOAD_FEN:
|
||||
if (resultCode == RESULT_OK) {
|
||||
String fen = data.getAction();
|
||||
setFEN(fen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
108
DroidFish/src/org/petero/droidfish/activities/FENFile.java
Normal file
108
DroidFish/src/org/petero/droidfish/activities/FENFile.java
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
DroidFish - An Android chess program.
|
||||
Copyright (C) 2013 Peter Österlund, peterosterlund2@gmail.com
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.petero.droidfish.activities;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.petero.droidfish.gamelogic.Pair;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
|
||||
public class FENFile {
|
||||
private final File fileName;
|
||||
|
||||
public FENFile(String fileName) {
|
||||
this.fileName = new File(fileName);
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return fileName.getAbsolutePath();
|
||||
}
|
||||
|
||||
static final class FenInfo {
|
||||
int gameNo;
|
||||
String fen;
|
||||
|
||||
FenInfo(int gameNo, String fen) {
|
||||
this.gameNo = gameNo;
|
||||
this.fen = fen;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder info = new StringBuilder(128);
|
||||
info.append(gameNo);
|
||||
info.append(". ");
|
||||
info.append(fen);
|
||||
return info.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static enum FenInfoResult {
|
||||
OK,
|
||||
CANCEL,
|
||||
OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/** Read all FEN strings (one per line) in a file. */
|
||||
public final Pair<FenInfoResult,ArrayList<FenInfo>> getFenInfo(Activity activity,
|
||||
final ProgressDialog progress) {
|
||||
ArrayList<FenInfo> fensInFile = new ArrayList<FenInfo>();
|
||||
try {
|
||||
int percent = -1;
|
||||
fensInFile.clear();
|
||||
BufferedRandomAccessFileReader f = new BufferedRandomAccessFileReader(fileName.getAbsolutePath());
|
||||
long fileLen = f.length();
|
||||
long filePos = 0;
|
||||
int fenNo = 1;
|
||||
while (true) {
|
||||
filePos = f.getFilePointer();
|
||||
String line = f.readLine();
|
||||
if (line == null)
|
||||
break; // EOF
|
||||
if ((line.length() == 0) || (line.charAt(0) == '#'))
|
||||
continue;
|
||||
FenInfo fi = new FenInfo(fenNo++, line.trim());
|
||||
fensInFile.add(fi);
|
||||
final int newPercent = (int)(filePos * 100 / fileLen);
|
||||
if (newPercent > percent) {
|
||||
percent = newPercent;
|
||||
if (progress != null) {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
progress.setProgress(newPercent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (Thread.currentThread().isInterrupted())
|
||||
return new Pair<FenInfoResult,ArrayList<FenInfo>>(FenInfoResult.CANCEL, null);
|
||||
}
|
||||
f.close();
|
||||
} catch (IOException e) {
|
||||
} catch (OutOfMemoryError e) {
|
||||
fensInFile.clear();
|
||||
fensInFile = null;
|
||||
return new Pair<FenInfoResult,ArrayList<FenInfo>>(FenInfoResult.OUT_OF_MEMORY, null);
|
||||
}
|
||||
return new Pair<FenInfoResult,ArrayList<FenInfo>>(FenInfoResult.OK, fensInFile);
|
||||
}
|
||||
}
|
317
DroidFish/src/org/petero/droidfish/activities/LoadFEN.java
Normal file
317
DroidFish/src/org/petero/droidfish/activities/LoadFEN.java
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
DroidFish - An Android chess program.
|
||||
Copyright (C) 2013 Peter Österlund, peterosterlund2@gmail.com
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.petero.droidfish.activities;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.petero.droidfish.ChessBoardPlay;
|
||||
import org.petero.droidfish.ColorTheme;
|
||||
import org.petero.droidfish.R;
|
||||
import org.petero.droidfish.Util;
|
||||
import org.petero.droidfish.activities.FENFile.FenInfo;
|
||||
import org.petero.droidfish.activities.FENFile.FenInfoResult;
|
||||
import org.petero.droidfish.gamelogic.ChessParseError;
|
||||
import org.petero.droidfish.gamelogic.Pair;
|
||||
import org.petero.droidfish.gamelogic.Position;
|
||||
import org.petero.droidfish.gamelogic.TextIO;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.ListActivity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.DialogInterface.OnCancelListener;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
|
||||
public class LoadFEN extends ListActivity {
|
||||
private static ArrayList<FenInfo> fensInFile = new ArrayList<FenInfo>();
|
||||
private static boolean cacheValid = false;
|
||||
private FENFile fenFile;
|
||||
private ProgressDialog progress;
|
||||
private FenInfo selectedFi = null;
|
||||
private ArrayAdapter<FenInfo> aa = null;
|
||||
|
||||
private SharedPreferences settings;
|
||||
private int defaultItem = 0;
|
||||
private String lastFileName = "";
|
||||
private long lastModTime = -1;
|
||||
|
||||
private Thread workThread = null;
|
||||
|
||||
private ChessBoardPlay cb;
|
||||
private Button okButton;
|
||||
private Button cancelButton;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
settings = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
Util.setFullScreenMode(this, settings);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
defaultItem = savedInstanceState.getInt("defaultItem");
|
||||
lastFileName = savedInstanceState.getString("lastFenFileName");
|
||||
if (lastFileName == null) lastFileName = "";
|
||||
lastModTime = savedInstanceState.getLong("lastFenModTime");
|
||||
} else {
|
||||
defaultItem = settings.getInt("defaultItem", 0);
|
||||
lastFileName = settings.getString("lastFenFileName", "");
|
||||
lastModTime = settings.getLong("lastFenModTime", 0);
|
||||
}
|
||||
|
||||
Intent i = getIntent();
|
||||
String action = i.getAction();
|
||||
String fileName = i.getStringExtra("org.petero.droidfish.pathname");
|
||||
if (action.equals("org.petero.droidfish.loadFen")) {
|
||||
fenFile = new FENFile(fileName);
|
||||
showDialog(PROGRESS_DIALOG);
|
||||
final LoadFEN lfen = this;
|
||||
workThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
if (!readFile())
|
||||
return;
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
lfen.showList();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
workThread.start();
|
||||
} else if (action.equals("org.petero.droidfish.loadNextFen") ||
|
||||
action.equals("org.petero.droidfish.loadPrevFen")) {
|
||||
fenFile = new FENFile(fileName);
|
||||
boolean next = action.equals("org.petero.droidfish.loadNextFen");
|
||||
final int loadItem = defaultItem + (next ? 1 : -1);
|
||||
if (loadItem < 0) {
|
||||
Toast.makeText(getApplicationContext(), R.string.no_prev_fen,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
} else {
|
||||
workThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
if (!readFile())
|
||||
return;
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (loadItem >= fensInFile.size()) {
|
||||
Toast.makeText(getApplicationContext(), R.string.no_next_fen,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
} else {
|
||||
defaultItem = loadItem;
|
||||
sendBackResult(fensInFile.get(loadItem));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
workThread.start();
|
||||
}
|
||||
} else { // Unsupported action
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt("defaultItem", defaultItem);
|
||||
outState.putString("lastFenFileName", lastFileName);
|
||||
outState.putLong("lastFenModTime", lastModTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
Editor editor = settings.edit();
|
||||
editor.putInt("defaultItem", defaultItem);
|
||||
editor.putString("lastFenFileName", lastFileName);
|
||||
editor.putLong("lastFenModTime", lastModTime);
|
||||
editor.commit();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (workThread != null) {
|
||||
workThread.interrupt();
|
||||
try {
|
||||
workThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
workThread = null;
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private final void showList() {
|
||||
progress.dismiss();
|
||||
setContentView(R.layout.load_fen);
|
||||
|
||||
cb = (ChessBoardPlay)findViewById(R.id.loadfen_chessboard);
|
||||
okButton = (Button)findViewById(R.id.loadfen_ok);
|
||||
cancelButton = (Button)findViewById(R.id.loadfen_cancel);
|
||||
|
||||
okButton.setEnabled(false);
|
||||
okButton.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (selectedFi != null)
|
||||
sendBackResult(selectedFi);
|
||||
}
|
||||
});
|
||||
cancelButton.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
Util.overrideFonts(findViewById(android.R.id.content));
|
||||
aa = new ArrayAdapter<FenInfo>(this, R.layout.select_game_list_item, fensInFile) {
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view = super.getView(position, convertView, parent);
|
||||
if (view instanceof TextView) {
|
||||
int fg = ColorTheme.instance().getColor(ColorTheme.FONT_FOREGROUND);
|
||||
((TextView) view).setTextColor(fg);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
};
|
||||
setListAdapter(aa);
|
||||
final ListView lv = getListView();
|
||||
lv.setSelectionFromTop(defaultItem, 0);
|
||||
lv.setFastScrollEnabled(true);
|
||||
lv.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
|
||||
selectedFi = aa.getItem(pos);
|
||||
if (selectedFi == null)
|
||||
return;
|
||||
defaultItem = pos;
|
||||
Position chessPos;
|
||||
try {
|
||||
chessPos = TextIO.readFEN(selectedFi.fen);
|
||||
} catch (ChessParseError e2) {
|
||||
chessPos = e2.pos;
|
||||
}
|
||||
if (chessPos != null) {
|
||||
cb.setPosition(chessPos);
|
||||
okButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
lv.requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
Position pos = cb.pos;
|
||||
showList();
|
||||
cb.setPosition(pos);
|
||||
okButton.setEnabled(selectedFi != null);
|
||||
}
|
||||
|
||||
final static int PROGRESS_DIALOG = 0;
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
case PROGRESS_DIALOG:
|
||||
progress = new ProgressDialog(this);
|
||||
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
progress.setTitle(R.string.reading_fen_file);
|
||||
progress.setMessage(getString(R.string.please_wait));
|
||||
progress.setOnCancelListener(new OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
Thread thr = workThread;
|
||||
if (thr != null)
|
||||
thr.interrupt();
|
||||
}
|
||||
});
|
||||
return progress;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean readFile() {
|
||||
String fileName = fenFile.getName();
|
||||
if (!fileName.equals(lastFileName))
|
||||
defaultItem = 0;
|
||||
long modTime = new File(fileName).lastModified();
|
||||
if (cacheValid && (modTime == lastModTime) && fileName.equals(lastFileName))
|
||||
return true;
|
||||
fenFile = new FENFile(fileName);
|
||||
Pair<FenInfoResult, ArrayList<FenInfo>> p = fenFile.getFenInfo(this, progress);
|
||||
if (p.first != FenInfoResult.OK) {
|
||||
fensInFile = new ArrayList<FenInfo>();
|
||||
switch (p.first) {
|
||||
case OUT_OF_MEMORY:
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
Toast.makeText(getApplicationContext(), R.string.file_too_large,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return false;
|
||||
}
|
||||
fensInFile = p.second;
|
||||
cacheValid = true;
|
||||
lastModTime = modTime;
|
||||
lastFileName = fileName;
|
||||
return true;
|
||||
}
|
||||
|
||||
private final void sendBackResult(FenInfo fi) {
|
||||
String fen = fi.fen;
|
||||
if (fen != null) {
|
||||
setResult(RESULT_OK, (new Intent()).setAction(fen));
|
||||
finish();
|
||||
} else {
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
DroidFish - An Android chess program.
|
||||
Copyright (C) 2011 Peter Österlund, peterosterlund2@gmail.com
|
||||
Copyright (C) 2011-2013 Peter Österlund, peterosterlund2@gmail.com
|
||||
|
||||
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
|
||||
|
@ -19,7 +19,6 @@
|
|||
package org.petero.droidfish.activities;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
@ -65,85 +64,6 @@ public class PGNFile {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static private final class BufferedRandomAccessFileReader {
|
||||
RandomAccessFile f;
|
||||
byte[] buffer = new byte[8192];
|
||||
long bufStartFilePos = 0;
|
||||
int bufLen = 0;
|
||||
int bufPos = 0;
|
||||
|
||||
BufferedRandomAccessFileReader(String fileName) throws FileNotFoundException {
|
||||
f = new RandomAccessFile(fileName, "r");
|
||||
}
|
||||
final long length() throws IOException {
|
||||
return f.length();
|
||||
}
|
||||
final long getFilePointer() throws IOException {
|
||||
return bufStartFilePos + bufPos;
|
||||
}
|
||||
final void close() throws IOException {
|
||||
f.close();
|
||||
}
|
||||
|
||||
private final static int EOF = -1024;
|
||||
|
||||
final String readLine() throws IOException {
|
||||
// First handle the common case where the next line is entirely
|
||||
// contained in the buffer
|
||||
for (int i = bufPos; i < bufLen; i++) {
|
||||
byte b = buffer[i];
|
||||
if ((b == '\n') || (b == '\r')) {
|
||||
String line = new String(buffer, bufPos, i - bufPos);
|
||||
for ( ; i < bufLen; i++) {
|
||||
b = buffer[i];
|
||||
if ((b != '\n') && (b != '\r')) {
|
||||
bufPos = i;
|
||||
return line;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Generic case
|
||||
byte[] lineBuf = new byte[8192];
|
||||
int lineLen = 0;
|
||||
int b;
|
||||
while (true) {
|
||||
b = getByte();
|
||||
if (b == '\n' || b == '\r' || b == EOF)
|
||||
break;
|
||||
lineBuf[lineLen++] = (byte)b;
|
||||
if (lineLen >= lineBuf.length)
|
||||
break;
|
||||
}
|
||||
while (true) {
|
||||
b = getByte();
|
||||
if ((b != '\n') && (b != '\r')) {
|
||||
if (b != EOF)
|
||||
bufPos--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((b == EOF) && (lineLen == 0))
|
||||
return null;
|
||||
else
|
||||
return new String(lineBuf, 0, lineLen);
|
||||
}
|
||||
|
||||
private final int getByte() throws IOException {
|
||||
if (bufPos >= bufLen) {
|
||||
bufStartFilePos = f.getFilePointer();
|
||||
bufLen = f.read(buffer);
|
||||
bufPos = 0;
|
||||
if (bufLen <= 0)
|
||||
return EOF;
|
||||
}
|
||||
return buffer[bufPos++];
|
||||
}
|
||||
}
|
||||
|
||||
private final static class HeaderInfo {
|
||||
int gameNo;
|
||||
String event = "";
|
||||
|
|
Loading…
Reference in New Issue
Block a user