diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form
index e9b349e1117..17513f7a0da 100644
--- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form
+++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form
@@ -645,6 +645,8 @@
+
+
@@ -659,6 +661,7 @@
+
@@ -846,6 +849,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java
index d23a4098246..f6fc566cef3 100644
--- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java
+++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java
@@ -232,7 +232,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
FilterCard filter = new FilterCard();
String name = jTextFieldSearch.getText().trim();
- filter.add(new CardTextPredicate(name, chkNames.isSelected(), chkTypes.isSelected(), chkRules.isSelected()));
+ filter.add(new CardTextPredicate(name, chkNames.isSelected(), chkTypes.isSelected(), chkRules.isSelected(), chkUnique.isSelected()));
if (limited) {
ArrayList> predicates = new ArrayList<>();
@@ -543,6 +543,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
chkNames = new javax.swing.JCheckBox();
chkTypes = new javax.swing.JCheckBox();
chkRules = new javax.swing.JCheckBox();
+ chkUnique = new javax.swing.JCheckBox();
jButtonSearch = new javax.swing.JButton();
jButtonClean = new javax.swing.JButton();
cardCountLabel = new javax.swing.JLabel();
@@ -1062,6 +1063,22 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
chkRulesActionPerformed(evt);
}
});
+
+ chkUnique.setSelected(true);
+ chkUnique.setText("Unique");
+ chkUnique.setToolTipText("Singleton results only.");
+ chkUnique.setFocusable(false);
+ chkUnique.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
+ chkUnique.setMaximumSize(new java.awt.Dimension(69, 16));
+ chkUnique.setMinimumSize(new java.awt.Dimension(69, 16));
+ chkUnique.setPreferredSize(new java.awt.Dimension(69, 16));
+ chkUnique.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ chkUnique.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ chkUniqueActionPerformed(evt);
+ }
+ });
+
jButtonSearch.setText("Search");
jButtonSearch.setToolTipText("Performs the search.");
@@ -1109,6 +1126,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
.addComponent(chkTypes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkRules, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(chkUnique, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(5, 5, 5)
.addComponent(cardCountLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@@ -1122,6 +1141,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
.addGroup(cardSelectorBottomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(chkTypes, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkRules, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(chkUnique, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkNames, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(cardSelectorBottomPanelLayout.createSequentialGroup()
.addGroup(cardSelectorBottomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -1341,6 +1361,10 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
// TODO add your handling code here:
}//GEN-LAST:event_chkRulesActionPerformed
+ private void chkUniqueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkRulesActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_chkRulesActionPerformed
+
private void btnExpansionSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExpansionSearchActionPerformed
FastSearchUtil.showFastSearchForStringComboBox(cbExpansionSet, "Select set or expansion");
}//GEN-LAST:event_btnExpansionSearchActionPerformed
@@ -1418,6 +1442,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
private javax.swing.JCheckBox chkPennyDreadful;
private javax.swing.JCheckBox chkPiles;
private javax.swing.JCheckBox chkRules;
+ private javax.swing.JCheckBox chkUnique;
private javax.swing.JCheckBox chkTypes;
private javax.swing.JButton jButtonAddToMain;
private javax.swing.JButton jButtonAddToSideboard;
diff --git a/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java b/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java
index 36cf356ce4f..503d290e054 100644
--- a/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java
+++ b/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java
@@ -27,6 +27,7 @@
*/
package mage.filter.predicate.other;
+import java.util.HashMap;
import mage.cards.Card;
import mage.cards.SplitCard;
import mage.constants.SubType;
@@ -44,21 +45,38 @@ public class CardTextPredicate implements Predicate {
private final boolean inNames;
private final boolean inTypes;
private final boolean inRules;
+ private final boolean isUnique;
+ private HashMap seenCards = null;
- public CardTextPredicate(String text, boolean inNames, boolean inTypes, boolean inRules) {
+ public CardTextPredicate(String text, boolean inNames, boolean inTypes, boolean inRules, boolean isUnique) {
this.text = text;
this.inNames = inNames;
this.inTypes = inTypes;
this.inRules = inRules;
+ this.isUnique = isUnique;
+ seenCards = new HashMap<>();
}
@Override
public boolean apply(Card input, Game game) {
- if (text.isEmpty()) {
+ if (text.isEmpty() && !isUnique) {
return true;
}
+
+ if (text.isEmpty() && isUnique) {
+ boolean found = !seenCards.keySet().contains(input.getName());
+ seenCards.put(input.getName(), true);
+ return found;
+ }
+
// first check in card name
if (inNames && input.getName().toLowerCase().contains(text.toLowerCase())) {
+ if (isUnique && seenCards.keySet().contains(input.getName())) {
+ return false;
+ }
+ if (isUnique) {
+ seenCards.put(input.getName(), true);
+ }
return true;
}
@@ -105,11 +123,18 @@ public class CardTextPredicate implements Predicate {
}
}
}
+
+ if (found && isUnique && seenCards.keySet().contains(input.getName())) {
+ found = false;
+ }
if (!found) {
return false;
}
}
+ if (isUnique) {
+ seenCards.put(input.getName(), true);
+ }
return true;
}