diff --git a/DroidFish/AndroidManifest.xml b/DroidFish/AndroidManifest.xml
index e7d6672..be857bb 100644
--- a/DroidFish/AndroidManifest.xml
+++ b/DroidFish/AndroidManifest.xml
@@ -62,6 +62,10 @@
android:label="@string/load_scid_game_title"
android:configChanges="orientation">
+
+
diff --git a/DroidFish/res/layout-land/load_fen.xml b/DroidFish/res/layout-land/load_fen.xml
new file mode 100644
index 0000000..a85deb3
--- /dev/null
+++ b/DroidFish/res/layout-land/load_fen.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DroidFish/res/layout/load_fen.xml b/DroidFish/res/layout/load_fen.xml
new file mode 100644
index 0000000..4bc40d6
--- /dev/null
+++ b/DroidFish/res/layout/load_fen.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DroidFish/res/values/strings.xml b/DroidFish/res/values/strings.xml
index 027e240..0cb3afb 100644
--- a/DroidFish/res/values/strings.xml
+++ b/DroidFish/res/values/strings.xml
@@ -76,6 +76,7 @@ you are not actively using the program.\
Load
Save
Reading PGN file
+ Reading FEN file
Reading Scid file
<New File>
<New Engine>
@@ -111,6 +112,8 @@ you are not actively using the program.\
Load Next Game
No previous game
No next game
+ No previous position
+ No next position
Select Action
Flip Board
Blindfold mode
@@ -160,6 +163,7 @@ you are not actively using the program.\
Edit File / Save Game
Select an existing game to control where to save the game. Long press an existing game to delete it.
Load Scid Game
+ Load Position
CPU Warning
Failed to read PGN data
Var:
diff --git a/DroidFish/src/org/petero/droidfish/DroidFish.java b/DroidFish/src/org/petero/droidfish/DroidFish.java
index 7651895..6b59b44 100644
--- a/DroidFish/src/org/petero/droidfish/DroidFish.java
+++ b/DroidFish/src/org/petero/droidfish/DroidFish.java
@@ -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);
diff --git a/DroidFish/src/org/petero/droidfish/activities/BufferedRandomAccessFileReader.java b/DroidFish/src/org/petero/droidfish/activities/BufferedRandomAccessFileReader.java
new file mode 100644
index 0000000..0ba8243
--- /dev/null
+++ b/DroidFish/src/org/petero/droidfish/activities/BufferedRandomAccessFileReader.java
@@ -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 .
+*/
+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++];
+ }
+}
diff --git a/DroidFish/src/org/petero/droidfish/activities/EditBoard.java b/DroidFish/src/org/petero/droidfish/activities/EditBoard.java
index 31b20fa..bb162c6 100644
--- a/DroidFish/src/org/petero/droidfish/activities/EditBoard.java
+++ b/DroidFish/src/org/petero/droidfish/activities/EditBoard.java
@@ -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;
}
}
}
diff --git a/DroidFish/src/org/petero/droidfish/activities/FENFile.java b/DroidFish/src/org/petero/droidfish/activities/FENFile.java
new file mode 100644
index 0000000..e026afa
--- /dev/null
+++ b/DroidFish/src/org/petero/droidfish/activities/FENFile.java
@@ -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 .
+*/
+
+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> getFenInfo(Activity activity,
+ final ProgressDialog progress) {
+ ArrayList fensInFile = new ArrayList();
+ 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.CANCEL, null);
+ }
+ f.close();
+ } catch (IOException e) {
+ } catch (OutOfMemoryError e) {
+ fensInFile.clear();
+ fensInFile = null;
+ return new Pair>(FenInfoResult.OUT_OF_MEMORY, null);
+ }
+ return new Pair>(FenInfoResult.OK, fensInFile);
+ }
+}
diff --git a/DroidFish/src/org/petero/droidfish/activities/LoadFEN.java b/DroidFish/src/org/petero/droidfish/activities/LoadFEN.java
new file mode 100644
index 0000000..f0e8f89
--- /dev/null
+++ b/DroidFish/src/org/petero/droidfish/activities/LoadFEN.java
@@ -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 .
+*/
+
+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 fensInFile = new ArrayList();
+ private static boolean cacheValid = false;
+ private FENFile fenFile;
+ private ProgressDialog progress;
+ private FenInfo selectedFi = null;
+ private ArrayAdapter 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(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> p = fenFile.getFenInfo(this, progress);
+ if (p.first != FenInfoResult.OK) {
+ fensInFile = new ArrayList();
+ 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();
+ }
+ }
+}
diff --git a/DroidFish/src/org/petero/droidfish/activities/PGNFile.java b/DroidFish/src/org/petero/droidfish/activities/PGNFile.java
index 846593f..afe064f 100644
--- a/DroidFish/src/org/petero/droidfish/activities/PGNFile.java
+++ b/DroidFish/src/org/petero/droidfish/activities/PGNFile.java
@@ -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 = "";