Commit af0fbf7b authored by fallenstardust's avatar fallenstardust

多关键词搜索

parent 31479f37
package cn.garymb.ygomobile.loader;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import cn.garymb.ygomobile.core.IrrlichtBridge;
import ocgcore.DataManager;
import ocgcore.data.Card;
public class CardKeyWord {
private final String word;
private final List<ICardFilter> filterList = new ArrayList<>();
private final boolean empty;
public CardKeyWord(String word) {
this.word = word;
if (!TextUtils.isEmpty(word)) {
if (TextUtils.isDigitsOnly(word)) {
//搜索卡密
filterList.add(new CodeFilter(Long.parseLong(word)));
} else {
String[] ws = word.split(" ");
for (String w : ws) {
if (TextUtils.isEmpty(w)) {
continue;
}
boolean exclude = false;
if (w.startsWith("-")) {
exclude = true;
w = w.substring(1);
}
boolean onlyText = false;
if (w.startsWith("\"") || w.startsWith("“") || w.startsWith("”")) {
//只搜索文字
onlyText = true;
if (w.endsWith("\"") || w.endsWith("“") || w.endsWith("”")) {
w = w.substring(1, w.length() - 1);
} else {
w = w.substring(1);
}
}
if (!onlyText) {
long setcode = DataManager.get().getStringManager().getSetCode(w);
if (setcode != 0) {
//如果是系列名
filterList.add(new SetcodeFilter(setcode, exclude));
}
}
// Log.d(IrrlichtBridge.TAG, "filter:word=" + w + ", exclude=" + exclude + ", onlyText=" + onlyText);
filterList.add(new NameFilter(w, exclude));
}
}
}
empty = filterList.size() == 0;
}
public String getValue() {
return word;
}
public boolean isValid(Card card) {
if (empty) {
return true;
}
for (ICardFilter filter : filterList) {
if (!filter.isValid(card)) {
return false;
}
}
return true;
}
private static class NameFilter implements ICardFilter {
private final boolean exclude;
private final String word;
public NameFilter(String word, boolean exclude) {
this.exclude = exclude;
this.word = word;
}
@Override
public boolean isValid(Card card) {
if (exclude) {
return !card.Name.contains(word);
} else {
return card.Name.contains(word);
}
}
}
private static class SetcodeFilter implements ICardFilter {
private final boolean exclude;
private final long setcode;
public SetcodeFilter(long setcode, boolean exclude) {
this.exclude = exclude;
this.setcode = setcode;
}
@Override
public boolean isValid(Card card) {
if (exclude) {
return !card.isSetCode(setcode);
} else {
return card.isSetCode(setcode);
}
}
}
private static class CodeFilter implements ICardFilter {
private final long code;
public CodeFilter(long code) {
this.code = code;
}
@Override
public boolean isValid(Card card) {
return card.Code == code || card.Alias == code;
}
}
}
......@@ -91,7 +91,7 @@ public class CardLoader implements ICardSearcher {
}
public void loadData() {
loadData(null);
loadData(null, null);
}
@Override
......@@ -114,7 +114,7 @@ public class CardLoader implements ICardSearcher {
}
}
private void loadData(CardSearchInfo searchInfo) {
private void loadData(CardSearchInfo searchInfo, List<Integer> inCards) {
if (!isOpen()) {
return;
}
......@@ -129,7 +129,11 @@ public class CardLoader implements ICardSearcher {
List<Card> list = new ArrayList<>();
for (int i = 0; i < cards.size(); i++) {
Card card = cards.valueAt(i);
if (searchInfo == null || searchInfo.check(card)) {
//ָΧ
if (inCards != null && (!inCards.contains(card.Code) && !inCards.contains(card.Alias))) {
continue;
}
if (searchInfo == null || searchInfo.isValid(card)) {
list.add(card);
}
}
......@@ -178,38 +182,16 @@ public class CardLoader implements ICardSearcher {
}
@Override
public void search(String prefixWord, String suffixWord,
long attribute, long level, long race,
String limitName, long limit,
String atk, String def, long pscale,
long setcode, long category, long ot, int linkKey, long... types) {
CardSearchInfo searchInfo = new CardSearchInfo();
if (!TextUtils.isEmpty(prefixWord)) {
searchInfo.keyWord1 = prefixWord;
searchInfo.keyWordSetcode1 = mStringManager.getSetCode(prefixWord);
}
if (!TextUtils.isEmpty(suffixWord)) {
searchInfo.keyWord2 = suffixWord;
searchInfo.keyWordSetcode2 = mStringManager.getSetCode(suffixWord);
}
searchInfo.attribute = (int) attribute;
searchInfo.level = (int) level;
searchInfo.atk = atk;
searchInfo.def = def;
searchInfo.ot = (int) ot;
searchInfo.linkKey = linkKey;
searchInfo.types = types;
searchInfo.category = category;
searchInfo.race = race;
searchInfo.pscale = (int) pscale;
searchInfo.setcode = setcode;
public void search(CardSearchInfo searchInfo) {
String limitName = searchInfo.getLimitName();
int limit = searchInfo.getLimitType();
LimitList limitList = null;
List<Integer> inCards = null;
if (!TextUtils.isEmpty(limitName)) {
limitList = mLimitManager.getLimit(limitName);
setLimitList(limitList);
LimitType cardLimitType = LimitType.valueOf(limit);
if (limitList != null) {
LimitType cardLimitType = LimitType.valueOf(limit);
List<Integer> ids;
if (cardLimitType == LimitType.Forbidden) {
ids = limitList.forbidden;
......@@ -222,13 +204,11 @@ public class CardLoader implements ICardSearcher {
} else {
ids = null;
}
if (ids != null) {
searchInfo.inCards = ids;
}
inCards = ids;
}
} else {
setLimitList(null);
}
loadData(searchInfo);
loadData(searchInfo, inCards);
}
}
......@@ -8,19 +8,158 @@ import ocgcore.data.Card;
import ocgcore.enums.CardOt;
import ocgcore.enums.CardType;
class CardSearchInfo {
public class CardSearchInfo implements ICardFilter{
//名字或者描述
String keyWord1, keyWord2;
int attribute;
int level, ot, pscale = -1;
long race, category;
String atk, def;
int linkKey;
List<Integer> inCards;
long[] types;
long setcode, keyWordSetcode1, keyWordSetcode2;
private CardKeyWord keyWord;
private int attribute;
private int level;
private int ot;
private int pscale = -1;
private long race;
private long category;
private String atk;
private String def;
private int linkKey;
private long[] types;
private long setcode;
private int limitType;
private String limitName;
CardSearchInfo() {
private CardSearchInfo() {
}
public int getLimitType() {
return limitType;
}
public String getLimitName() {
return limitName;
}
public CardKeyWord getKeyWord() {
return keyWord;
}
public int getAttribute() {
return attribute;
}
public int getLevel() {
return level;
}
public int getOt() {
return ot;
}
public int getPscale() {
return pscale;
}
public long getRace() {
return race;
}
public long getCategory() {
return category;
}
public String getAtk() {
return atk;
}
public String getDef() {
return def;
}
public int getLinkKey() {
return linkKey;
}
public long[] getTypes() {
return types;
}
public long getSetcode() {
return setcode;
}
public static class Builder {
private final CardSearchInfo searchInfo = new CardSearchInfo();
public CardSearchInfo build() {
return searchInfo;
}
public Builder limitType(int limit){
searchInfo.limitType = limit;
return this;
}
public Builder limitName(String val) {
searchInfo.limitName = val;
return this;
}
public Builder keyword(String val) {
searchInfo.keyWord = new CardKeyWord(val);
return this;
}
public Builder attribute(int val) {
searchInfo.attribute = val;
return this;
}
public Builder level(int val) {
searchInfo.level = val;
return this;
}
public Builder ot(int val) {
searchInfo.ot = val;
return this;
}
public Builder pscale(int val) {
searchInfo.pscale = val;
return this;
}
public Builder race(long val) {
searchInfo.race = val;
return this;
}
public Builder category(long val) {
searchInfo.category = val;
return this;
}
public Builder atk(String val) {
searchInfo.atk = val;
return this;
}
public Builder def(String val) {
searchInfo.def = val;
return this;
}
public Builder linkKey(int linkKey) {
searchInfo.linkKey = linkKey;
return this;
}
public Builder types(long[] types) {
searchInfo.types = types;
return this;
}
public Builder setcode(long setcode) {
searchInfo.setcode = setcode;
return this;
}
}
public static boolean containsIgnoreCase(String src, String what) {
......@@ -45,32 +184,11 @@ class CardSearchInfo {
return false;
}
List<Integer> getInCards() {
return inCards;
}
public boolean check(Card card) {
if (inCards != null && !inCards.contains(Integer.valueOf(card.Code))) {
return false;
}
if (!TextUtils.isEmpty(keyWord1)) {
if (TextUtils.isDigitsOnly(keyWord1) && keyWord1.length() >= 5) {
//code
long code = Long.parseLong(keyWord1);
return card.Code == code || card.Alias == code;
} else if (!((card.Name != null && containsIgnoreCase(card.Name, keyWord1))
|| (card.Desc != null && containsIgnoreCase(card.Desc, keyWord1))
|| (keyWordSetcode1 > 0 && card.isSetCode(keyWordSetcode1)))) {
@Override
public boolean isValid(Card card) {
if(keyWord != null && !keyWord.isValid(card)){
return false;
}
}
if (!TextUtils.isEmpty(keyWord2)) {
if (!((card.Name != null && containsIgnoreCase(card.Name, keyWord2))
|| (card.Desc != null && containsIgnoreCase(card.Desc, keyWord2))
|| (keyWordSetcode2 > 0 && card.isSetCode(keyWordSetcode2)))) {
return false;
}
}
if (attribute != 0) {
if (card.Attribute != attribute) {
return false;
......@@ -113,7 +231,7 @@ class CardSearchInfo {
}
}
if (ot > CardOt.ALL.getId()) {
if(ot == CardOt.NO_EXCLUSIVE.getId()){
if (ot == CardOt.NO_EXCLUSIVE.getId()) {
if (card.Ot == CardOt.OCG.getId() || card.Ot == CardOt.TCG.getId()) {
return false;
}
......
package cn.garymb.ygomobile.loader;
import ocgcore.data.Card;
public interface ICardFilter {
boolean isValid(Card card);
}
......@@ -3,10 +3,7 @@ package cn.garymb.ygomobile.loader;
import ocgcore.data.LimitList;
public interface ICardSearcher extends ICardLoader{
void search(String prefixWord, String suffixWord,
long attribute, long level, long race,String limitName,long limit,
String atk, String def,long pscale,
long setcode, long category, long ot,int link, long... types);
void search(CardSearchInfo searchInfo);
void onReset();
void setLimitList(LimitList limit);
LimitList getLimitList();
......
......@@ -4,6 +4,7 @@ import android.text.TextUtils;
import android.util.SparseArray;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
......@@ -73,7 +74,16 @@ public class CardFavorites {
mList.clear();
File config = AppsSettings.get().getFavoriteFile();
List<String> lines;
if (!config.exists()) {
if (config.exists()) {
//重命名
if(config.renameTo(AppsSettings.get().getSystemConfig())) {
try {
FileUtils.copyFile(AppsSettings.get().getFavoriteFile().getPath(), AppsSettings.get().getSystemConfig().getPath());
} catch (IOException e) {
//TODO 复制失败,直接删除?
FileUtils.deleteFile(AppsSettings.get().getFavoriteFile());
}
}
config = AppsSettings.get().getSystemConfig();
}
if (!config.exists()) {
......
......@@ -20,6 +20,7 @@ import java.util.List;
import cn.garymb.ygomobile.AppsSettings;
import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.loader.CardSearchInfo;
import cn.garymb.ygomobile.loader.ICardSearcher;
import cn.garymb.ygomobile.ui.adapters.SimpleSpinnerAdapter;
import cn.garymb.ygomobile.ui.adapters.SimpleSpinnerItem;
......@@ -44,9 +45,8 @@ public class CardSearcher implements View.OnClickListener {
protected StringManager mStringManager;
protected LimitManager mLimitManager;
protected AppsSettings mSettings;
int lineKey;
private final EditText prefixWord;
private final EditText suffixWord;
private int lineKey;
private final EditText keyWord;
private final Spinner otSpinner;
private final Spinner limitSpinner;
private final Spinner limitListSpinner;
......@@ -92,8 +92,7 @@ public class CardSearcher implements View.OnClickListener {
this.mSettings = AppsSettings.get();
mStringManager = DataManager.get().getStringManager();
mLimitManager = DataManager.get().getLimitManager();
prefixWord = findViewById(R.id.edt_word1);
suffixWord = findViewById(R.id.edt_word2);
keyWord = findViewById(R.id.edt_word1);
otSpinner = findViewById(R.id.sp_ot);
limitSpinner = findViewById(R.id.sp_limit);
limitListSpinner = findViewById(R.id.sp_limit_list);
......@@ -131,8 +130,7 @@ public class CardSearcher implements View.OnClickListener {
return false;
};
prefixWord.setOnEditorActionListener(searchListener);
suffixWord.setOnEditorActionListener(searchListener);
keyWord.setOnEditorActionListener(searchListener);
myFavButton.setOnClickListener(v -> {
if(isShowFavorite()){
......@@ -525,6 +523,10 @@ public class CardSearcher implements View.OnClickListener {
}
}
private int getIntSelect(Spinner spinner) {
return (int)getSelect(spinner);
}
private long getSelect(Spinner spinner) {
return SimpleSpinnerAdapter.getSelect(spinner);
}
......@@ -554,19 +556,35 @@ public class CardSearcher implements View.OnClickListener {
if (TextUtils.isEmpty(message)) {
message = "";
}
prefixWord.setText(message);
keyWord.setText(message);
search();
}
private void search() {
if (dataLoader != null) {
dataLoader.search(text(prefixWord), text(suffixWord), getSelect(attributeSpinner)
, getSelect(levelSpinner), getSelect(raceSpinner), getSelectText(limitListSpinner), getSelect(limitSpinner),
text(atkText), text(defText),
getSelect(pScale),
getSelect(setCodeSpinner)
, getSelect(categorySpinner), getSelect(otSpinner), lineKey, getSelect(typeSpinner), getSelect(typeMonsterSpinner), getSelect(typeSpellSpinner), getSelect(typeTrapSpinner)
, getSelect(typeMonsterSpinner2));
CardSearchInfo searchInfo = new CardSearchInfo.Builder()
.keyword(text(keyWord))
.attribute(getIntSelect(attributeSpinner))
.level(getIntSelect(levelSpinner))
.race(getSelect(raceSpinner))
.atk(text(atkText))
.def(text(defText))
.pscale(getIntSelect(pScale))
.limitType(getIntSelect(limitSpinner))
.limitName(getSelectText(limitListSpinner))
.setcode(getSelect(setCodeSpinner))
.category(getSelect(categorySpinner))
.ot(getIntSelect(otSpinner))
.types(new long[]{
getSelect(typeSpinner),
getSelect(typeMonsterSpinner),
getSelect(typeSpellSpinner),
getSelect(typeTrapSpinner),
getSelect(typeMonsterSpinner2)
})
.linkKey(lineKey)
.build();
dataLoader.search(searchInfo);
lineKey = 0;
}
}
......@@ -575,8 +593,7 @@ public class CardSearcher implements View.OnClickListener {
if (dataLoader != null) {
dataLoader.onReset();
}
prefixWord.setText(null);
suffixWord.setText(null);
keyWord.setText(null);
reset(otSpinner);
reset(limitSpinner);
// reset(limitListSpinner);
......
......@@ -176,7 +176,7 @@ public abstract class PreferenceFragmentPlus extends BasePreferenceFragment {
if (mCurImageInfo != null) {
String cachePath = photos.get(0);
try {
FileUtils.copyFile(cachePath, mCurImageInfo.mOutFile, true);
FileUtils.copyFile(cachePath, mCurImageInfo.mOutFile);
} catch (IOException e) {
Toast.makeText(getContext(), e + "", Toast.LENGTH_LONG).show();
onChooseFileFail(curPreference);
......
......@@ -4,6 +4,7 @@ package ocgcore;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.BufferedReader;
import java.io.Closeable;
......@@ -47,8 +48,7 @@ public class LimitManager implements Closeable {
return mLimitNames;
}
public @NonNull
LimitList getLimit(String name) {
public @Nullable LimitList getLimit(String name) {
return mLimitLists.get(name);
}
......
......@@ -263,42 +263,29 @@
android:textColorHint="@color/gold" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/button_bg"
android:text="@string/search" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_search"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:layout_weight="1">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/edt_word2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hit_keyword2"
android:imeOptions="actionSearch"
android:inputType="textNoSuggestions"
android:maxLines="1"
android:singleLine="true"
android:textColorHint="@color/gold" />
</com.google.android.material.textfield.TextInputLayout>
android:layout_marginRight="10dp"
android:layout_gravity="center_vertical"
android:background="@drawable/button_bg"
android:text="@string/search" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_reset"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:background="@drawable/button_bg"
android:text="@string/reset" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment