DroidFish: When receiving a fen file from an external program, let the user select which fen position to use.

This commit is contained in:
Peter Osterlund 2013-03-02 17:29:10 +00:00
parent 6a1186dca5
commit f72dd4f466
10 changed files with 709 additions and 130 deletions

View File

@ -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>

View 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>

View 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>

View File

@ -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">&lt;New File&gt;</string>
<string name="new_engine">&lt;New Engine&gt;</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>

View File

@ -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);

View File

@ -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++];
}
}

View File

@ -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;
}
}
}

View 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);
}
}

View 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();
}
}
}

View File

@ -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 = "";