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 { ...@@ -91,7 +91,7 @@ public class CardLoader implements ICardSearcher {
} }
public void loadData() { public void loadData() {
loadData(null); loadData(null, null);
} }
@Override @Override
...@@ -114,7 +114,7 @@ public class CardLoader implements ICardSearcher { ...@@ -114,7 +114,7 @@ public class CardLoader implements ICardSearcher {
} }
} }
private void loadData(CardSearchInfo searchInfo) { private void loadData(CardSearchInfo searchInfo, List<Integer> inCards) {
if (!isOpen()) { if (!isOpen()) {
return; return;
} }
...@@ -129,7 +129,11 @@ public class CardLoader implements ICardSearcher { ...@@ -129,7 +129,11 @@ public class CardLoader implements ICardSearcher {
List<Card> list = new ArrayList<>(); List<Card> list = new ArrayList<>();
for (int i = 0; i < cards.size(); i++) { for (int i = 0; i < cards.size(); i++) {
Card card = cards.valueAt(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); list.add(card);
} }
} }
...@@ -178,38 +182,16 @@ public class CardLoader implements ICardSearcher { ...@@ -178,38 +182,16 @@ public class CardLoader implements ICardSearcher {
} }
@Override @Override
public void search(String prefixWord, String suffixWord, public void search(CardSearchInfo searchInfo) {
long attribute, long level, long race, String limitName = searchInfo.getLimitName();
String limitName, long limit, int limit = searchInfo.getLimitType();
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;
LimitList limitList = null; LimitList limitList = null;
List<Integer> inCards = null;
if (!TextUtils.isEmpty(limitName)) { if (!TextUtils.isEmpty(limitName)) {
limitList = mLimitManager.getLimit(limitName); limitList = mLimitManager.getLimit(limitName);
setLimitList(limitList); setLimitList(limitList);
LimitType cardLimitType = LimitType.valueOf(limit);
if (limitList != null) { if (limitList != null) {
LimitType cardLimitType = LimitType.valueOf(limit);
List<Integer> ids; List<Integer> ids;
if (cardLimitType == LimitType.Forbidden) { if (cardLimitType == LimitType.Forbidden) {
ids = limitList.forbidden; ids = limitList.forbidden;
...@@ -222,13 +204,11 @@ public class CardLoader implements ICardSearcher { ...@@ -222,13 +204,11 @@ public class CardLoader implements ICardSearcher {
} else { } else {
ids = null; ids = null;
} }
if (ids != null) { inCards = ids;
searchInfo.inCards = ids;
}
} }
} else { } else {
setLimitList(null); setLimitList(null);
} }
loadData(searchInfo); loadData(searchInfo, inCards);
} }
} }
...@@ -8,19 +8,158 @@ import ocgcore.data.Card; ...@@ -8,19 +8,158 @@ import ocgcore.data.Card;
import ocgcore.enums.CardOt; import ocgcore.enums.CardOt;
import ocgcore.enums.CardType; import ocgcore.enums.CardType;
class CardSearchInfo { public class CardSearchInfo implements ICardFilter{
//名字或者描述 //名字或者描述
String keyWord1, keyWord2; private CardKeyWord keyWord;
int attribute; private int attribute;
int level, ot, pscale = -1; private int level;
long race, category; private int ot;
String atk, def; private int pscale = -1;
int linkKey; private long race;
List<Integer> inCards; private long category;
long[] types; private String atk;
long setcode, keyWordSetcode1, keyWordSetcode2; 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) { public static boolean containsIgnoreCase(String src, String what) {
...@@ -45,32 +184,11 @@ class CardSearchInfo { ...@@ -45,32 +184,11 @@ class CardSearchInfo {
return false; return false;
} }
List<Integer> getInCards() { @Override
return inCards; public boolean isValid(Card card) {
} if(keyWord != null && !keyWord.isValid(card)){
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)))) {
return false; 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 (attribute != 0) {
if (card.Attribute != attribute) { if (card.Attribute != attribute) {
return false; return false;
...@@ -113,7 +231,7 @@ class CardSearchInfo { ...@@ -113,7 +231,7 @@ class CardSearchInfo {
} }
} }
if (ot > CardOt.ALL.getId()) { 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()) { if (card.Ot == CardOt.OCG.getId() || card.Ot == CardOt.TCG.getId()) {
return false; 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; ...@@ -3,10 +3,7 @@ package cn.garymb.ygomobile.loader;
import ocgcore.data.LimitList; import ocgcore.data.LimitList;
public interface ICardSearcher extends ICardLoader{ public interface ICardSearcher extends ICardLoader{
void search(String prefixWord, String suffixWord, void search(CardSearchInfo searchInfo);
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 onReset(); void onReset();
void setLimitList(LimitList limit); void setLimitList(LimitList limit);
LimitList getLimitList(); LimitList getLimitList();
......
...@@ -4,6 +4,7 @@ import android.text.TextUtils; ...@@ -4,6 +4,7 @@ import android.text.TextUtils;
import android.util.SparseArray; import android.util.SparseArray;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -73,7 +74,16 @@ public class CardFavorites { ...@@ -73,7 +74,16 @@ public class CardFavorites {
mList.clear(); mList.clear();
File config = AppsSettings.get().getFavoriteFile(); File config = AppsSettings.get().getFavoriteFile();
List<String> lines; 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(); config = AppsSettings.get().getSystemConfig();
} }
if (!config.exists()) { if (!config.exists()) {
......
...@@ -20,6 +20,7 @@ import java.util.List; ...@@ -20,6 +20,7 @@ import java.util.List;
import cn.garymb.ygomobile.AppsSettings; import cn.garymb.ygomobile.AppsSettings;
import cn.garymb.ygomobile.lite.R; import cn.garymb.ygomobile.lite.R;
import cn.garymb.ygomobile.loader.CardSearchInfo;
import cn.garymb.ygomobile.loader.ICardSearcher; import cn.garymb.ygomobile.loader.ICardSearcher;
import cn.garymb.ygomobile.ui.adapters.SimpleSpinnerAdapter; import cn.garymb.ygomobile.ui.adapters.SimpleSpinnerAdapter;
import cn.garymb.ygomobile.ui.adapters.SimpleSpinnerItem; import cn.garymb.ygomobile.ui.adapters.SimpleSpinnerItem;
...@@ -44,9 +45,8 @@ public class CardSearcher implements View.OnClickListener { ...@@ -44,9 +45,8 @@ public class CardSearcher implements View.OnClickListener {
protected StringManager mStringManager; protected StringManager mStringManager;
protected LimitManager mLimitManager; protected LimitManager mLimitManager;
protected AppsSettings mSettings; protected AppsSettings mSettings;
int lineKey; private int lineKey;
private final EditText prefixWord; private final EditText keyWord;
private final EditText suffixWord;
private final Spinner otSpinner; private final Spinner otSpinner;
private final Spinner limitSpinner; private final Spinner limitSpinner;
private final Spinner limitListSpinner; private final Spinner limitListSpinner;
...@@ -92,8 +92,7 @@ public class CardSearcher implements View.OnClickListener { ...@@ -92,8 +92,7 @@ public class CardSearcher implements View.OnClickListener {
this.mSettings = AppsSettings.get(); this.mSettings = AppsSettings.get();
mStringManager = DataManager.get().getStringManager(); mStringManager = DataManager.get().getStringManager();
mLimitManager = DataManager.get().getLimitManager(); mLimitManager = DataManager.get().getLimitManager();
prefixWord = findViewById(R.id.edt_word1); keyWord = findViewById(R.id.edt_word1);
suffixWord = findViewById(R.id.edt_word2);
otSpinner = findViewById(R.id.sp_ot); otSpinner = findViewById(R.id.sp_ot);
limitSpinner = findViewById(R.id.sp_limit); limitSpinner = findViewById(R.id.sp_limit);
limitListSpinner = findViewById(R.id.sp_limit_list); limitListSpinner = findViewById(R.id.sp_limit_list);
...@@ -131,8 +130,7 @@ public class CardSearcher implements View.OnClickListener { ...@@ -131,8 +130,7 @@ public class CardSearcher implements View.OnClickListener {
return false; return false;
}; };
prefixWord.setOnEditorActionListener(searchListener); keyWord.setOnEditorActionListener(searchListener);
suffixWord.setOnEditorActionListener(searchListener);
myFavButton.setOnClickListener(v -> { myFavButton.setOnClickListener(v -> {
if(isShowFavorite()){ if(isShowFavorite()){
...@@ -525,6 +523,10 @@ public class CardSearcher implements View.OnClickListener { ...@@ -525,6 +523,10 @@ public class CardSearcher implements View.OnClickListener {
} }
} }
private int getIntSelect(Spinner spinner) {
return (int)getSelect(spinner);
}
private long getSelect(Spinner spinner) { private long getSelect(Spinner spinner) {
return SimpleSpinnerAdapter.getSelect(spinner); return SimpleSpinnerAdapter.getSelect(spinner);
} }
...@@ -554,19 +556,35 @@ public class CardSearcher implements View.OnClickListener { ...@@ -554,19 +556,35 @@ public class CardSearcher implements View.OnClickListener {
if (TextUtils.isEmpty(message)) { if (TextUtils.isEmpty(message)) {
message = ""; message = "";
} }
prefixWord.setText(message); keyWord.setText(message);
search(); search();
} }
private void search() { private void search() {
if (dataLoader != null) { if (dataLoader != null) {
dataLoader.search(text(prefixWord), text(suffixWord), getSelect(attributeSpinner) CardSearchInfo searchInfo = new CardSearchInfo.Builder()
, getSelect(levelSpinner), getSelect(raceSpinner), getSelectText(limitListSpinner), getSelect(limitSpinner), .keyword(text(keyWord))
text(atkText), text(defText), .attribute(getIntSelect(attributeSpinner))
getSelect(pScale), .level(getIntSelect(levelSpinner))
getSelect(setCodeSpinner) .race(getSelect(raceSpinner))
, getSelect(categorySpinner), getSelect(otSpinner), lineKey, getSelect(typeSpinner), getSelect(typeMonsterSpinner), getSelect(typeSpellSpinner), getSelect(typeTrapSpinner) .atk(text(atkText))
, getSelect(typeMonsterSpinner2)); .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; lineKey = 0;
} }
} }
...@@ -575,8 +593,7 @@ public class CardSearcher implements View.OnClickListener { ...@@ -575,8 +593,7 @@ public class CardSearcher implements View.OnClickListener {
if (dataLoader != null) { if (dataLoader != null) {
dataLoader.onReset(); dataLoader.onReset();
} }
prefixWord.setText(null); keyWord.setText(null);
suffixWord.setText(null);
reset(otSpinner); reset(otSpinner);
reset(limitSpinner); reset(limitSpinner);
// reset(limitListSpinner); // reset(limitListSpinner);
......
...@@ -176,7 +176,7 @@ public abstract class PreferenceFragmentPlus extends BasePreferenceFragment { ...@@ -176,7 +176,7 @@ public abstract class PreferenceFragmentPlus extends BasePreferenceFragment {
if (mCurImageInfo != null) { if (mCurImageInfo != null) {
String cachePath = photos.get(0); String cachePath = photos.get(0);
try { try {
FileUtils.copyFile(cachePath, mCurImageInfo.mOutFile, true); FileUtils.copyFile(cachePath, mCurImageInfo.mOutFile);
} catch (IOException e) { } catch (IOException e) {
Toast.makeText(getContext(), e + "", Toast.LENGTH_LONG).show(); Toast.makeText(getContext(), e + "", Toast.LENGTH_LONG).show();
onChooseFileFail(curPreference); onChooseFileFail(curPreference);
......
...@@ -4,6 +4,7 @@ package ocgcore; ...@@ -4,6 +4,7 @@ package ocgcore;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.Closeable; import java.io.Closeable;
...@@ -47,8 +48,7 @@ public class LimitManager implements Closeable { ...@@ -47,8 +48,7 @@ public class LimitManager implements Closeable {
return mLimitNames; return mLimitNames;
} }
public @NonNull public @Nullable LimitList getLimit(String name) {
LimitList getLimit(String name) {
return mLimitLists.get(name); return mLimitLists.get(name);
} }
......
...@@ -263,42 +263,29 @@ ...@@ -263,42 +263,29 @@
android:textColorHint="@color/gold" /> android:textColorHint="@color/gold" />
</com.google.android.material.textfield.TextInputLayout> </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>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"> android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout <androidx.appcompat.widget.AppCompatButton
android:layout_width="0dp" android:id="@+id/btn_search"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:layout_weight="1"> android:layout_marginRight="10dp"
android:layout_gravity="center_vertical"
<androidx.appcompat.widget.AppCompatEditText android:background="@drawable/button_bg"
android:id="@+id/edt_word2" android:text="@string/search" />
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>
<androidx.appcompat.widget.AppCompatButton <androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_reset" android:id="@+id/btn_reset"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="40dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:background="@drawable/button_bg" android:background="@drawable/button_bg"
android:text="@string/reset" /> 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