From 5d46763df90502ee78839595e23f4d736f134c27 Mon Sep 17 00:00:00 2001 From: Paco Ito Date: Sun, 6 Feb 2022 04:57:33 +0000 Subject: [PATCH] Fix Deck Editor filter update times --- .../main/java/forge/item/InventoryItem.java | 47 ++++++++++++++++ .../src/main/java/forge/item/PaperCard.java | 8 +++ .../java/forge/itemmanager/ColumnDef.java | 54 ++----------------- 3 files changed, 59 insertions(+), 50 deletions(-) diff --git a/forge-core/src/main/java/forge/item/InventoryItem.java b/forge-core/src/main/java/forge/item/InventoryItem.java index df8e20a1818..6f019c53c9d 100644 --- a/forge-core/src/main/java/forge/item/InventoryItem.java +++ b/forge-core/src/main/java/forge/item/InventoryItem.java @@ -26,4 +26,51 @@ import forge.util.IHasName; public interface InventoryItem extends IHasName { String getItemType(); String getImageKey(boolean altState); + + /** + * Converts a card name to a sortable name. + * Trim leading quotes, then move article last, then replace characters. + * Because An-Havva Constable. + * Capitals and lowercase sorted as one: "my deck" before "Myr Retribution" + * Apostrophes matter, though: "D'Avenant" before "Danitha" + * TO DO: Commas before apostrophes: "Rakdos, Lord of Riots" before "Rakdos's Return" + * + * @param printedName The name of the card. + * @return A sortable name. + */ + public static String toSortableName(String printedName) { + if (printedName.startsWith("\"")) printedName = printedName.substring(1); + return moveArticleToEnd(printedName).toLowerCase().replaceAll("[^\\s'0-9a-z]", ""); + } + + + /** + * Article words. These words get kicked to the end of a sortable name. + * For localization, simply overwrite this array with appropriate words. + * Words in this list are used by the method String moveArticleToEnd(String), useful + * for alphabetizing phrases, in particular card or other inventory object names. + */ + public static final String[] ARTICLE_WORDS = { + "A", + "An", + "The" + }; + + /** + * Detects whether a string begins with an article word + * + * @param str The name of the card. + * @return The sort-friendly name of the card. Example: "The Hive" becomes "Hive The". + */ + public static String moveArticleToEnd(String str) { + String articleWord; + for (int i = 0; i < ARTICLE_WORDS.length; i++) { + articleWord = ARTICLE_WORDS[i]; + if (str.startsWith(articleWord + " ")) { + str = str.substring(articleWord.length() + 1) + " " + articleWord; + return str; + } + } + return str; + } } diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index 6685bc7c153..3656e81da9d 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -55,6 +55,7 @@ public final class PaperCard implements Comparable, InventoryItemFro private final int artIndex; private final boolean foil; private Boolean hasImage; + private String sortableName; // Calculated fields are below: private transient CardRarity rarity; // rarity is given in ctor when set is assigned @@ -187,6 +188,9 @@ public final class PaperCard implements Comparable, InventoryItemFro rarity = rarity0; artist = (artist0 != null ? TextUtil.normalizeText(artist0) : IPaperCard.NO_ARTIST_NAME); collectorNumber = (collectorNumber0 != null) && (collectorNumber0.length() > 0) ? collectorNumber0 : IPaperCard.NO_COLLECTOR_NUMBER; + // If the user changes the language this will make cards sort by the old language until they restart the game. + // This is a good tradeoff + sortableName = InventoryItem.toSortableName(CardTranslation.getTranslatedName(rules0.getName())); } // Want this class to be a key for HashTable @@ -346,4 +350,8 @@ public final class PaperCard implements Comparable, InventoryItemFro || (this.getName().equals("Forest")) || (this.getName().equals("Mountain")); } + + public String getSortableName() { + return sortableName; + } } diff --git a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java index fce43bc1f8c..b6d2ff85e0f 100644 --- a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java +++ b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java @@ -63,9 +63,10 @@ public enum ColumnDef { new Function, Comparable>() { @Override public Comparable apply(final Entry from) { - if (from.getKey() instanceof PaperCard) - return toSortableName(from.getKey().toString()); - return toSortableName(from.getKey().getName()); + if (from.getKey() instanceof PaperCard) { + return ((PaperCard)from.getKey()).getSortableName(); + } + return InventoryItem.toSortableName(from.getKey().getName()); } }, new Function, Object>() { @@ -540,53 +541,6 @@ public enum ColumnDef { return this.longName; } - /** - * Converts a card name to a sortable name. - * Trim leading quotes, then move article last, then replace characters. - * Because An-Havva Constable. - * Capitals and lowercase sorted as one: "my deck" before "Myr Retribution" - * Apostrophes matter, though: "D'Avenant" before "Danitha" - * TO DO: Commas before apostrophes: "Rakdos, Lord of Riots" before "Rakdos's Return" - * - * @param printedName The name of the card. - * @return A sortable name. - */ - private static String toSortableName(String printedName) { - if (printedName.startsWith("\"")) printedName = printedName.substring(1); - return moveArticleToEnd(printedName).toLowerCase().replaceAll("[^\\s'0-9a-z]", ""); - } - - - /** - * Article words. These words get kicked to the end of a sortable name. - * For localization, simply overwrite this array with appropriate words. - * Words in this list are used by the method String moveArticleToEnd(String), useful - * for alphabetizing phrases, in particular card or other inventory object names. - */ - private static final String[] ARTICLE_WORDS = { - "A", - "An", - "The" - }; - - /** - * Detects whether a string begins with an article word - * - * @param str The name of the card. - * @return The sort-friendly name of the card. Example: "The Hive" becomes "Hive The". - */ - private static String moveArticleToEnd(String str) { - String articleWord; - for (int i = 0; i < ARTICLE_WORDS.length; i++) { - articleWord = ARTICLE_WORDS[i]; - if (str.startsWith(articleWord + " ")) { - str = str.substring(articleWord.length() + 1) + " " + articleWord; - return str; - } - } - return str; - } - private static String toType(final InventoryItem i) { return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getType().toString() : i.getItemType(); }