mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2024-11-23 11:31:33 +01:00
Support regular expression search in game load/save activity
Standard Java regular expression syntax is supported. The search is case insensitive.
This commit is contained in:
parent
15b62e9bc2
commit
fbb2091d45
|
@ -72,6 +72,7 @@ public abstract class EditPGN extends AppCompatActivity {
|
||||||
private String lastSearchString = "";
|
private String lastSearchString = "";
|
||||||
private String lastFileName = "";
|
private String lastFileName = "";
|
||||||
private long lastModTime = -1;
|
private long lastModTime = -1;
|
||||||
|
private boolean useRegExp = false;
|
||||||
|
|
||||||
private Thread workThread = null;
|
private Thread workThread = null;
|
||||||
private boolean canceled = false;
|
private boolean canceled = false;
|
||||||
|
@ -95,11 +96,13 @@ public abstract class EditPGN extends AppCompatActivity {
|
||||||
lastFileName = savedInstanceState.getString("lastFileName");
|
lastFileName = savedInstanceState.getString("lastFileName");
|
||||||
if (lastFileName == null) lastFileName = "";
|
if (lastFileName == null) lastFileName = "";
|
||||||
lastModTime = savedInstanceState.getLong("lastModTime");
|
lastModTime = savedInstanceState.getLong("lastModTime");
|
||||||
|
useRegExp = savedInstanceState.getBoolean("useRegExpSearch");
|
||||||
} else {
|
} else {
|
||||||
defaultFilePos = settings.getLong("defaultFilePos", 0);
|
defaultFilePos = settings.getLong("defaultFilePos", 0);
|
||||||
lastSearchString = settings.getString("lastSearchString", "");
|
lastSearchString = settings.getString("lastSearchString", "");
|
||||||
lastFileName = settings.getString("lastFileName", "");
|
lastFileName = settings.getString("lastFileName", "");
|
||||||
lastModTime = settings.getLong("lastModTime", 0);
|
lastModTime = settings.getLong("lastModTime", 0);
|
||||||
|
useRegExp = settings.getBoolean("useRegExpSearch", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Intent i = getIntent();
|
Intent i = getIntent();
|
||||||
|
@ -131,14 +134,14 @@ public abstract class EditPGN extends AppCompatActivity {
|
||||||
workThread = new Thread(() -> {
|
workThread = new Thread(() -> {
|
||||||
if (!readFile())
|
if (!readFile())
|
||||||
return;
|
return;
|
||||||
|
GameAdapter.ItemMatcher<GameInfo> m =
|
||||||
|
GameAdapter.getItemMatcher(lastSearchString, useRegExp);
|
||||||
int itemNo = getItemNo(gamesInFile, defaultFilePos) + (next ? 1 : -1);
|
int itemNo = getItemNo(gamesInFile, defaultFilePos) + (next ? 1 : -1);
|
||||||
if (next) {
|
if (next) {
|
||||||
while (itemNo < gamesInFile.size() &&
|
while (itemNo < gamesInFile.size() && !m.matches(gamesInFile.get(itemNo)))
|
||||||
!GameAdapter.matchItem(gamesInFile.get(itemNo), lastSearchString))
|
|
||||||
itemNo++;
|
itemNo++;
|
||||||
} else {
|
} else {
|
||||||
while (itemNo >= 0 &&
|
while (itemNo >= 0 && !m.matches(gamesInFile.get(itemNo)))
|
||||||
!GameAdapter.matchItem(gamesInFile.get(itemNo), lastSearchString))
|
|
||||||
itemNo--;
|
itemNo--;
|
||||||
}
|
}
|
||||||
final int loadItem = itemNo;
|
final int loadItem = itemNo;
|
||||||
|
@ -205,6 +208,7 @@ public abstract class EditPGN extends AppCompatActivity {
|
||||||
outState.putString("lastSearchString", lastSearchString);
|
outState.putString("lastSearchString", lastSearchString);
|
||||||
outState.putString("lastFileName", lastFileName);
|
outState.putString("lastFileName", lastFileName);
|
||||||
outState.putLong("lastModTime", lastModTime);
|
outState.putLong("lastModTime", lastModTime);
|
||||||
|
outState.putBoolean("useRegExpSearch", useRegExp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -214,6 +218,7 @@ public abstract class EditPGN extends AppCompatActivity {
|
||||||
editor.putString("lastSearchString", lastSearchString);
|
editor.putString("lastSearchString", lastSearchString);
|
||||||
editor.putString("lastFileName", lastFileName);
|
editor.putString("lastFileName", lastFileName);
|
||||||
editor.putLong("lastModTime", lastModTime);
|
editor.putLong("lastModTime", lastModTime);
|
||||||
|
editor.putBoolean("useRegExpSearch", useRegExp);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
@ -234,6 +239,8 @@ public abstract class EditPGN extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.edit_file_options_menu, menu);
|
getMenuInflater().inflate(R.menu.edit_file_options_menu, menu);
|
||||||
|
MenuItem item = menu.findItem(R.id.regexp_search);
|
||||||
|
item.setChecked(useRegExp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,6 +250,14 @@ public abstract class EditPGN extends AppCompatActivity {
|
||||||
case R.id.item_delete_file:
|
case R.id.item_delete_file:
|
||||||
reShowDialog(DELETE_PGN_FILE_DIALOG);
|
reShowDialog(DELETE_PGN_FILE_DIALOG);
|
||||||
break;
|
break;
|
||||||
|
case R.id.regexp_search:
|
||||||
|
useRegExp = !useRegExp;
|
||||||
|
item.setChecked(useRegExp);
|
||||||
|
if (binding != null) {
|
||||||
|
String s = binding.selectGameFilter.getText().toString();
|
||||||
|
setFilterString(s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -480,17 +495,20 @@ public abstract class EditPGN extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFilterString(String s) {
|
private void setFilterString(String s) {
|
||||||
|
boolean regExp = useRegExp;
|
||||||
Filter.FilterListener listener = (count) -> {
|
Filter.FilterListener listener = (count) -> {
|
||||||
ArrayList<GameInfo> arr = aa.getValues();
|
ArrayList<GameInfo> arr = aa.getValues();
|
||||||
int itemNo = getItemNo(arr, currentFilePos);
|
int itemNo = getItemNo(arr, currentFilePos);
|
||||||
if (itemNo < 0)
|
if (itemNo < 0)
|
||||||
itemNo = 0;
|
itemNo = 0;
|
||||||
while (itemNo < arr.size() &&
|
GameAdapter.ItemMatcher<GameInfo> m =
|
||||||
!GameAdapter.matchItem(arr.get(itemNo), lastSearchString))
|
GameAdapter.getItemMatcher(lastSearchString, regExp);
|
||||||
|
while (itemNo < arr.size() && !m.matches(arr.get(itemNo)))
|
||||||
itemNo++;
|
itemNo++;
|
||||||
if (itemNo < arr.size())
|
if (itemNo < arr.size())
|
||||||
binding.listView.setSelectionFromTop(itemNo, 0);
|
binding.listView.setSelectionFromTop(itemNo, 0);
|
||||||
};
|
};
|
||||||
|
aa.setUseRegExp(regExp);
|
||||||
aa.getFilter().filter(s, listener);
|
aa.getFilter().filter(s, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ import android.widget.Filterable;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.PatternSyntaxException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An adapter for displaying an ArrayList<GameInfo> in a ListView.
|
* An adapter for displaying an ArrayList<GameInfo> in a ListView.
|
||||||
|
@ -38,6 +40,7 @@ public class GameAdapter<T> extends BaseAdapter implements Filterable {
|
||||||
private final LayoutInflater inflater;
|
private final LayoutInflater inflater;
|
||||||
private int resource;
|
private int resource;
|
||||||
private GameFilter filter; // Initialized at first use
|
private GameFilter filter; // Initialized at first use
|
||||||
|
private boolean useRegExp = false; // If true, use regular expression in filter
|
||||||
|
|
||||||
public GameAdapter(Context context, int resource, ArrayList<T> objects) {
|
public GameAdapter(Context context, int resource, ArrayList<T> objects) {
|
||||||
origValues = objects;
|
origValues = objects;
|
||||||
|
@ -83,6 +86,10 @@ public class GameAdapter<T> extends BaseAdapter implements Filterable {
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUseRegExp(boolean regExp) {
|
||||||
|
useRegExp = regExp;
|
||||||
|
}
|
||||||
|
|
||||||
private class GameFilter extends Filter {
|
private class GameFilter extends Filter {
|
||||||
@Override
|
@Override
|
||||||
protected FilterResults performFiltering(CharSequence constraint) {
|
protected FilterResults performFiltering(CharSequence constraint) {
|
||||||
|
@ -91,10 +98,10 @@ public class GameAdapter<T> extends BaseAdapter implements Filterable {
|
||||||
res.values = origValues;
|
res.values = origValues;
|
||||||
res.count = origValues.size();
|
res.count = origValues.size();
|
||||||
} else {
|
} else {
|
||||||
String s = constraint.toString().toLowerCase();
|
ItemMatcher<T> m = getItemMatcher(constraint.toString(), useRegExp);
|
||||||
ArrayList<T> newValues = new ArrayList<>();
|
ArrayList<T> newValues = new ArrayList<>();
|
||||||
for (T item : origValues)
|
for (T item : origValues)
|
||||||
if (matchItem(item, s))
|
if (m.matches(item))
|
||||||
newValues.add(item);
|
newValues.add(item);
|
||||||
res.values = newValues;
|
res.values = newValues;
|
||||||
res.count = newValues.size();
|
res.count = newValues.size();
|
||||||
|
@ -110,10 +117,27 @@ public class GameAdapter<T> extends BaseAdapter implements Filterable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true if matchStr matches item.
|
interface ItemMatcher<U> {
|
||||||
* @param item The item to check. The toString() value converted to lowercase is used.
|
/** Return true if item matches the search criteria. */
|
||||||
* @param matchStr The match string. Must be lowercase. */
|
boolean matches(U item);
|
||||||
static <U> boolean matchItem(U item, String matchStr) {
|
}
|
||||||
return item.toString().toLowerCase().contains(matchStr);
|
|
||||||
|
/** Return an object that determines if an item matches given search criteria.
|
||||||
|
* @param matchStr The match string.
|
||||||
|
* @param useRegExp If true matchStr is interpreted as a regular expression. */
|
||||||
|
static <U> ItemMatcher<U> getItemMatcher(String matchStr, boolean useRegExp) {
|
||||||
|
if (useRegExp) {
|
||||||
|
Pattern tmp;
|
||||||
|
try {
|
||||||
|
tmp = Pattern.compile(matchStr, Pattern.CASE_INSENSITIVE);
|
||||||
|
} catch (PatternSyntaxException ex) {
|
||||||
|
tmp = null;
|
||||||
|
}
|
||||||
|
Pattern p = tmp;
|
||||||
|
return item -> p == null || p.matcher(item.toString()).find();
|
||||||
|
} else {
|
||||||
|
String s = matchStr.toLowerCase();
|
||||||
|
return item -> item.toString().toLowerCase().contains(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/item_delete_file"
|
android:id="@+id/item_delete_file"
|
||||||
android:title="@string/delete_file" />
|
android:title="@string/delete_file" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/regexp_search"
|
||||||
|
android:title="@string/regexp_search"
|
||||||
|
android:checkable="true"
|
||||||
|
app:showAsAction="never" />
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -196,6 +196,7 @@ If you are running on battery power, it is recommended that you change settings
|
||||||
<string name="delete_file">Delete file</string>
|
<string name="delete_file">Delete file</string>
|
||||||
<string name="delete_file_question">Delete file?</string>
|
<string name="delete_file_question">Delete file?</string>
|
||||||
<string name="delete_named_file">Delete file %s?</string>
|
<string name="delete_named_file">Delete file %s?</string>
|
||||||
|
<string name="regexp_search">Regular Expression Search</string>
|
||||||
<string name="game_saved">Game saved</string>
|
<string name="game_saved">Game saved</string>
|
||||||
<string name="failed_to_save_game">Failed to save game</string>
|
<string name="failed_to_save_game">Failed to save game</string>
|
||||||
<string name="failed_to_delete_game">Failed to delete game</string>
|
<string name="failed_to_delete_game">Failed to delete game</string>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user