Merge pull request #8694 from kevlahnota/master4

fix Keyword Advanced Search
This commit is contained in:
kevlahnota
2025-09-11 19:04:51 +08:00
committed by GitHub
2 changed files with 200 additions and 136 deletions

View File

@@ -278,6 +278,12 @@ public enum Keyword {
return keywords; return keywords;
} }
public static Keyword get(String key) {
if (key.isEmpty())
return null;
return Arrays.stream(values()).filter(k -> key.equalsIgnoreCase(k.displayName)).findFirst().orElse(null);
}
private static final Map<String, Set<Keyword>> cardKeywordSetLookup = new HashMap<>(); private static final Map<String, Set<Keyword>> cardKeywordSetLookup = new HashMap<>();
public static Set<Keyword> getKeywordSet(PaperCard card) { public static Set<Keyword> getKeywordSet(PaperCard card) {

View File

@@ -57,6 +57,7 @@ public class AdvancedSearch {
protected String getItemValue(PaperCard input) { protected String getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<String> getItemValues(PaperCard input) { protected Set<String> getItemValues(PaperCard input) {
Set<String> names = new HashSet<>(); Set<String> names = new HashSet<>();
@@ -77,6 +78,7 @@ public class AdvancedSearch {
protected String getItemValue(PaperCard input) { protected String getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<String> getItemValues(PaperCard input) { protected Set<String> getItemValues(PaperCard input) {
Set<String> names = new HashSet<>(); Set<String> names = new HashSet<>();
@@ -98,22 +100,31 @@ public class AdvancedSearch {
protected Keyword getItemValue(PaperCard input) { protected Keyword getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<Keyword> getItemValues(PaperCard input) { protected Set<Keyword> getItemValues(PaperCard input) {
CardSplitType cardSplitType = input.getRules().getSplitType(); CardSplitType cardSplitType = input.getRules().getSplitType();
if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) {
Set<Keyword> keywords = new HashSet<>(); Set<Keyword> keywords = new HashSet<>();
if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) {
if (input.getRules().getOtherPart() != null) { if (input.getRules().getOtherPart() != null) {
PaperCard otherPart = FModel.getMagicDb().getCommonCards().getCard(input.getRules().getOtherPart().getName()); if (input.getRules().getOtherPart().getKeywords() != null) {
if (otherPart != null) { for (String key : input.getRules().getOtherPart().getKeywords()) {
keywords.addAll(Keyword.getKeywordSet(otherPart)); Keyword keyword = Keyword.get(key);
keywords.addAll(Keyword.getKeywordSet(input)); if (keyword != null)
keywords.add(keyword);
}
}
}
}
if (input.getRules().getMainPart().getKeywords() != null) {
for (String key : input.getRules().getMainPart().getKeywords()) {
Keyword keyword = Keyword.get(key);
if (keyword != null)
keywords.add(keyword);
} }
} }
return keywords; return keywords;
} }
return Keyword.getKeywordSet(input);
}
}), }),
CARD_SET("lblSet", PaperCard.class, FilterOperator.SINGLE_LIST_OPS, new CustomListEvaluator<PaperCard, CardEdition>(FModel.getMagicDb().getSortedEditions(), CardEdition::getCode) { CARD_SET("lblSet", PaperCard.class, FilterOperator.SINGLE_LIST_OPS, new CustomListEvaluator<PaperCard, CardEdition>(FModel.getMagicDb().getSortedEditions(), CardEdition::getCode) {
@Override @Override
@@ -126,6 +137,7 @@ public class AdvancedSearch {
protected GameFormat getItemValue(PaperCard input) { protected GameFormat getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<GameFormat> getItemValues(PaperCard input) { protected Set<GameFormat> getItemValues(PaperCard input) {
return FModel.getFormats().getAllFormatsOfCard(input); return FModel.getFormats().getAllFormatsOfCard(input);
@@ -136,6 +148,7 @@ public class AdvancedSearch {
protected ConquestPlane getItemValue(PaperCard input) { protected ConquestPlane getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<ConquestPlane> getItemValues(PaperCard input) { protected Set<ConquestPlane> getItemValues(PaperCard input) {
return ConquestPlane.getAllPlanesOfCard(input); return ConquestPlane.getAllPlanesOfCard(input);
@@ -146,6 +159,7 @@ public class AdvancedSearch {
protected ConquestRegion getItemValue(PaperCard input) { protected ConquestRegion getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<ConquestRegion> getItemValues(PaperCard input) { protected Set<ConquestRegion> getItemValues(PaperCard input) {
return ConquestRegion.getAllRegionsOfCard(input); return ConquestRegion.getAllRegionsOfCard(input);
@@ -156,6 +170,7 @@ public class AdvancedSearch {
protected QuestWorld getItemValue(PaperCard input) { protected QuestWorld getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<QuestWorld> getItemValues(PaperCard input) { protected Set<QuestWorld> getItemValues(PaperCard input) {
return QuestWorld.getAllQuestWorldsOfCard(input); return QuestWorld.getAllQuestWorldsOfCard(input);
@@ -166,6 +181,7 @@ public class AdvancedSearch {
protected MagicColor.Color getItemValue(PaperCard input) { protected MagicColor.Color getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<MagicColor.Color> getItemValues(PaperCard input) { protected Set<MagicColor.Color> getItemValues(PaperCard input) {
return input.getRules().getColor().toEnumSet(); return input.getRules().getColor().toEnumSet();
@@ -176,6 +192,7 @@ public class AdvancedSearch {
protected MagicColor.Color getItemValue(PaperCard input) { protected MagicColor.Color getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<MagicColor.Color> getItemValues(PaperCard input) { protected Set<MagicColor.Color> getItemValues(PaperCard input) {
return input.getRules().getColorIdentity().toEnumSet(); return input.getRules().getColorIdentity().toEnumSet();
@@ -192,6 +209,7 @@ public class AdvancedSearch {
protected String getItemValue(PaperCard input) { protected String getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<String> getItemValues(PaperCard input) { protected Set<String> getItemValues(PaperCard input) {
final CardType type = input.getRules().getType(); final CardType type = input.getRules().getType();
@@ -228,6 +246,7 @@ public class AdvancedSearch {
protected String getItemValue(PaperCard input) { protected String getItemValue(PaperCard input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<String> getItemValues(PaperCard input) { protected Set<String> getItemValues(PaperCard input) {
CardSplitType cardSplitType = input.getRules().getSplitType(); CardSplitType cardSplitType = input.getRules().getSplitType();
@@ -294,7 +313,9 @@ public class AdvancedSearch {
@Override @Override
protected Boolean getItemValue(PaperCard input) { protected Boolean getItemValue(PaperCard input) {
List<PaperCard> cards = FModel.getMagicDb().getCommonCards().getAllCards(input.getName()); List<PaperCard> cards = FModel.getMagicDb().getCommonCards().getAllCards(input.getName());
if (cards.size() <= 1) { return true; } if (cards.size() <= 1) {
return true;
}
cards.sort(FModel.getMagicDb().getEditions().CARD_EDITION_COMPARATOR); cards.sort(FModel.getMagicDb().getEditions().CARD_EDITION_COMPARATOR);
return cards.get(0) == input; return cards.get(0) == input;
@@ -326,6 +347,7 @@ public class AdvancedSearch {
protected Keyword getItemValue(InventoryItem input) { protected Keyword getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<Keyword> getItemValues(InventoryItem input) { protected Set<Keyword> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -352,6 +374,7 @@ public class AdvancedSearch {
protected GameFormat getItemValue(InventoryItem input) { protected GameFormat getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<GameFormat> getItemValues(InventoryItem input) { protected Set<GameFormat> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -365,6 +388,7 @@ public class AdvancedSearch {
protected ConquestPlane getItemValue(InventoryItem input) { protected ConquestPlane getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<ConquestPlane> getItemValues(InventoryItem input) { protected Set<ConquestPlane> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -378,6 +402,7 @@ public class AdvancedSearch {
protected ConquestRegion getItemValue(InventoryItem input) { protected ConquestRegion getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<ConquestRegion> getItemValues(InventoryItem input) { protected Set<ConquestRegion> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -391,6 +416,7 @@ public class AdvancedSearch {
protected QuestWorld getItemValue(InventoryItem input) { protected QuestWorld getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<QuestWorld> getItemValues(InventoryItem input) { protected Set<QuestWorld> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -404,6 +430,7 @@ public class AdvancedSearch {
protected MagicColor.Color getItemValue(InventoryItem input) { protected MagicColor.Color getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<MagicColor.Color> getItemValues(InventoryItem input) { protected Set<MagicColor.Color> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -417,6 +444,7 @@ public class AdvancedSearch {
protected MagicColor.Color getItemValue(InventoryItem input) { protected MagicColor.Color getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<MagicColor.Color> getItemValues(InventoryItem input) { protected Set<MagicColor.Color> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -439,6 +467,7 @@ public class AdvancedSearch {
protected String getItemValue(InventoryItem input) { protected String getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<String> getItemValues(InventoryItem input) { protected Set<String> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -460,6 +489,7 @@ public class AdvancedSearch {
protected String getItemValue(InventoryItem input) { protected String getItemValue(InventoryItem input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<String> getItemValues(InventoryItem input) { protected Set<String> getItemValues(InventoryItem input) {
if (!(input instanceof PaperCard)) { if (!(input instanceof PaperCard)) {
@@ -525,7 +555,9 @@ public class AdvancedSearch {
@Override @Override
protected Boolean getItemValue(InventoryItem input) { protected Boolean getItemValue(InventoryItem input) {
List<PaperCard> cards = FModel.getMagicDb().getCommonCards().getAllCards(input.getName()); List<PaperCard> cards = FModel.getMagicDb().getCommonCards().getAllCards(input.getName());
if (cards.size() <= 1) { return true; } if (cards.size() <= 1) {
return true;
}
cards.sort(FModel.getMagicDb().getEditions().CARD_EDITION_COMPARATOR); cards.sort(FModel.getMagicDb().getEditions().CARD_EDITION_COMPARATOR);
return cards.get(0) == input; return cards.get(0) == input;
@@ -581,6 +613,7 @@ public class AdvancedSearch {
protected GameFormat getItemValue(DeckProxy input) { protected GameFormat getItemValue(DeckProxy input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<GameFormat> getItemValues(DeckProxy input) { protected Set<GameFormat> getItemValues(DeckProxy input) {
return input.getExhaustiveFormats(); return input.getExhaustiveFormats();
@@ -591,6 +624,7 @@ public class AdvancedSearch {
protected QuestWorld getItemValue(DeckProxy input) { protected QuestWorld getItemValue(DeckProxy input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<QuestWorld> getItemValues(DeckProxy input) { protected Set<QuestWorld> getItemValues(DeckProxy input) {
return QuestWorld.getAllQuestWorldsOfDeck(input.getDeck()); return QuestWorld.getAllQuestWorldsOfDeck(input.getDeck());
@@ -601,6 +635,7 @@ public class AdvancedSearch {
protected MagicColor.Color getItemValue(DeckProxy input) { protected MagicColor.Color getItemValue(DeckProxy input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<MagicColor.Color> getItemValues(DeckProxy input) { protected Set<MagicColor.Color> getItemValues(DeckProxy input) {
return input.getColor().toEnumSet(); return input.getColor().toEnumSet();
@@ -611,6 +646,7 @@ public class AdvancedSearch {
protected MagicColor.Color getItemValue(DeckProxy input) { protected MagicColor.Color getItemValue(DeckProxy input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<MagicColor.Color> getItemValues(DeckProxy input) { protected Set<MagicColor.Color> getItemValues(DeckProxy input) {
return input.getColorIdentity().toEnumSet(); return input.getColorIdentity().toEnumSet();
@@ -673,6 +709,7 @@ public class AdvancedSearch {
protected MagicColor.Color getItemValue(ConquestCommander input) { protected MagicColor.Color getItemValue(ConquestCommander input) {
throw new RuntimeException("getItemValues should be called instead"); throw new RuntimeException("getItemValues should be called instead");
} }
@Override @Override
protected Set<MagicColor.Color> getItemValues(ConquestCommander input) { protected Set<MagicColor.Color> getItemValues(ConquestCommander input) {
return input.getCard().getRules().getColorIdentity().toEnumSet(); return input.getCard().getRules().getColorIdentity().toEnumSet();
@@ -825,6 +862,7 @@ public class AdvancedSearch {
} }
return false; return false;
} }
@Override @Override
public boolean apply(Set<String> inputs, List<String> values) { public boolean apply(Set<String> inputs, List<String> values) {
if (inputs != null && !inputs.isEmpty() && !values.isEmpty()) { if (inputs != null && !inputs.isEmpty() && !values.isEmpty()) {
@@ -846,6 +884,7 @@ public class AdvancedSearch {
} }
return false; return false;
} }
@Override @Override
public boolean apply(Set<String> inputs, List<String> values) { public boolean apply(Set<String> inputs, List<String> values) {
if (inputs != null && !inputs.isEmpty() && !values.isEmpty()) { if (inputs != null && !inputs.isEmpty() && !values.isEmpty()) {
@@ -867,6 +906,7 @@ public class AdvancedSearch {
} }
return false; return false;
} }
@Override @Override
public boolean apply(Set<String> inputs, List<String> values) { public boolean apply(Set<String> inputs, List<String> values) {
if (inputs != null && !inputs.isEmpty() && !values.isEmpty()) { if (inputs != null && !inputs.isEmpty() && !values.isEmpty()) {
@@ -890,6 +930,7 @@ public class AdvancedSearch {
} }
return false; return false;
} }
@Override @Override
public boolean apply(Set<Object> inputs, List<Object> values) { public boolean apply(Set<Object> inputs, List<Object> values) {
if (inputs != null && inputs.size() == values.size()) { if (inputs != null && inputs.size() == values.size()) {
@@ -915,6 +956,7 @@ public class AdvancedSearch {
} }
return false; return false;
} }
@Override @Override
public boolean apply(Set<Object> inputs, List<Object> values) { public boolean apply(Set<Object> inputs, List<Object> values) {
if (inputs != null) { if (inputs != null) {
@@ -939,6 +981,7 @@ public class AdvancedSearch {
} }
return false; return false;
} }
@Override @Override
public boolean apply(Set<Object> inputs, List<Object> values) { public boolean apply(Set<Object> inputs, List<Object> values) {
if (inputs != null) { if (inputs != null) {
@@ -959,6 +1002,7 @@ public class AdvancedSearch {
} }
return false; return false;
} }
@Override @Override
public boolean apply(Set<Object> inputs, List<Object> values) { public boolean apply(Set<Object> inputs, List<Object> values) {
if (inputs != null) { if (inputs != null) {
@@ -977,6 +1021,7 @@ public class AdvancedSearch {
public boolean apply(Object input, List<Object> values) { public boolean apply(Object input, List<Object> values) {
throw new RuntimeException("shouldn't be called with a single input"); throw new RuntimeException("shouldn't be called with a single input");
} }
@Override @Override
public boolean apply(Set<Object> inputs, List<Object> values) { public boolean apply(Set<Object> inputs, List<Object> values) {
if (inputs != null) { if (inputs != null) {
@@ -994,6 +1039,7 @@ public class AdvancedSearch {
public boolean apply(Object input, List<Object> values) { public boolean apply(Object input, List<Object> values) {
throw new RuntimeException("shouldn't be called with a single input"); throw new RuntimeException("shouldn't be called with a single input");
} }
@Override @Override
public boolean apply(Set<Object> inputs, List<Object> values) { public boolean apply(Set<Object> inputs, List<Object> values) {
if (inputs != null) { if (inputs != null) {
@@ -1125,8 +1171,7 @@ public class AdvancedSearch {
final List<V> values; final List<V> values;
try { try {
values = getValuesFromString(initialValueText, option, operator); values = getValuesFromString(initialValueText, option, operator);
} } catch (Exception e) {
catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
@@ -1134,8 +1179,11 @@ public class AdvancedSearch {
} }
protected abstract List<V> getValues(FilterOption option, FilterOperator operator); protected abstract List<V> getValues(FilterOption option, FilterOperator operator);
protected abstract List<V> getValuesFromString(String valueText, FilterOption option, FilterOperator operator); protected abstract List<V> getValuesFromString(String valueText, FilterOption option, FilterOperator operator);
protected abstract String getCaption(List<V> values, FilterOption option, FilterOperator operator); protected abstract String getCaption(List<V> values, FilterOption option, FilterOperator operator);
protected abstract V getItemValue(T input); protected abstract V getItemValue(T input);
protected Set<V> getItemValues(T input) { //available for options that have multiple inputs protected Set<V> getItemValues(T input) { //available for options that have multiple inputs
@@ -1178,12 +1226,13 @@ public class AdvancedSearch {
String message; String message;
if (operator.valueCount == FilterValueCount.ONE) { if (operator.valueCount == FilterValueCount.ONE) {
message = option.name + " " + operator.caption + " ?"; message = option.name + " " + operator.caption + " ?";
} } else {
else {
message = "? " + operator.caption.replace("|", " " + option.name + " "); message = "? " + operator.caption.replace("|", " " + option.name + " ");
} }
Integer lowerBound = SGuiChoose.getInteger(message, min, max); Integer lowerBound = SGuiChoose.getInteger(message, min, max);
if (lowerBound == null) { return null; } if (lowerBound == null) {
return null;
}
final List<Integer> values = new ArrayList<>(); final List<Integer> values = new ArrayList<>();
values.add(lowerBound); values.add(lowerBound);
@@ -1195,7 +1244,9 @@ public class AdvancedSearch {
upperBoundMin += 2; //if exclusive, ensure it's possible to have numbers in between upperBoundMin += 2; //if exclusive, ensure it's possible to have numbers in between
} }
Integer upperBound = SGuiChoose.getInteger(message, upperBoundMin, max); Integer upperBound = SGuiChoose.getInteger(message, upperBoundMin, max);
if (upperBound == null) { return null; } if (upperBound == null) {
return null;
}
values.add(upperBound); values.add(upperBound);
} }
@@ -1226,7 +1277,9 @@ public class AdvancedSearch {
protected List<String> getValues(FilterOption option, FilterOperator operator) { protected List<String> getValues(FilterOption option, FilterOperator operator) {
String message = option.name + " " + operator.caption + " ?"; String message = option.name + " " + operator.caption + " ?";
String value = SOptionPane.showInputDialog("", message, null, initialInput); String value = SOptionPane.showInputDialog("", message, null, initialInput);
if (value == null) { return null; } if (value == null) {
return null;
}
initialInput = value; //store value as initial input for next time initialInput = value; //store value as initial input for next time
@@ -1253,9 +1306,11 @@ public class AdvancedSearch {
public CustomListEvaluator(Collection<V> choices0) { public CustomListEvaluator(Collection<V> choices0) {
this(choices0, null, null); this(choices0, null, null);
} }
public CustomListEvaluator(Collection<V> choices0, Function<V, String> toShortString0) { public CustomListEvaluator(Collection<V> choices0, Function<V, String> toShortString0) {
this(choices0, toShortString0, null); this(choices0, toShortString0, null);
} }
public CustomListEvaluator(Collection<V> choices0, Function<V, String> toShortString0, Function<V, String> toLongString0) { public CustomListEvaluator(Collection<V> choices0, Function<V, String> toShortString0, Function<V, String> toLongString0) {
choices = choices0; choices = choices0;
toShortString = toShortString0; toShortString = toShortString0;
@@ -1350,12 +1405,16 @@ public class AdvancedSearch {
protected List<Map<String, Integer>> getValues(FilterOption option, FilterOperator operator) { protected List<Map<String, Integer>> getValues(FilterOption option, FilterOperator operator) {
String message = option.name + " " + operator.caption + " ?"; String message = option.name + " " + operator.caption + " ?";
PaperCard card = SGuiChoose.oneOrNone(message, FModel.getMagicDb().getCommonCards().getUniqueCards()); PaperCard card = SGuiChoose.oneOrNone(message, FModel.getMagicDb().getCommonCards().getUniqueCards());
if (card == null) { return null; } if (card == null) {
return null;
}
Integer amount = -1; Integer amount = -1;
if (operator == FilterOperator.CONTAINS_X_COPIES_OF_CARD) { //prompt for quantity if needed if (operator == FilterOperator.CONTAINS_X_COPIES_OF_CARD) { //prompt for quantity if needed
amount = SGuiChoose.getInteger(Localizer.getInstance().getMessage("lblHowManyCopiesOfN", CardTranslation.getTranslatedName(card.getName())), 0, 4); amount = SGuiChoose.getInteger(Localizer.getInstance().getMessage("lblHowManyCopiesOfN", CardTranslation.getTranslatedName(card.getName())), 0, 4);
if (amount == null) { return null; } if (amount == null) {
return null;
}
} }
Map<String, Integer> map = new HashMap<>(); Map<String, Integer> map = new HashMap<>();
@@ -1375,8 +1434,7 @@ public class AdvancedSearch {
String[] split = valueText.split(" ", 2); String[] split = valueText.split(" ", 2);
amount = Integer.parseInt(split[0]); amount = Integer.parseInt(split[0]);
cardName = split[1]; cardName = split[1];
} } else
else
cardName = valueText; cardName = valueText;
Map<String, Integer> map = new HashMap<>(); Map<String, Integer> map = new HashMap<>();
map.put(cardName, amount); map.put(cardName, amount);
@@ -1412,21 +1470,25 @@ public class AdvancedSearch {
} }
} }
option = SGuiChoose.oneOrNone(Localizer.getInstance().getMessage("lblSelectAFilterType"), options, defaultOption, null); option = SGuiChoose.oneOrNone(Localizer.getInstance().getMessage("lblSelectAFilterType"), options, defaultOption, null);
if (option == null) { return editFilter; } if (option == null) {
return editFilter;
} }
else { } else {
option = defaultOption; option = defaultOption;
} }
if (option == FilterOption.NONE) { return null; } //allow user to clear filter by selecting "(none)" if (option == FilterOption.NONE) {
return null;
} //allow user to clear filter by selecting "(none)"
final FilterOperator operator; final FilterOperator operator;
if (option.operatorOptions.length > 1) { if (option.operatorOptions.length > 1) {
final FilterOperator defaultOperator = option == defaultOption ? editFilter.operator : null; final FilterOperator defaultOperator = option == defaultOption ? editFilter.operator : null;
operator = SGuiChoose.oneOrNone(Localizer.getInstance().getMessage("lblSelectOperatorFor", option.name), option.operatorOptions, defaultOperator, null); operator = SGuiChoose.oneOrNone(Localizer.getInstance().getMessage("lblSelectOperatorFor", option.name), option.operatorOptions, defaultOperator, null);
if (operator == null) { return editFilter; } if (operator == null) {
return editFilter;
} }
else { } else {
operator = option.operatorOptions[0]; operator = option.operatorOptions[0];
} }
@@ -1440,8 +1502,7 @@ public class AdvancedSearch {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T extends InventoryItem> Filter<T> getFilter(Class<? super T> type, String filterText) { public static <T extends InventoryItem> Filter<T> getFilter(Class<? super T> type, String filterText) {
String[] words = filterText.split(" ", 3); String[] words = filterText.split(" ", 3);
if(words.length < 2) if (words.length < 2) {
{
System.out.printf("Unable to generate filter from expression '%s'%n", filterText); System.out.printf("Unable to generate filter from expression '%s'%n", filterText);
return null; return null;
} }
@@ -1454,8 +1515,7 @@ public class AdvancedSearch {
System.out.printf("Unable to generate filter from FilterOption '%s'%n", words[0]); System.out.printf("Unable to generate filter from FilterOption '%s'%n", words[0]);
return null; return null;
} }
if(option.type != type) if (option.type != type) {
{
System.out.printf("Unable to generate filter from FilterOption '%s' - filter type '%s' != option type '%s' %n", words[0], type, option.type); System.out.printf("Unable to generate filter from FilterOption '%s' - filter type '%s' != option type '%s' %n", words[0], type, option.type);
return null; return null;
} }
@@ -1515,14 +1575,23 @@ public class AdvancedSearch {
public interface IFilterControl<T extends InventoryItem> { public interface IFilterControl<T extends InventoryItem> {
IButton getBtnNotBeforeParen(); IButton getBtnNotBeforeParen();
IButton getBtnOpenParen(); IButton getBtnOpenParen();
IButton getBtnNotAfterParen(); IButton getBtnNotAfterParen();
IButton getBtnFilter(); IButton getBtnFilter();
IButton getBtnCloseParen(); IButton getBtnCloseParen();
IButton getBtnAnd(); IButton getBtnAnd();
IButton getBtnOr(); IButton getBtnOr();
Filter<T> getFilter(); Filter<T> getFilter();
void setFilter(Filter<T> filter0); void setFilter(Filter<T> filter0);
Class<? super T> getGenericType(); Class<? super T> getGenericType();
} }
@@ -1554,23 +1623,18 @@ public class AdvancedSearch {
Object piece = iterator.get(); Object piece = iterator.get();
if (piece.equals(Operator.OPEN_PAREN)) { if (piece.equals(Operator.OPEN_PAREN)) {
predPiece = getPredicatePiece(iterator.next()); predPiece = getPredicatePiece(iterator.next());
} } else if (piece.equals(Operator.CLOSE_PAREN)) {
else if (piece.equals(Operator.CLOSE_PAREN)) {
return pred; return pred;
} } else if (piece.equals(Operator.AND)) {
else if (piece.equals(Operator.AND)) {
operator = Operator.AND; operator = Operator.AND;
continue; continue;
} } else if (piece.equals(Operator.OR)) {
else if (piece.equals(Operator.OR)) {
operator = Operator.OR; operator = Operator.OR;
continue; continue;
} } else if (piece.equals(Operator.NOT)) {
else if (piece.equals(Operator.NOT)) {
applyNot = !applyNot; applyNot = !applyNot;
continue; continue;
} } else {
else {
predPiece = ((AdvancedSearch.Filter<T>) piece).getPredicate(); predPiece = ((AdvancedSearch.Filter<T>) piece).getPredicate();
} }
if (applyNot) { if (applyNot) {
@@ -1579,11 +1643,9 @@ public class AdvancedSearch {
} }
if (pred == null) { if (pred == null) {
pred = predPiece; pred = predPiece;
} } else if (operator == Operator.AND) {
else if (operator == Operator.AND) {
pred = pred.and(predPiece); pred = pred.and(predPiece);
} } else if (operator == Operator.OR) {
else if (operator == Operator.OR) {
pred = pred.or(predPiece); pred = pred.or(predPiece);
} }
operator = null; operator = null;
@@ -1626,16 +1688,7 @@ public class AdvancedSearch {
control.setFilter(filter); control.setFilter(filter);
if (filter != null) { if (filter != null) {
control.getBtnFilter().setText(GuiBase.getInterface().encodeSymbols(filter.toString(), false)); control.getBtnFilter().setText(GuiBase.getInterface().encodeSymbols(filter.toString(), false));
} else {
if (filter.getOption() == FilterOption.CARD_KEYWORDS) {
//the first time the user selects keywords, preload keywords for all cards
Runnable preloadTask = Keyword.getPreloadTask();
if (preloadTask != null) {
GuiBase.getInterface().runBackgroundTask(Localizer.getInstance().getMessage("lblLoadingKeywords"), preloadTask);
}
}
}
else {
control.getBtnFilter().setText(EMPTY_FILTER_TEXT); control.getBtnFilter().setText(EMPTY_FILTER_TEXT);
} }
if (onChange != null) { if (onChange != null) {
@@ -1657,14 +1710,15 @@ public class AdvancedSearch {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void updateLabel() { public void updateLabel() {
if (label == null) { return; } if (label == null) {
return;
}
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("Filter: "); builder.append("Filter: ");
if (expression.isEmpty()) { if (expression.isEmpty()) {
builder.append("(none)"); builder.append("(none)");
} } else {
else {
int prevFilterEndIdx = -1; int prevFilterEndIdx = -1;
AdvancedSearch.Filter<T> filter, prevFilter = null; AdvancedSearch.Filter<T> filter, prevFilter = null;
for (Object piece : expression) { for (Object piece : expression) {
@@ -1675,14 +1729,12 @@ public class AdvancedSearch {
builder.replace(prevFilterEndIdx, builder.length(), builder.substring(prevFilterEndIdx).toLowerCase()); builder.replace(prevFilterEndIdx, builder.length(), builder.substring(prevFilterEndIdx).toLowerCase());
//append only values for filter //append only values for filter
builder.append(filter.extractValuesFromCaption()); builder.append(filter.extractValuesFromCaption());
} } else {
else {
builder.append(filter); builder.append(filter);
} }
prevFilter = filter; prevFilter = filter;
prevFilterEndIdx = builder.length(); prevFilterEndIdx = builder.length();
} } else {
else {
if (piece.equals(Operator.OPEN_PAREN) || piece.equals(Operator.CLOSE_PAREN)) { if (piece.equals(Operator.OPEN_PAREN) || piece.equals(Operator.CLOSE_PAREN)) {
prevFilter = null; //prevent merging filters with parentheses in between prevFilter = null; //prevent merging filters with parentheses in between
} }
@@ -1695,7 +1747,9 @@ public class AdvancedSearch {
} }
public String getTooltip() { public String getTooltip() {
if (expression.isEmpty()) { return ""; } if (expression.isEmpty()) {
return "";
}
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("Filter:\n"); builder.append("Filter:\n");
@@ -1718,7 +1772,9 @@ public class AdvancedSearch {
expression.clear(); expression.clear();
for (IFilterControl<T> control : controls) { for (IFilterControl<T> control : controls) {
if (control.getFilter() == null) { continue; } //skip any blank filters if (control.getFilter() == null) {
continue;
} //skip any blank filters
if (control.getBtnNotBeforeParen().isSelected()) { if (control.getBtnNotBeforeParen().isSelected()) {
expression.add(Operator.NOT); expression.add(Operator.NOT);
@@ -1737,8 +1793,7 @@ public class AdvancedSearch {
} }
if (control.getBtnAnd().isSelected()) { if (control.getBtnAnd().isSelected()) {
expression.add(Operator.AND); expression.add(Operator.AND);
} } else if (control.getBtnOr().isSelected()) {
else if (control.getBtnOr().isSelected()) {
expression.add(Operator.OR); expression.add(Operator.OR);
} }
} }
@@ -1748,13 +1803,16 @@ public class AdvancedSearch {
private class ExpressionIterator { private class ExpressionIterator {
private int index; private int index;
private boolean hasNext() { private boolean hasNext() {
return index < expression.size(); return index < expression.size();
} }
private ExpressionIterator next() { private ExpressionIterator next() {
index++; index++;
return this; return this;
} }
private Object get() { private Object get() {
return expression.get(index); return expression.get(index);
} }